Re: [xsl] Processing directed acyclic graph (DAG) for object inheritance in XSLT

Subject: Re: [xsl] Processing directed acyclic graph (DAG) for object inheritance in XSLT
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Sun, 20 May 2001 16:32:15 +0100
Hi Soumen,

The following does what I think you want it to do, although it doesn't
do anything fancy really.

First, set up a key to get at the Class element nodes quickly when you
know their name:

<xsl:key name="classes" match="Class" use="@name" />

Second, the normal template for each Class gives the details of the
class.  To get the attributes of the class, I apply templates in
'attributes' mode:

<xsl:template match="Class">
   Managed object name is <xsl:value-of select="@name"/>
   Attributes from this class are:
   <xsl:apply-templates select="." mode="attributes" />
</xsl:template>

Finally, the attributes-mode template for the Class outputs the
attributes for that class, and then moves up in the hierarchy to apply
templates to the Base classes.  These classes are retrieved using the
name attribute of the Base element and the key that I set up above.
By definition, the node set returned by the key won't return any
duplicate Class elements, so even if there were Base elements that had
the same name, then it wouldn't matter.

<xsl:template match="Class" mode="attributes">
   <xsl:for-each select="Attribute">
      Attribute: <xsl:value-of select="@name" />
   </xsl:for-each>
   <xsl:apply-templates select="key('classes', Base/@name)"
                        mode="attributes" />
</xsl:template>

There are problems with this, however - while you won't get duplicates
in any particular step, there may well be duplicates overall, if two
of the Base classes have the same class as a Base. If you want to get
around this, I suggest having the attributes-mode template return
copies of the attributes, and then converting that to a node set and
iterating over only those with unique names:

<xsl:template match="Class" mode="attributes">
   <xsl:copy-of select="Attribute" />
   <xsl:apply-templates select="key('classes', Base/@name)"
                        mode="attributes" />
</xsl:template>

<xsl:key name="attributes" match="Attribute" use="@name" />

<xsl:template match="Class">
   Managed object name is <xsl:value-of select="@name"/>
   Attributes from this class are:
   <xsl:variable name="attributes-rtf">
      <xsl:apply-templates select="." mode="attributes" />
   </xsl:variable>
   <xsl:variable name="unique-attributes"
      select="exsl:node-set($attributes-rtf)/Attribute
                 [count(.|key('attributes', @name)[1]) = 1]">
   <xsl:for-each select="$unique-attributes">
      Attribute: <xsl:value-of select="@name" />
   </xsl:for-each>
</xsl:template>

I hope that helps,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/



 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread