[xsl] Use for-each-group to eliminate duplicate output nodes?

Subject: [xsl] Use for-each-group to eliminate duplicate output nodes?
From: cknell@xxxxxxxxxx
Date: Wed, 21 Dec 2005 13:10:30 -0500
I have a transformation during which I'd like to eliminate some duplicate nodes which are generated in the transformation. Below is a sample of a portion of the input document the relevant templates from the XSLT document and the output currently generated.

I need to eliminate duplicate lines from the output file. If I were post-processing with perl, I'd use a hash to do this. Now that I'm moving into XSLT 2.0, I have the feeling that something similar to a perl hash can be got using <xsl:for-each-group>.

The actual stylesheet and data document are somewhat more complicated. I hope that I have steered correctly between the Scylla and Charybdis of too much and too little information. Can someone tell me whether <xsl:for-each-group> can be used like a perl hash to eliminate duplicate values, and if so how? Thanks.

-- Data Document (sample portion)--
<path>
<node type="process" id="023">
  <predecessors>
     <node type="process" id="020">
        <predecessors>
           <node type="process" id="001">
              <predecessors>
                 <node type="data-store" id="058"/>
              </predecessors>
           </node>
           <node type="process" id="002">
              <predecessors>
                 <node type="data-store" id="059"/>
              </predecessors>
           </node>
        </predecessors>
     </node>
  </predecessors>
</node>

<node type="process" id="024">
  <predecessors>
     <node type="process" id="020">
        <predecessors>
           <node type="process" id="001">
              <predecessors>
                 <node type="data-store" id="058"/>
              </predecessors>
           </node>
           <node type="process" id="002">
              <predecessors>
                 <node type="data-store" id="059"/>
              </predecessors>
           </node>
        </predecessors>
     </node>
   </predecessors>
</node>
</path>

These are the templates that process the part of the document shown.:

-- XSLT document --
<xsl:template match="/">
  digraph d{
  <xsl:apply-templates />
		}
</xsl:template>

<xsl:template match="path">
  node_<xsl:value-of select="node/@id" /> ;
  <xsl:apply-templates mode="set-nodes" />
  <xsl:apply-templates mode="set-connections" />
</xsl:template>

<xsl:template match="predecessors" mode="set-nodes">
  <xsl:apply-templates mode="set-nodes" />
</xsl:template>

<xsl:template match="node" mode="set-nodes">
  <xsl:apply-templates mode="set-nodes" />
</xsl:template>

<xsl:template match="predecessors/node" mode="set-nodes">
  node_<xsl:value-of select="@id" />
  <xsl:apply-templates mode="set-nodes" />
</xsl:template>

<xsl:template match="node" mode="set-connections">
  <xsl:variable name="target-node" select="." />
  <xsl:for-each select="predecessors/node">
    node_<xsl:value-of select="@id" /> -> node_<xsl:value-of select="$target-node/@id" />
  </xsl:for-each>
  <xsl:apply-templates mode="set-connections" />
</xsl:template>

Output from existing stylesheet (sorted to make identification of duplicates easier):

digraph d{
	node_001
	node_001
	node_002
	node_002
	node_003
	node_003
	node_004
	node_005
	node_006
	node_007
	node_008
	node_020
	node_020
	node_023
	node_024
	node_028
	node_038
	node_058
	node_058
	node_059
	node_059
	node_060
	node_061
	node_062
	node_063
	node_064
	node_065

	node_001 -> node_020
	node_001 -> node_020
	node_002 -> node_020
	node_002 -> node_020
	node_004 -> node_038
	node_005 -> node_038
	node_006 -> node_038
	node_007 -> node_038
	node_008 -> node_038
	node_020 -> node_023
	node_020 -> node_024
	node_023 -> node_038
	node_024 -> node_038
	node_038 -> node_028
	node_058 -> node_001
	node_058 -> node_001
	node_059 -> node_002
	node_059 -> node_002
	node_060 -> node_003
	node_061 -> node_004
	node_062 -> node_005
	node_063 -> node_006
	node_064 -> node_007
	node_065 -> node_008
}
-- 
Charles Knell
cknell@xxxxxxxxxx - email

Current Thread