RE: [xsl] Counting nodes efficiently

Subject: RE: [xsl] Counting nodes efficiently
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Thu, 19 Feb 2004 02:41:46 -0800 (PST)
> <xsl:stylesheet version="1.0"
>  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
>  <xsl:output omit-xml-declaration="yes"/>
>  
>   <xsl:template match="@* | node()">
>     <xsl:copy>
>       <xsl:apply-templates select="@*"/>
>       <xsl:apply-templates select="node()[1]"/>
>     </xsl:copy>
>     <xsl:apply-templates select="following-sibling::node()[1]"/>
>   </xsl:template>
> 
> </xsl:stylesheet>
> 
> This transformation produces the same results as the more well-known
> identity rule.
> 
> The difference is that we now have the finest possible grain-level of
> controll as every xsl:apply-templates instruction above always selects
> at
> most one node.
> 
> It is trivial to add parameters and to override the one-at-a-time
> identity
> for elements. Thus we finally have:
> 
> <xsl:stylesheet version="1.0"
>  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
>  <xsl:output omit-xml-declaration="yes"/>
>  
>   <xsl:template match="@* | node()">
>     <xsl:param name="pnAncestors" select="0"/>
>     <xsl:param name="pnPreceding" select="0"/>
>     <xsl:copy>
>       <xsl:apply-templates select="@*"/>
>       <xsl:apply-templates select="node()[1]">
>         <xsl:with-param name="pnAncestors" 
>                         select="$pnAncestors+1"/>
>         <xsl:with-param name="pnPreceding"
>                         select="$pnPreceding"/>
>       </xsl:apply-templates>
>     </xsl:copy>
>     <xsl:apply-templates select="following-sibling::node()[1]">
>       <xsl:with-param name="pnAncestors" 
>                       select="$pnAncestors"/>
>       <xsl:with-param name="pnPreceding"
>                       select="$pnPreceding+1"/>
>           
>     </xsl:apply-templates>
>   </xsl:template>
>   
>   <xsl:template match="*">
>     <xsl:param name="pnAncestors" select="0"/>
>     <xsl:param name="pnPreceding" select="0"/>
>     
>     <xsl:copy>
>       <xsl:copy-of select="@*"/>
>       <xsl:attribute name="_id">
>         <xsl:value-of select=
>                     "concat(name(), '_',
>                             $pnAncestors, '_', 
>                             $pnPreceding 
>                             )"/>
>       </xsl:attribute>
>     </xsl:copy>
>     <xsl:apply-templates select="node()[1]">
>       <xsl:with-param name="pnAncestors" 
>                       select="$pnAncestors+1"/>
>       <xsl:with-param name="pnPreceding"
>                       select="$pnPreceding"/>
>     </xsl:apply-templates>
>     <xsl:apply-templates select="following-sibling::node()[1]">
>       <xsl:with-param name="pnAncestors" 
>                       select="$pnAncestors"/>
>       <xsl:with-param name="pnPreceding"
>                       select="$pnPreceding+1"/>
>           
>     </xsl:apply-templates>
>     
>   </xsl:template>
> 
> </xsl:stylesheet>


Ooppss... 

The last but one xsl:apply-templates must be inside xsl:copy.

So, the correct override for elements is:

  <xsl:template match="*">
    <xsl:param name="pnAncestors" select="0"/>
    <xsl:param name="pnPreceding" select="0"/>
    
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:attribute name="_id">
        <xsl:value-of select=
                    "concat(name(), '_',
                            $pnAncestors, '_', 
                            $pnPreceding 
                            )"/>
      </xsl:attribute>
      <xsl:apply-templates select="node()[1]">
        <xsl:with-param name="pnAncestors" 
                        select="$pnAncestors+1"/>
        <xsl:with-param name="pnPreceding"
                        select="$pnPreceding"/>
      </xsl:apply-templates>
    </xsl:copy>
    <xsl:apply-templates select="following-sibling::node()[1]">
      <xsl:with-param name="pnAncestors" 
                      select="$pnAncestors"/>
      <xsl:with-param name="pnPreceding"
                      select="$pnPreceding+1"/>
          
    </xsl:apply-templates>
    
  </xsl:template>

Cheers,

Dimitre Novatchev 
FXSL developer,

http://fxsl.sourceforge.net/ -- the home of FXSL
Resume: http://fxsl.sf.net/DNovatchev/Resume/Res.html


__________________________________
Do you Yahoo!?
Yahoo! Mail SpamGuard - Read only the mail you want.
http://antispam.yahoo.com/tools

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


Current Thread