给出以下标记:
<div id="about">
<dl>
<dt>Date</dt>
<dd>1872</dd>
<dt>Names</dt>
<dd>A</dd>
<dd>B</dd>
<dd>C</dd>
<dt>Status</dt>
<dd>on</dd>
<dt>Another Field</dt>
<dd>X</dd>
<dd>Y</dd>
</dl>
</div>
我尝试提取<dd>
之后的所有<dt>Names</dt>
个节点,但只是在另一个<dt>
开始之前。在这种情况下,我在以下节点之后:
<dd>A</dd>
<dd>B</dd>
<dd>C</dd>
我正在尝试以下XPath代码,但它没有按预期工作。
xpath("//div[@id='about']/dl/dt[contains(text(),'Names')]/following-sibling::dd[not(following-sibling::dt)]/text()")
有关如何修复它的任何想法?
非常感谢。
答案 0 :(得分:3)
在您的情况下有一个先决条件,即锚项始终是具有特定属性的第一个前一个兄弟。因此,这是编写以下复杂表达式的一种更简单的方法:
/div/dl/dd[preceding-sibling::dt[1][. = 'Names']]
换句话说:
dd
dt
(前一个兄弟轴向后计数)从oXygen的以下屏幕截图中可以看出,它选择了您想要选择的节点(如果您更改&#34;名称&#34;到&#34;状态&#34;或&#34;另一个字段&#34;,它也会在下一个dt
之前仅选择以下内容。
这在XPath 2.0中要容易得多,但我们假设您只能使用XPath 1.0。诀窍是计算你的锚元素中的前一个兄弟姐妹的数量(其中包含&#34;姓名&#34;在其中),并忽略任何错误计数(即,当我们越过<dt>Status</dt>
时,先前兄弟姐妹的数量增加了。)
对于XPath 1.0,删除(:
和:)
之间的注释(在XPath中,空白是无关紧要的,为了便于阅读,可以使其成为多行XPath,但在1.0中,注释是不可能的)< / p>
/div/dl/dd
(: any dd having a dt before it with "Names" :)
[preceding-sibling::dt[. = 'Names']]
(: count the preceding siblings up to dt with "Names", add one to include 'self' :)
[count(preceding-sibling::dt[. = 'Names']/preceding-sibling::dt) + 1
=
(: compare with count of all preceding siblings :)
count(preceding-sibling::dt)]
作为一个单行:
/div/dl/dd[preceding-sibling::dt[. = 'Names']][count(preceding-sibling::dt[. = 'Names']/preceding-sibling::dt) + 1 = count(preceding-sibling::dt)]
答案 1 :(得分:0)
这个怎么样:
//dd[preceding-sibling::dt[contains(., 'Names')]][following-sibling::dt]