Here is an excerpt of my xml :
content
You could do it this way:
../node[not(text()) and preceding-sibling::node[@id][1][@id='1']]
where '1'
is the id of the current node (generate the expression dynamically).
The expression says:
If you are in XSLT you can select from the following-sibling axis because you can use the current()
function:
<!-- 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>
or simpler (and more efficient) with a key:
<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']))" />
Simpler than the accepted answer:
//node[@id='1']/following-sibling::node[following::node[@id='2']]
node
elementsnode
with id="2"
somewhere after them.Shown in action with a more clear test document (and legal id
values):
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"/>
XPath 2.0 has the operators '<<' and '>>' where node1 << node2
is true if node1 precedes node2 in document order.
So based on that with XPath 2.0 in an XSLT 2.0 stylesheet where the current node is the node[@id = '1'] you could use
following-sibling::node[not(text()) and . << current()/following-sibling::node[@od][1]]
That also needs the current() function from XSLT, so that is why I said "with XPath 2.0 in an XSLT 2.0 stylesheet". The syntax above is pure XPath, in an XSLT stylesheet you would need to escape '<<' as '<<'.