如何在Java中使用XPath将CDATA作为节点访问?

时间:2012-08-27 19:06:05

标签: java xpath cdata

在以下XML上使用this在线XPath测试程序

<a>foo <![CDATA[ MyCData]]>  baz</a>    

使用XPath表达式/a/text(),我收回所有文本

foo <![CDATA[ MyCData]]>  baz 

(这是三个节点,我们可以看到使用/a/text()[2],它返回baz。)

但是,对于 javax.xml.xpath.XPath, CData和最后一个文本节点根本不会返回 。我得到一个foo的单个节点,文本<![CDATA[ MyCData]]> baz的其余部分不可用。无论XPath如何处理XML结构,如果我们根本无法访问节点,那就是一个错误。

但是,如果我在 DocumentBuilderFactory 上设置 isCoalescing(true),它会将所有text和CData节点连接成一个节点。我可能最终会使用它,但它会将CData转换为输出中的转义文本,即使标准允许,它也会显得很难看。此外,我更愿意能够将CData单独作为某种节点来处理,无论是“只是”文本节点,还是某种特殊类型的CData节点。

顺便说一下,如果CData是其父元素的 only 内容,前面没有空格或其他文本,普通的文本内容XPath会成功检索它,即使使用 isCoalescing 默认情况下( false )。因此,我们看到Java XPath始终返回第一个文本节点,而且只返回第一个文本节点。

当我检查DOM文档的完整DOM树时,默认情况下 isCoalescing ,我发现CData部分表示为自己的 cdata-section 节点 em>,这很好,但是如何在XPath中访问此节点?

1 个答案:

答案 0 :(得分:2)

在线XPath测试人员错了,我很害怕。根据XPath数据模型,<a>元素具有单个文本节点子节点,其字符串值为"foo MyCDATA baz";没有第二个文本节点,因此对第二个文本节点的请求不应返回任何内容。

XPath数据模型认为CDATA只是一种输入数据的便捷方式,以避免必须转义特殊字符; CDATA的存在不会影响XML的含义或信息内容,因此它不适用于该应用程序。