Not sure if that description is the best...but given this xml:
<?xml version="1.0"?>
<root>
<type1 num="1" first="1"/>
<type1 num="2" />
<type2 num="3" />
<type2 num="4" />
<type1 num="5" first="2"/>
<type1 num="6" />
<type2 num="7" />
<type2 num="8" />
<type1 num="9" first="3"/>
<type1 num="10" />
<type2 num="11" />
<type2 num="12" />
</root>
I want to deepen the hierarchy and add a new 'group' node every time I hit the first in a sequence of type1 nodes. (note: the @first is there just so I could see what exact node the template was picking up...I don't want to use it to start the group)
Here is my stylesheet.
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kFirstText" match="*" use="generate-id(preceding-sibling::type1[not(preceding-sibling::*[1][self::type1])][1])"/>
<xsl:template match="/">
<newroot>
<xsl:apply-templates/>
</newroot>
</xsl:template>
<xsl:template match="type1[not(preceding-sibling::*[1][self::type1])]">
<group>
<type1>
<xsl:copy-of select="@*"/>
<xsl:attribute name="first-in-group">true</xsl:attribute>
</type1>
<xsl:copy-of select="key('kFirstText', generate-id())"/>
</group>
</xsl:template>
</xsl:stylesheet>
And the result I am getting is:
<?xml version='1.0' ?>
<newroot>
<group><type1 num="1" first="1" first-in-group="true"/><type1 num="2"/><type2 num="3"/><type2 num="4"/><type1 num="5" first="2"/></group>
<group><type1 num="5" first="2" first-in-group="true"/><type1 num="6"/><type2 num="7"/><type2 num="8"/><type1 num="9" first="3"/></group>
<group><type1 num="9" first="3" first-in-group="true"/><type1 num="10"/><type2 num="11"/><type2 num="12"/></group>
</newroot>
I found this question which got me pretty close, but as you can see in the output, the first instance of the type1 node is being duplicated in the first two groups.
I also realized I'm a little fuzzy on exactly what the key is picking up. My read is it's picking up any node that follows the immediate preceding instance of a type1 that does not have a type1 right behind it...is that right?
I also tried to exclude that node(@num="5") in the @match using the same xpath in the template, but that was just ignored. Any idea how to accomplish what I described above?
thanks!