使用:
(//h2[span/@id='Neo'])[1]/following-sibling::ul
[count(.
|
(//h2[span/@id='Neo'])[1]
/following-sibling::h2[1]
/preceding-sibling::ul
)
=
count((//h2[span/@id='Neo'])[1]
/following-sibling::h2[1]
/preceding-sibling::ul
)
]
/li
这将选择所有li
紧跟第h2
一个的span
子节点,该子节点的id
属性值为“Neo”。
要选择第二个这样的 qoutatations h2
,只需将上面的表达式替换1
为2
。
对所有数字执行此操作:1,2, ..., count(//h2[span/@id='Neo'])
基于 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=
"(//h2[span/@id='Neo'])[1]/following-sibling::ul
[count(.
|
(//h2[span/@id='Neo'])[1]
/following-sibling::h2[1]
/preceding-sibling::ul
)
=
count((//h2[span/@id='Neo'])[1]
/following-sibling::h2[1]
/preceding-sibling::ul
)
]
/li
"/>
</xsl:template>
</xsl:stylesheet>
当此转换应用于提供的 XML 文档时:
<html>
<h2><span class="mw-headline" id="Neo">Neo</span></h2>
<ul>
<li> First quote </li>
</ul>
<ul>
<li> Second quote </li>
</ul>
<h2><span class="mw-headline" id="dont wanna this">Useless</span></h2> >
</html>
计算 XPath 表达式,并将选定的节点复制到输出:
<li> First quote </li>
<li> Second quote </li>
说明:
这来自两个节点集的交集的 Kayessian(Michael Kay 博士)公式:
$ns1[count(.|$ns2) = count($ns2)]
上面恰好选择了同时属于 nodeset$ns
和 nodeset 的所有节点$ns2
。
因此,我们替换$ns1
为由所有感兴趣的后续兄弟组成的节点ul
集h2
。我们$ns2
用包含所有前面兄弟节点的节点集ul
替换,h2
即感兴趣的直接(第一个)跟随兄弟节点h2
。
这两个节点集的交集正好包含所有ul
需要的元素。
更新:在评论中,OP 声明他只知道他希望结果来自第一部分——字符串“Neo”是未知的。
这是修改后的解决方案:
(//h2[span/@id=$vSectionId])[1]
/following-sibling::ul
[count(.
|
(//h2[span/@id=$vSectionId])[1]
/following-sibling::h2[1]
/preceding-sibling::ul
)
=
count((//h2[span/@id=$vSectionId])[1]
/following-sibling::h2[1]
/preceding-sibling::ul
)
]
/li
该变量$vSectionId
必须作为以下 XPath 表达式的字符串值获取:
substring(//div[h2='Contents']
/following-sibling::ul[1]
/li[1]/a/@href,
2)
在这里,我们id
从第一个目录条目中的 中获取所需内容,并跳过第一个字符“#” href
。a
这里又是一个基于 XSLT 的验证:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vSectionId" select=
"substring(//div[h2='Contents']
/following-sibling::ul[1]
/li[1]/a/@href,
2)
"/>
<xsl:template match="/">
<xsl:copy-of select=
"(//h2[span/@id=$vSectionId])[1]
/following-sibling::ul
[count(.
|
(//h2[span/@id=$vSectionId])[1]
/following-sibling::h2[1]
/preceding-sibling::ul
)
=
count((//h2[span/@id=$vSectionId])[1]
/following-sibling::h2[1]
/preceding-sibling::ul
)
]
/li
"/>
</xsl:template>
</xsl:stylesheet>
当此转换应用于位于
http://en.wikiquote.org/wiki/The_Matrix的完整 XML 文档时,应用这两个 XPath 表达式的结果(将第一个的结果替换为第二个,然后评估第二个表达式)是想要的,正确的一个:
<li>I know you're out there. I can feel you now. I know that you're afraid. You're afraid of us. You're afraid of change. I don't know the future. I didn't come here to tell you how this is going to end. I came here to tell you how it's going to begin. I'm going to hang up this phone, and then I'm going to show these people what you don't want them to see. I'm going to show them a world … without you. A world without rules and controls, without borders or boundaries; a world where anything is possible. Where we go from there is a choice I leave to you.</li>
<li>Whoa.</li>
<li>I know kung-fu.</li>
<li>Yeah. Well, that sounds like a pretty good deal. But I think I may have a better one. How about, I give you the finger [He does] and you give me my phone call.</li>
<li>Guns.. lots of guns...</li>
<li>There is no spoon.</li>
<li>My name...is Neo!</li>