RE: [xsl] Efficient recursive grouping in XSLT 1.0?

Subject: RE: [xsl] Efficient recursive grouping in XSLT 1.0?
From: "Andreas L. Delmelle" <a_l.delmelle@xxxxxxxxxx>
Date: Fri, 19 Mar 2004 02:33:57 +0100
> -----Original Message-----
> From: Ian Young
>
<snip />
> One thing I thought of is to do the transform in two steps: the first
> generates output isomorphic to the input elements, but annotates each with
> its ancestor name list (as a string); the second traverses that file using
> Muenchian grouping. This works -- albeit with rather variable performance
> -- in msxml. For the 1.3MB file step 2 takes 71 seconds in Saxon and 75 in
> libxslt (and 1 second in msxml). This confuses me!
>

Hi,

Just out of curiosity: have you thought about doing the transformation in
one step using multiple keys to achieve the grouping?

Some keys like:

<xsl:key name="by-depth-and-name" match="*"
         use="concat(count(ancestor::*),' ',name())" />
<xsl:key name="by-depth-parent-and-name" match="*"
         use="concat(count(ancestor::*),' ',name(parent::*),' ',name()) />

Then a separate template for the root as an introduction to the further
recursive logic:

<xsl:template match="root">
  <root ct="1">
    <xsl:apply-templates select="*[generate-id()=generate-id(
                           key('by-depth-and-name',concat('1 ',name())))]"
/>
  </root>
</xsl:template>

And the general template for the others (maybe a few of the variables could
be further avoided...but for readability's sake I didn't try to)

<xsl:template match="*">
  <xsl:variable name="vdepth" select="count(ancestor::*)" />
  <xsl:variable name="vparent" select="name(parent::*)" />
  <xsl:variable name="vsame" select="key('by-depth-and-name',concat(
                               $vdepth,' ',name()))[
                                 parent::*[name()=$vparent]]" />
  <xsl:variable name="vchild" select="$vsame/*" />

  <xsl:copy>
    <xsl:attribute name="ct">
      <xsl:value-of select="count($vsame)" />
    </xsl:attribute>
    <xsl:apply-templates select="$vchild[generate-id()=generate-id(
                           key('by-depth-parent-and-name',concat(
                             $vdepth+1,' ',name(current()),' ',name())))]"
/>
  </xsl:copy>
</xsl:template>

To be completely honest, I have no *exact* idea on how this would perform
with your larger structures, but it did deliver the wanted results in one
step, so might be worth a shot.

Hope this helps!

Cheers,

Andreas


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


Current Thread