Re: [xsl] Meunch away on this

Subject: Re: [xsl] Meunch away on this
From: Nic James Ferrier <nferrier@xxxxxxxxxxxxxxxxxxxx>
Date: Fri, 22 Dec 2006 10:16:30 +0000
"Thomas Stone" <stonethomasjames@xxxxxxxxx> writes:

>    Here is what I came up with that seems pretty straight forward.
>    Using the Position() function within the sorted list, only output
>    the first position.  This will always get the first entry in
>    alphabetical order.  Select sorted all elements that are not the
>    same name as the first and recurse to the same procedure, thus
>    displaying only the second entry in alphabetical order.  Append
>    each entry to a delimited string array and use a Contains() test
>    to eliminate duplicates from the next selection list.
>
>           <xsl:apply-templates select="//*" mode="unique">
>             <xsl:sort select="name()"/>
>             <xsl:with-param name="code_list" select="';'"/>
>           </xsl:apply-templates>
>
>
>   <xsl:template match="*" mode="unique">
>     <xsl:param name="code_list"/>
>     
>     <xsl:if test="position()=1">
>       
>       <xsl:variable name="ent_name" select="name()"/>
>       
>       <tr>
>         <td><xsl:value-of select="$ent_name"/></td>
>       </tr>
>       
>       <xsl:variable name="new_list" select="concat($code_list, concat($ent_name, ';'))"/>
>       
>       <xsl:apply-templates select="//*[contains($new_list, concat(';', concat(name(), ';')))=false()]" mode="unique">
>         <xsl:sort select="name()"/>
>         <xsl:with-param name="code_list" select="$new_list"/>
>       </xsl:apply-templates>
>     </xsl:if>
>   </xsl:template>

This looks great. It's recursive so it wouldn't work on really,
really, big data (I can't see that it's tail recursive). But none the
less, it is quite simple to explain.


>    This gives me a unique sorted list of all entities in the document.  I prefer to have them enumerated.
>
>           <xsl:apply-templates select="//*" mode="summary">
>             <xsl:sort select="name()"/>
>             <xsl:with-param name="code_list" select="';'"/>
>             <xsl:with-param name="seq_counter" select="1"/>
>           </xsl:apply-templates>
>
>
>   <xsl:template match="*" mode="summary">
>     <xsl:param name="code_list"/>
>     <xsl:param name="seq_counter"/>
>     
>     <xsl:if test="position()=1">
>       
>       <xsl:variable name="ent_name" select="name()"/>
>       
>       <tr>
>         <td><xsl:value-of select="$seq_counter"/></td>
>           <td><xsl:value-of select="$ent_name"/></td>
>       </tr>
>       
>       <xsl:variable name="new_list" select="concat($code_list, concat($ent_name, ';'))"/>
>       
>       <xsl:apply-templates select="//*[contains($new_list, concat(';', concat(name(), ';')))=false()]" mode="summary">
>         <xsl:sort select="name()"/>
>         <xsl:with-param name="code_list" select="$new_list"/>
>         <xsl:with-param name="seq_counter" select="$seq_counter+1"/>
>       </xsl:apply-templates>
>     </xsl:if>
>   </xsl:template>
>
>
>
>    From this structure, I can group by placing a correlated
>    sub-query <apply-templates> where the <tr> output is.  The
>    uniqueness test can be applied just as directly to character data
>    or attributes.

Cool!

You need to write this up on a webpage somewhere.

-- 
Nic Ferrier
http://www.tapsellferrier.co.uk   for all your tapsell ferrier needs

Current Thread