XPath:select所有以下兄弟姐妹,直到另一个兄弟姐妹
这里是我的XML的摘录:
<node/> <node/> <node id="1">content</node> <node/> <node/> <node/> <node id="2">content</node> <node/> <node/>
我被定位在node[@id='1']
。 我需要一个Xpath来匹配所有的<node/>
元素,直到下一个非空节点(这里是node[@id='2']
)。
编辑: @ID属性只是为了更清楚地解释我的问题,但不在我原来的XML。 我需要一个不使用@id属性的解决scheme。
我不想匹配node[@id='2']
之后的空兄弟,所以我不能使用天真的following-sibling::node[text()='']
。
我怎样才能做到这一点?
你可以这样做:
../ node [not(text())和preceding-sibling :: node [@id] [1] [@ id ='1']]
其中'1'
是当前节点的ID(dynamic生成expression式)。
expression说:
- 从当前的情况下去到父母
- select那些子节点
- 没有文字和
- 从所有“具有一个id的兄弟节点之前”,第一个必须有一个id
如果您处于XSLT中,则可以从以下兄弟轴中进行select,因为您可以使用current()
函数:
<!-- the for-each is merely to switch the current node --> <xsl:for-each select="node[@id='1']"> <xsl:copy-of select=" following-sibling::node[ not(text()) and generate-id(preceding-sibling::node[@id][1]) = generate-id(current()) ] " /> </xsl:for-each>
或者更简单(更高效)的关键:
<xsl:key name="kNode" match="node[not(text())]" use="generate-id(preceding-sibling::node[@id][1])" /> <xsl:copy-of select="key('kNode', generate-id(node[@id='1']))" />
XPath 2.0具有运算符“<<”和“>>”,其中如果node1以文档顺序在node2之前,则node1 << node2
为true。 因此,基于XPath 2.0在XSLT 2.0样式表中,当前节点是节点[@id ='1'],您可以使用
following-sibling::node[not(text()) and . << current()/following-sibling::node[@od][1]]
这也需要XSLT中的current()函数,所以这就是为什么我在“XSLT 2.0样式表中使用XPath 2.0”的原因。 上面的语法是纯XPath,在XSLT样式表中,您需要将“<<”转义为“&lt;&lt;”。
比接受的答案简单:
//node[@id='1']/following-sibling::node[following::node[@id='2']]
- find任何地方的身份证号码是“1”
- 现在find所有以下兄弟
node
元素 - …但只有当这些元素在其后的某处还具有
id="2"
的node
时。
显示在一个更清晰的testing文件(和合法的id
号码)的行动:
xml = '<root> <node id="a"/><node id="b"/> <node id="c">content</node> <node id="d"/><node id="e"/><node id="f"/> <node id="g">content</node> <node id="h"/><node id="i"/> </root>' # A Ruby library that uses libxml2; http://nokogiri.org require 'nokogiri'; doc = Nokogiri::XML(xml) expression = "//node[@id='c']/following-sibling::node[following::node[@id='g']]" puts doc.xpath(expression) #=> <node id="d"/> #=> <node id="e"/> #=> <node id="f"/>