xsl code to get a range of nodes from xml
I have an xml like this:
<persons>
<person name="a">
</person>
<person name="f">
</person>
<person name="b">
</person>
<person name="g">
</person>
</persons>
Suppose i want to have all nodes between the one with name "f" and the one with name "g" So, parsing it with xslt, it should produce:
&开发者_StackOverflowlt;person name="b">
</person>
How can i do this??
Appreciate any help, thank you!!
In a simple list (not groups) this XPath 1.0 expression:
/persons/person[preceding-sibling::person[@name='f']]
[following-sibling::person[@name='g']]
If there are groups, this XPath 1.0 expression:
/persons
/person
[count(.|preceding-sibling::person[@name='f'][1]
/following-sibling::person[@name='g'][1]
/preceding-sibling::*) =
count(preceding-sibling::person[@name='f'][1]
/following-sibling::person[@name='g'][1]
/preceding-sibling::*)]
In XPath 2.0 you could use for both cases:
/persons/person[preceding-sibling::person[@name='f'][1]
/following-sibling::person[@name='g'][1] >> .]
In XSLT 1.0 you could use:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kPersonByMarks" match="person"
use="concat(generate-id(
preceding-sibling::person[@name='f'][1]),
'+',
generate-id(
following-sibling::person[@name='g'][1]))"/>
<xsl:template match="person[@name='f']">
<xsl:copy-of select="key('kPersonByMarks',
concat(generate-id(),'+',
generate-id(
following-sibling::person
[@name='g'][1])))"/>
</xsl:template>
</xsl:stylesheet>
Output:
<person name="b"></person>
Edit: Correct "including" expression for XPath 1.0, and XPath 2.0
I would use the position() function to select nodes whose position is greater than the position of the lower limit, and less than the position of the upper limit.
<xsl:apply-templates
match="persons/person[not(../preceding-sibling::person[f])]"/>
精彩评论