有这样的标记:
<div class="foo">
<div><span class="a1"></span><a href="...">...</a></div>
<div><span class="a2"></span><a href="...">...</a></div>
<div><span class="a1"></span>some text</div>
<div><span class="a3"></span>some text</div>
</div>
如果相邻的<a>
属于班级some text
,我有兴趣让所有span
和a1
。因此,在整个代码的末尾,我的结果应该是来自第一个<a>
的{{1}}和来自第三个的div
。如果some text
和<a>
位于some text
或span
内有div
属性,那就很容易了,但没有运气。
我现在正在做的是class
使用span
类:
a1
然后我得到它的父节点并用该父节点做另一个//div[contains(@class,'foo')]/div/span[contains(@class,'a1')]
作为上下文节点。这看起来远非有效,所以问题显然是否有更好的方法来实现我的目标?
答案附录
根据@MarcB accepted answer,要使用的正确查询是:
query()
但对于//div[contains(@class,'foo')]/div/span[contains(@class,'a1')]/..
,最好使用:
<a>
获取//div[contains(@class,'foo')]/div/span[contains(@class,'a1')]/../a
而不是其容器。
答案 0 :(得分:55)
关于xpath查询的好处是你可以将它们视为文件系统路径,所以只需要
//div[contains(@class,'foo')]/div/span[contains(@class,'a1')]/..
^^
将找到位于.foo节点下的所有.a1节点,然后向上移动一级到a1节点的父节点。
答案 1 :(得分:16)
表达更好而不是使用反向轴:
//div[contains(@class,'foo')]/div[span[contains(@class,'a1')]]
这会选择div
的{{1}}个孩子div
,其class
属性包含字符串“foo”,并且(所选的div
)有{span
1}} class
属性包含字符串“a1”的子项。
基于XSLT的验证:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select=
"//div[contains(@class,'foo')]
/div[span[contains(@class,'a1')]]"/>
</xsl:template>
</xsl:stylesheet>
在提供的XML文档上应用此转换时:
<div class="foo">
<div><span class="a1"></span><a href="...">...</a></div>
<div><span class="a2"></span><a href="...">...</a></div>
<div><span class="a1"></span>some text</div>
<div><span class="a3"></span>some text</div>
</div>
评估XPath表达式并将所选元素复制到输出中:
<div>
<span class="a1"/>
<a href="...">...</a>
</div>
<div>
<span class="a1"/>some text</div>
<强> II。关于通过其中一个类访问Html元素的备注:
如果知道该元素只能有一个类,则根本不需要使用contains()
请勿使用:
//div[contains(@class, 'foo')]
使用强>:
//div[@class = 'foo']
或者,如果可能有前导/尾随空格,请使用:
//div[normalize-space(@class) = 'foo']
的一个关键问题:
//div[contains(@class, 'foo')]
是选择任何div
类,如“myfoo”,“foo2”或“myfoo3”。
如果元素可能有多个类,并且为了避免上述问题,正确的XPath表达式为:
//div[contains(concat(' ', @class, ' '), ' foo ')]