具有这样的XML:
<foo><bar> foobar </bar></foo>
以下XPath表达式中的哪个表达式可以更快/更高效地选择包含某个'bar'元素的'foo'元素:
//bar[contains(text(), 'foobar')]/..
要么
//foo[bar[contains(text(), 'foobar')]]
?
最佳答案
我认为您问题的答案在很大程度上取决于所使用的特定XPath引擎的实现。
我使用xmllint
(基于libxml)使用以下测试文档执行了一些测量:
<root>
<foo><bar> </bar></foo>
[... 99998 lines ommitted ...]
<foo><bar> </bar></foo>
<foo><bar> foobar </bar></foo>
</root>
结果如下:
> time xmllint --repeat --xpath "//bar[contains(text(), 'foobar')]/.." test.xml > /dev/null
real 0m34.984s
user 0m45.820s
sys 0m2.332s
> time xmllint --repeat --xpath "//foo[bar[contains(text(), 'foobar')]]" test.xml > /dev/null
real 0m40.963s
user 0m40.660s
sys 0m0.260s
这似乎表明,在这种特定情况下,第一种变体比第二种变体快得多。
甚至更快的变体如下:
> time xmllint --repeat --xpath "//foo/bar[contains(text(), 'foobar')]/.." test.xml > /dev/null
real 0m31.945s
user 0m31.692s
sys 0m0.212s
这似乎表明,使用具有更多特定节点测试的位置路径并避免使用谓词似乎更好,但是我不知道在一般情况下这是否成立。
关于xpath - 哪个更有效:嵌套谓词或选择父元素(通常遍历祖先),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40356879/