RE: [xsl] Is this a legal XPath Expression?

Subject: RE: [xsl] Is this a legal XPath Expression?
From: "Phil Gooch" <phil.gooch@xxxxxxxxx>
Date: Thu, 15 Mar 2001 13:22:04 -0000
Thanks Jeni - that's just brilliant. You're a genius!

Phil

> -----Original Message-----
> From: owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> [mailto:owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx]On Behalf Of Jeni Tennison
> Sent: Thursday, March 15, 2001 1:08 PM
> To: Phil Gooch
> Cc: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: Re: [xsl] Is this a legal XPath Expression?
> 
> 
> Hi Phil,
> 
> > Basically what I am doing is TRying to find unique occurrences of
> > the contents of cells in column 15 of an HTML table, e.g
> [snip]
> > , then, for each of these, pick out unique occurrences of the
> > contents of cells in column 28, and for each of those, pick out the
> > contents of cell 3. Looks like a job for <saxon:group>, but I
> > couldn't figure out how to do it, so my code looks like this: (it
> > works, but its v. inefficient!)
> 
> I'd use keys for this (i.e. the Muenchian Method), and index each
> *row* according to:
> 
>   (a) column 15
>   (b) column 15 + column 28
>   (c) column 15 + column 28 + column 3
> 
> The three keys would be:
> 
> <xsl:key name="group-15"      match="TR"
>          use="TD[15]" />
> <xsl:key name="group-15-28"   match="TR"
>          use="concat(TD[15], '::', TD[28])" />
> <xsl:key name="group-15-28-3" match="TR"
>          use="concat(TD[15], '::', TD[28], '::', TD[3])" />
> 
> Now you should apply templates to only the unique rows. In the first
> go, those are the rows where they're the first node in the list
> returned when you use the 'group-15' key with a value of their own
> TD[15] child.  So apply templates with:
> 
> <xsl:apply-templates
>    select="TR[count(.|key('group-15', TD[15])[1]) = 1]"
>    mode="group-15" />
> 
> The count() expression counts how many nodes there are in the node set
> consisting of (a) the TR element you're looking at and (b) the first
> of the nodes returned by the 'group-15' key when you use an index
> value of the TR element that you're looking at's TD[15] child.
> 
> Then you can have a template that matches the TR elements in
> 'group-15' mode.  This template will only ever be applied to the
> TR elements with unique values for their TD[15] child, so you don't
> have to worry about testing the TR element for uniqueness.  Here, you
> apply templates according to the second grouping in a very similar way
> to how it's done above.
> 
> <xsl:template match="TR" mode="group-15">
>    <xsl:variable name="subject" select="TD[15]" />
>    <xsl:if test="string($subject)">
>       <xsl:variable name="link" select="generate-id($subject)"/>
>       <tr>
>          <td>
>             <a href="{$link}.html"><xsl:value-of select="$subject"/></a>
>          </td>
>       </tr>
>       <!-- for each subject, output the project title to a sep. file-->
>       <saxon:output file="{concat($link, '.html')}">
>          <html><head></head>
>             <body><table>
>                <xsl:apply-templates
>                    select="//TR[count(.|key('group-15-28',
>                                             concat($subject, 
> '::', TD[28])[1]) = 1]"
>                    mode="group-15-28" />
>             </table></body>
>          </html>
>       </saxon:output>
>    </xsl:if>
> </xsl:template>
> 
> Then you have another template that matches TR elements but in
> group-15-28 mode.  Again it applies templates to the uniquely valued
> table rows only:
> 
> <xsl:template match="TR" mode="group-15-28">
>    <xsl:variable name="subject" select="TD[3]" />
>    <xsl:variable name="projecttitle" select="TD[28]" />
>    <xsl:if test="string($projecttitle)">
>       <xsl:variable name="link" select="generate-id($projecttitle)" />
>       <tr>
>          <td>
>             <a href="{$link}.html"><xsl:value-of 
> select="$projecttitle"/></a>
>          </td>
>       </tr>
> 
>       <!-- for each project, output the filename to a sep. file-->
>       <saxon:output file="{concat($link, '.html')}">
>          <html><head></head>
>             <body><table>
>                <xsl:apply-templates
>                    select="//TR[count(.|
>                                       key('group-15-28-3',
>                                           concat($subject, '::',
>                                                  $projecttitle, '::',
>                                                  TD[3])[1]) = 1]"
>                    mode="group-15-28-3" />
>             </table></body>
>          </html>
>       </saxon:output>
> 
>    </xsl:if>
> </xsl:template>
> 
> And finally a template that matches in group-15-28-3 mode:
> 
> <xsl:template match="TR" mode="group-15-28-3">
>    <xsl:variable name="fn"  select="TD[3]"/>
>    <tr>
>       <td>
>          <a href="{$fn}">Download <xsl:value-of select="$fn"/></a>
>       </td>
>    </tr>
> </xsl:template>
> 
> This is untested as I didn't have a sample.  But I think it should
> roughly work.
> 
> I hope that helps,
> 
> Jeni
> 
> ---
> Jeni Tennison
> http://www.jenitennison.com/
> 
> 
> 
>  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
> 
> 


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


Current Thread