XPath: 选择自身和后续同级节点

9
<div>
    <dt>
        Test 1
    </dt>
    <dd>
    </dd>
    <dt>
        Test 2
    </dt>
    <dd>
    </dd>
</div>

我到目前为止已经写好了这个XPath

//dt[contains(text(), "Test")]/self::dt|following-sibling::dd

但是这个并没有同时展示 dtdd,只有 dt
5个回答

5
如果必须是单个XPath 1.0表达式,那么你需要这样写:
//dt[contains(., 'Test')] | //dt[contains(., 'Test')]/following-sibling::dd[1]

最后的[1]很重要,因为如果没有它,它将提取包含“Test”的dt后面的所有dd元素,即

<div>
    <dt>
        Test 1
    </dt>
    <dd>
        Foo
    </dd>
    <dt>
        Something else 2
    </dt>
    <dd>
        Bar
    </dd>
</div>

没有[1]的版本将匹配三个节点,即包含“Test 1”的dt和“Foo”以及“Bar”dd元素。有了[1],你将只得到“Test 1”和“Foo”。但根据你使用XPath的方式,先选择某些元素可能更清晰。

//dt[contains(., 'Test')]

然后迭代匹配的节点,并进行评估。

. | following-sibling::dd[1]

在依次处理每个节点的上下文中。


4
使用XPath 2.0时:
//dt[contains(text(), "Test")]/(self::dt, following-sibling::dd)

1
那很整洁。但我正在使用1.0版本。 - Umair A.

0
为了避免重复测试 dt 元素的 contains,您可以重写查询,使所有所需的输出元素仅在搜索条件中表达一次:
//*[contains(self::dt|self::dd/preceding-sibling::dt[1],"Test")]

解释:从所有可能的输出元素池开始,选择一个以dt为前导或者以dt为前导的dd,其中dt匹配搜索条件。

包含此答案是为了展示一种减少代码重复并使表达式的联合运算符|更易于阅读的方法...


0

尝试使用这个XPATH:

//dt[contains(text(), "Test")]/self::dt or //dt[contains(text(), "Test")]/following-sibling::dd

这是我曾经使用的备选方案,但是有点冗长 :) - Umair A.
1
如果您正在使用“1.0”,那么这是唯一的选项。 - Navin Rawat

-1
根据您的示例,您可以使用此xpath,它更短,更简单,但是前提是您要查找dt,然后您想要dt的所有兄弟节点(不仅是下一个兄弟节点和自身)。此xpath查找dt的父级并获取其所有子项:
//dt[contains(text(), "Test")]/../*

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