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"/>