Hi, I'm new to these forums and have been working with xslt for about a month. So far I've been able to do just about everything I need with it, but my most recent task has me confused.
I have a relatively flat xml structure that I'm using XSLT to transform into html that looks like a tree. I'm not concerned about the html part, I'm concerned about how to process the xml. My xml looks like this:
<system>
<device attr1='0' attr2='0' attr3='0'>
<sub-device range='24' value='0'/>
<sub-device range='25' value='1'/>
</device>
<device attr1='0' attr2='1' attr3='0'/>
<device attr1='0' attr2='2' attr3='0'/>
<device attr1='1' attr2='0' attr3='0'/>
<device attr1='1' attr2='1' attr3='0'/>
</system>
So when a device has sub-devices with range 24 and 25 then I know this device has children. The sub-device with a range of 25 holds the key to finding the children. Any device with an attr1 equal to the value associated with the sub-device range='25' is a child. The xslt I'm using to find these is:
<xsl:template match="system">
<xsl:result-document href="resdoc.html">
<html>
<body>
<xsl:apply-templates select="device"/>
</body>
</html>
</xsl:result-document>
</xsl:template>
<!-- this matches the parents -->
<xsl:template match="device[sub-device/@range='24' sub-device/@range='25']">
<xsl:variable name="node-def">
<xsl:value-of select="@attr1"><xsl:text>:</xsl:text>
<xsl:value-of select="@attr2"><xsl:text>:</xsl:text>
<xsl:value-of select="@attr3">
</xsl:variable>
<xsl:value-of select="$node-def"/><xsl:text> has children.</xsl:text> <br/>
<xsl:apply-templates select="../device[@attr1=current()/sub-device[range='25']/@value]"/>
</xsl:template>
<!-- this matches everything else -->
<xsl:template match="device">
<xsl:variable name="node-def">
<xsl:value-of select="@attr1"><xsl:text>:</xsl:text>
<xsl:value-of select="@attr2"><xsl:text>:</xsl:text>
<xsl:value-of select="@attr3">
</xsl:variable>
<xsl:value-of select="$node-def"/><xsl:text> has no children.</xsl:text> <br/>
</xsl:template>
The problem is, I'm processing the children twice.
The above xml would produce the following output:
0:0:0 has children.
1:0:0 has no children.
1:1:0 has no children.
0:1:0 has no children.
0:2:0 has no children.
1:0:0 has no children.
1:1:0 has no children.
What I'm looking for at this point is:
0:0:0 has children.
1:0:0 has no children.
1:1:0 has no children.
0:1:0 has no children.
0:2:0 has no children.
I want to only process the children once. I've been trying to figure out if grouping items using for-each-group is possible but I can't seem to figure out how to get the parent and children grouped together. The only other thing I could think of would be to keep a list of all the nodes I have processed and then check before re-processing, but I don't understand recursion enough to figure this out.
Is this possible? It has to be right? I'd really appreciate any ideas, suggestions or thoughts on this problem.
Thanks!