3

在以下 XML 上使用此在线 XPath 测试器

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

使用 XPath 表达式/a/text(),我得到了所有的文本

foo <![CDATA[ MyCData]]>  baz 

(这被构造为三个节点,我们可以看到 using /a/text()[2],它返回baz。)

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

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

顺便说一句,如果 CData 是其父元素的唯一内容,并且前面没有空格或其他文本,则普通的 text-content XPath 会成功检索它,即使isCoalescing的默认值 ( false ) 也是如此。因此,我们看到 Java XPath 总是返回第一个,并且只返回第一个文本节点。

当我检查我的 DOM 文档的完整 DOM 树时,默认使用isCoalescing,我发现 CData 部分表示为它自己的类型为cdata-section的节点,这很好,但是如何在 XPath 中访问这个节点?

4

1 回答 1

2

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

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

于 2012-08-28T08:17:13.520 回答