XPath - 选择某个元素后的第一个元素

61

我对XPath还不太熟悉,只是摸索了几个小时,所以我不确定它是否可以执行以下操作。

好的,以下是情况说明:我想从一个页面中找到一个链接。该链接仅可通过其文本值识别,即在<a>标签(<a href="#">此链接</a>)之间的文本。到目前为止,我已成功得到带有该文本的链接元素,唯一的问题是周围还有几个这样的链接。

这些链接都来自于无序列表,这些列表之前有另一个链接标签,可以作为一个非常好的“锚点”来开始搜索我想要找到的最终元素(即然后我只需接受与之匹配的第一个元素)

为了澄清事情,这里是一个示例:

<a href="#">first dropdown menu</a>
<ul>
  <li><a href="#">some link</a></li>
  <li><a href="#">link i want to find</a></li>
</ul>

<-- *And i would actually want to find the thing from this list* --> 
<a href="#">second dropdown menu</a>
<ul>
  <li><a href="#">some link</a></li>
  <li><a href="#">link i want to find</a></li>
</ul>
我应该明确指出,我只想要收到一个结果或一组结果,其中第一个元素是“正确”的元素- 我要找的元素。
编辑:问题已经得到解答,但有一些评论说我应该更明确地说明一下,这样人们才能真正理解问题。
因此,我的想法是使用一个元素来指定另一个元素的位置,该元素可能在整个文档中散布着重复的搜索结果。
如果您想从一组下拉菜单中找到具有相同名称或值的元素,则基本上会遇到这样的情况。
这就是基本情况。我知道这仍然有点难以理解,但不幸的是我很难解释得更好。我相信其他人可以做得更好,如果发生这种情况,我很乐意在这里包含那个描述。

1
请更新问题 - 从回复中可以看出您的目标不清楚。 - Gishu
3个回答

92

我不止一次阅读了你的问题,但我认为我理解了。你感兴趣的是谓词。谓词允许你根据条件选择节点。

例如,你可以这样做:

//a[text()='second dropdown menu']/following::ul[1]/li/a[text()='link i want to find']

这个代码会选择所有包含特定文本的锚点,找到下一个ul标签,然后遍历它的子元素。

此外,你可以在结果集中指定位置索引,以下XPath是一个演示(但它并不能解决你的问题):

//a[text()='first dropdown menu']/ul/li[last()]/a/text()

或者你可以使用轴(axes)来在兄弟节点、祖先节点和子节点之间导航:

//a[ancestor::ul/preceding::a[1]/text() = 'second dropdown menu']/text()

所以我不确定我完全理解了你的问题,但这应该有助于你编写XPath。

基本上,我假设你的XPath匹配了多个列表中的锚点,并且你想确保选择正确的一个。在XPath的某个位置,您需要使用谓词来指定一个条件,该条件仅对所需节点所在的列表为真。


8
我理解您的意思是:您想要在“第二个下拉菜单”之后找到“一些链接”节点。请注意,此处保留了HTML标签。
ul[preceding::a[text()='second dropdown menu' and position()=last()]]/li/a[text()='link i want to find']

这应该能解决问题(我不是100%确定您是否需要检查position() = 1,但我认为如果您省略它,则会匹配所有后续的ul,因为它们都被“所有”前置节点隔开 - 这取决于您xml结构的其余部分)


其实我想找到值为“我想找的链接”的链接,但这个也可以;)稍后我会检查一下。 - JHollanti
我刚刚阅读了一些内容,你需要使用position()=last()而不是position()=1,因为preceding会获取文档顺序中'上下文节点之前的所有节点'。 - Niko

-1

如果我错了,请纠正我 - 你需要从上面的示例中选择“第二个下拉菜单”,但文本可能会重复,所以你只需要第二个。

XPath:

//a[text()='second drop down menu'][2]

是的,但是想法是通过两个单独的“参数”来查找元素。第一个参数是标记的“索引”,第二个参数是我想要查找的特定元素。因此,静态位置的引用是不可行的。 - JHollanti
这将返回:<a href="#">第二个下拉菜单</a>,如果只有一个锚点与其匹配,则返回空。 - Chris Cameron-Mills

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接