I am using xslt 2.0, I have following sample xml, I want to get all "header-lightgray" nodes between the two "header-gray" nodes, the problem here is: I don't know how many "header-lightgray" there. so I can not use position() function. and xsl for each don't support break.
<t>
<parent class="header-gray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-lightgray"></parent>
...
<parent class="header-gray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-gray"></parent>
</t>
I want go through them and replace all nodes, header-gray with div and header-lightgray with span. the output expected is:
<div class="header-gray">
<span class="header-lightgray"/>
<span class="header-lightgray"/>
<span class="header-lightgray"/>
...
</div>
<div class="header-gray">
<span class="header-lightgray"/>
<span class="header-lightgray"/>
<span class="header-lightgray"/>
</div>
So how to do it?
Any help is appreciated.
Solution I'd like to share according to Jan Vlcinsky's answer:
<xsl:for-each select="/t/parent[@class='header-gray']">
<xsl:variable name="ns1" select="current()/following-sibling::parent"/>
<xsl:variable name="ns2" select="current()/following-sibling::parent[@class='header-gray'][1]/preceding-sibling::parent"/>
<div class="header-gray">
<xsl:for-each select="$ns1[count(.| $ns2)=count($ns2)]">
<span class="header-lightgray"/>
</xsl:for-each>
</div>
</xsl:for-each>
I don't verify above code, but it's the same logic in my real code. I didn't use xslt 2.0 way because I found that lxml 2.3 I am using does not support xslt 2.