我正在寻找可以为我执行以下两项任务的XML / XHTML Java库/框架。

在进行一些定义之前:


NodeOffset(Node node, int offset)标记XML树中文本节点中的某个点。
nodeBnodeInodeP是下面提到的XHTML树的相应Node实例,nodeSpan是一些新创建的节点(其中Node不一定是org.w3c.dom.Node,并且可以是任何其他抽象)


将XHTML奉承成纯文本

该库应该能够从给定的XHTML生成纯文本输出(例如,通过实现CharSequence或类似方法),并提供输出中的字符与原始XHTML节点树之间的一对一映射(例如,通过函数NodeOffset getNodeOffset(int plainTextOffset))。

示例:假设我们有以下XHTML:

<p><b>GeForce</b> 9300M GS provides powerful <i>visual computing features</i> to thin and light notebooks.</p>


那么,纯文本表示形式显然是:

GeForce 9300M GS provides powerful visual computing features to thin and light notebooks.


然后例如


getNodeOffset(0)应该返回节点NodeOffset(nodeB, 0)
getNodeOffset(40)应该返回节点NodeOffset(nodeI, 5)
getNodeOffset(80)应该返回节点NodeOffset(nodeP, 49)


我可能会错过正确的数字,但我希望你明白了。我重复这个例子,现在插入了伪标记:

|GeForce 9300M GS provides powerful visua|l computing features to thin and light n|otebooks.




<p><b>|GeForce</b> 9300M GS provides powerful <i>visua|l computing features</i> to thin and light n|otebooks.</p>


节点操作

该库应提供将节点注入XHTML的可能性,该节点可能跨越树,可能跨越节点边界,例如跨树。通过操作NodeSet insert(Node nodeToInsert, NodeOffset start, NodeOffset end, int mode)。该功能在两种模式下工作:


模式1:如有必要,拆分要插入的节点。在这种情况下,将从nodeToInsert节点拆分的节点作为操作结果返回。
模式2:关闭父节点。 nodeToInsert照原样返回。


例如:insert(nodeSpan, NodeOffset(nodeB, 2), NodeOffset(nodeP, 9), mode1)操作应产生

<p><b>Ge<span>Force</span></b><span> 9300M GS</span> provides powerful <i>visual computing features</i> to thin and light notebooks.</p>


insert(nodeSpan, NodeOffset(nodeB, 2), NodeOffset(nodeP, 9), mode2)操作应产生:

<p><b>Ge</b><span><b>Force</b> 9300M GS</span> provides powerful <i>visual computing features</i> to thin and light notebooks.</p>


它类似于用户在丰富编辑器中所做的工作:

GeForce 9300M GS

我想知道,在OpenSource世界中是否有类似的东西,因为我真的不想重新实现这个轮子……我已经快速检查Open Source HTML Parsers in Java并没有成功。

当您发布答案时:


确保库API中提供了上述功能(提供指向JavaDoc的链接)。
该库是Java本地库(无JNI)和OpenSource。

最佳答案

我在一个开源项目ShtutXML中包装了已有的代码,并进行了修改以匹配您的请求(WIP)。它已被很好地记录下来,所以我怀疑您在使用它时会遇到问题。

第一个请求(查找节点并从全局位置偏移)已经内置,并且XML中的文本节点拆分已经内置(因此您可以根据需要轻松地将它们包装在新节点中)。因此,添加用于用元素标记区域的逻辑相当简单。稍后我会尝试做,但这是我目前针对此请求的最大努力。

在您的XML上,使用我的example program这是我的输出:

************* BASE DOCUMENT *****************
DOCUMENT ROOT
|-<p >
| |-<b >
| | |-Text: GeForce
| |-Text:  9300M GS provides powerful
| |-<i >
| | |-Text: visual computing features
| |-Text:  to thin and light notebooks.

*** Text ***
"GeForce 9300M GS provides powerful visual computing features to thin and light notebooks."

*** Node of each text segment ***
[b: null]: GeForce
[p: null]:  9300M GS provides powerful
[i: null]: visual computing features
[p: null]:  to thin and light notebooks.


*** Offset testing ***
offset 0 is at [b: null] at 0
offset 40 is at [i: null] at 5
offset 80 is at [p: null] at 48


要求它在全局位置4拆分元素将产生

*********** Split(4) DOCUMENT *****************
DOCUMENT ROOT
|-<p >
| |-<b >
| | |-Text: GeFo
| | |-Text: rce
| |-Text:  9300M GS provides powerful
| |-<i >
| | |-Text: visual computing features
| |-Text:  to thin and light notebooks.

*** Node of each text segment ***
[b: null]: GeFo
[b: null]: rce
[p: null]:  9300M GS provides powerful
[i: null]: visual computing features
[p: null]:  to thin and light notebooks.


当然,这种语法上的拆分对于与该文档匹配的实际XML代码没有任何意义,但是它将允许一次将一个文本部分与您希望的任何其他节点包装在一起。

编辑:第一个插入模式已受支持

编辑2:已经支持第二种插入模式

笔记:


您可能进行的任何文档修改都会使所有胶印无效。以后使用它们会导致整个文档的损坏。因此,每次修改后,您都必须执行GetOffset以再次获取偏移量。
我知道某些功能没有记录。基本上,应该在包外部使用的唯一功能是您从StrXML类请求的功能。稍后会添加更多文档,您可以通过电子邮件(请参阅我的资料页面)与我联系以获取疑问。

10-04 18:12