Reputation: 177
Consider I have this XML file:
<text>
<w>John</w>
<x>Smith</x>
<z>Andy</z>
<w>Goo</w>
<w>Joseph</w>
<y>Lee</y>
<x>Kenny</x>
<z>Maria</z>
<y>Zoe</y>
<z>Martin</z>
</text>
Now I wish to select elements between 1st <z>
and 2nd <z>
So the output will be :
<w>Goo</w>
<w>Joseph</w>
<y>Lee</y>
<x>Kenny</x>
What I know is we can "copy-of" select the "following siblings" of "z[1]" but I don't know how to stop it on "z[2]"
Upvotes: 4
Views: 2471
Reputation: 60414
Select the intersection of the following two node-sets:
z
z
The intersection of these two sets will be all nodes between the first and second z
elements. Use the following expression:
/*/z/following-sibling::*[
count(.|/*/z[2]/preceding-sibling::*) =
count(/*/z[2]/preceding-sibling::*)]
Note: This uses the Kayessian node-set intersection formula. In general, use the following to find the intersection of $set1
and $set2
:
$set1[count(.|$set2)=count($set2)]
Upvotes: 4
Reputation: 56162
You can use XPath:
text/*[preceding-sibling::z and following-sibling::z[2]]
e.g.:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="text/*[preceding-sibling::z and following-sibling::z[2]]"/>
</xsl:template>
</xsl:stylesheet>
Upvotes: 2