XPath查询结果顺序

时间:2011-11-19 17:10:17

标签: php xpath domdocument libxml2

对于another question我已经创建了一些与我的开发机器相关的XML相关代码,但在viper键盘上没有,我在测试之前将其添加到我的答案中。

我可以将我的问题减少到DOMXPath::query()返回的节点顺序在我的系统和键盘之间有所不同。

XML:<test>This is some <span>text</span>, fine.</test>

当我查询所有文本节点//child::text()时,结果不同:

Viper Codepad:

#0: This is some 
#1: , fine.
#2: text

我的机器:

#0: This is some 
#1: text
#2: , fine.

我不熟悉xpath,我确实理解为什么会发生这种情况以及如何通过PHP实现来影响返回顺序。

修改

进一步测试显示,LIBXML_VERSION在两个系统之间有所不同:

Viper Codepad: 20626 (2.6.26; 6 Jun 2006)
My Machine...: 20707 (2.7.7; 15 Mar 2010)

5 个答案:

答案 0 :(得分:7)

从技术上讲,XPath 1.0返回节点集而不是节点序列。在XPath 1.0规范中,没有关于这些节点集顺序的陈述 - 事实上,作为集合,它们没有内在的顺序。

但是,XSLT 1.0始终按文档顺序处理XPath 1.0返回的节点集,并且由于该先例,人们普遍期望当从XSLT以外的语言调用XPath时,XPath结果将按文档顺序排列。但是,规范中没有任何内容可以保证这一点。在XPath 2.0中,用户期望成为规范的一部分,路径表达式的结果必须按文档顺序排列。

答案 1 :(得分:4)

我可以找到以下错误报告看起来像这个问题:Bug 363252 - proximity position in libxml2's xmlXPathEvalExpression()报告于2006年10月18日,并确认自2006年5月以来可追溯到2.6.26版本之前。

这应该在libxml2 2.6.27中修复。

答案 2 :(得分:2)

它看起来像20626版本中的错误:

它首先按文档顺序处理所有子文本节点,然后处理子元素节点的内容。应该是你机器上的结果

答案 3 :(得分:2)

XPath是一种查询语言,因此它应该只读取.xml文档的结构,并且永远不会修改它。这包括节点顺序。在你的第一个例子中,这不是真的。所以这绝对是this的错误。

答案 4 :(得分:1)

Viper Codepad似乎没有按照第一个文档顺序返回选定的text()节点,而是进行广度优先评估。

它应该是深度优先遍历。

Saxon,MSXML,Altova XML各自以深度优先顺序返回结果。