两个查询都会检索已被喜欢超过5次的图片。 我认为查询1定义了相对路径,而查询2没有,这就是查询2使用“祖先”的原因。我对吗?哪个更好?
首先查询:
//div[@class="pin"]
[.//span[@class = 'LikesCount']
[substring-before(normalize-space(.),' ') > 5]]
/div[@class="PinHolder"]
/a/img
第二次查询:
//div[@class="pin"]/p/span[@class="LikesCount"]
[substring-before(., " ") > 5]/ancestor::div[@class="pin"]/a/img
关注标记:
<div class="pin">
[...]
<div class="PinHolder">
<a href="/pin/56787645270909880/" class="PinImage ImgLink">
<img src="http://media-cache-ec3.pinterest.com/upload/56787645270909880_d7AaHYHA_b.jpg"
alt="Krizia"
data-componenttype="MODAL_PIN"
class="PinImageImg"
style="height: 288px;">
</a>
</div>
<p class="stats colorless">
<span class="LikesCount">
22 likes
</span>
<span class="RepinsCount">
6 repins
</span>
</p>
[...]
</div>
答案 0 :(得分:2)
有一些差异可能会使它们返回不同的结果,而一些差别没有区别。某些差异会影响某些输入中的表达式(或类似表达式)的值,而不会影响其他输入。
第一个表达式查找与以下路径匹配的元素(的一个子集):
//div[@class='pin']/div[@class='PinHolder']/a/img
第二个查找与此路径匹配的元素(的一部分):
//div[@class='pin']/a/img
所以两者永远不会返回重叠的结果。
在检查类span
的{{1}}上的条件时,第一个表达式在提取第一个标记之前将LikesCount
函数应用于span的字符串值;第二个没有。给定字符串值,例如样本标记中的字符串值(换行符,八个空格,“22个喜欢”,空白,换行符,四个空格),这可能会有所不同。如果环境在评估XPath表达式之前规范化空格,则可能没有区别。
每个表达式测试类normalize-space
的{{1}}元素;第一个表达式在具有类span
的{{1}}的所有后代中查找此类跨度,而第二个表达式仅在父项为LikesCount
的孙子中查找它。在显示的示例XML中,这些都是相同的(第一个表达式找不到第二个表达式也找不到的类div
的任何跨度。
由于在第二个表达式中使用了祖先轴,在某些具有类pin
的嵌套p
元素的文档中,两者将返回不同的结果;如果输入中没有这样的嵌套LikesCount
元素,则表达式中的这种差异不会对它们返回的值产生影响。
在空格对XPath不重要的地方,第一个表达式使用的空格比第二个表达式多。这可能使一些读者更容易阅读第一个表达;它也使它需要更多空间(一些读者不喜欢)。表达式1中谓词的缩进将谓词应用于直接在彼此上下相同的节点,这可以帮助一些读者看到它们适用于相同的节点。在极少数情况下,我遇到了XPath评估程序,它们没有准备好处理XPath表达式中无关紧要的空格,当然一些编程语言需要对多行字符串进行特殊处理,因此第一个表达式的多行缩进形式可能很难用于某些环境,即使它是合法的XPath。
你写的“我认为查询1定义了相对路径,而查询2没有,这就是查询2使用”祖先“的原因。我是对的吗?”我不确定你的意思,所以这个答案的尝试可能没有用(抱歉)。第一个表达式将关于likes-count跨度的测试放入类div
的{{1}}上的谓词,而第二个表达式导航到span,执行测试,然后导航回到集合所有祖先是pin
元素,类div
。在如图所示的XML中,这些配方具有相同的效果;当div
类的pin
元素可以嵌套时,它们可以产生稍微不同的结果。但是测试的确切表述和遍历问题。
你问“哪个更好?”由于它们目前会返回不同的结果,因此决定这一点的第一种方法是询问“哪一个表达了您想要问的问题?”
如果修改它们以返回相同的结果,那么问题将变成“你觉得哪一个更容易理解?”,这样在维护代码时你或你的继任者可以看到发生了什么?