Re: [xsl] Removing Duplicates & Formatting

Subject: Re: [xsl] Removing Duplicates & Formatting
From: JCS <subscriber@xxxxxxxxxxxxx>
Date: Thu, 11 Dec 2003 21:05:18 +1300
Hi David,

Thanks a lot for taking the time to devise a solution for me. I was playing
with keys when this came in the mail. I was glad to know that my idea of
making two passes wasn't all that nuts, only I wasn't sure how to go about
making two passes. I generally use Sablotron, but the Saxon extension didn't
work so I used libxslt. That worked.

Your solution presented some interesting results. The first, most notable,
was that the paths were not in the order of the XML tree--what I mean is,
the first five or six paths in the XML document were output at the bottom of
the result. I have a few ideas why this might have happened but I couldn't
explain them properly yet. (?)

The second thing is that your solution works, however I was hoping to get
the paths grouped together somehow (and why I was looking at a key solution
perhaps?) like so:

 one/two
 one/two/three
 one/two/four
 one/two/four/one
 one/two/four/two

Etc.

Hopefully that makes sense.

And last but not least, I tried to substitute the <p> element in your
solution (and change the saxon expression) to <div class="foo"> but it
didn't work--the duplicates came forth. I was, however able to keep the <p>
element and put font coloring in place like so:

<xsl:template match="/">
<html>
    <font face="'Courier New', Courier, mono">
    <xsl:variable name="x">
    <xsl:for-each select="//*[not(*)]">
    <p>
     <font color="blue">
       <xsl:for-each select="ancestor::*">
        <xsl:value-of select="name()"/><xsl:text>/</xsl:text>
       </xsl:for-each>
     </font>
     <font color="red">
        <xsl:value-of select="name()"/>
     </font>
    </p>
    </xsl:for-each>
    </xsl:variable>

<xsl:copy-of select="saxon:node-set($x)/p[not(.=following-sibling::p)]"/>
 </font>
</html>
</xsl:template>

When I was playing with keys, I'm able to easily match and group the text,
but what I'm wondering is how one would "use" an element node to group
elements. For example, I wrote:

<xsl:key name="myKey" match="//*[not(*)]" use="name()"/>

I'm not sure if that's correct. I'm thinking it will match all the
descendent element nodes of the root node that don't have children nodes,
and use the name of the element node as the index. I thought there would be
a way to group and sort the paths together using the Munchkin method.

I'll be playing around with this some more, if there are any suggestions
please let me know. And David, of course, thanks heaps for your help. Much
appreciated. :-)

/johnny :)


On 11/12/03 3:44 AM, "David Carlisle" <davidc@xxxxxxxxx> wrote:

> 
> you'd probbaly better off doing this in two passes, first get the paths
> then elimiate duplicates.
> 
> this uses saxon node-set extension to do two passes in one stylesheet,
> more or less every xslt engine (except mozilla) has a similar extension.
> 
> <a>
> <b><c/><c/><d/></b>
> <b><d/></b>
> <c><d><e/></d></c>
> <c><d><e/></d></c>
> </a>
> 
> 
> 
> 
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="1.0"
> xmlns:saxon="http://icl.com/saxon";
> extension-element-prefixes="saxon"
>> 
> <xsl:output method="xml" indent="yes" />
> 
> <xsl:key name="ref" match="elem" use="ref"/>
> 
> <xsl:template match="/">
> <xsl:variable name="x">
> <xsl:for-each select="//*[not(*)]">
> <p>
> <xsl:for-each select="ancestor-or-self::*"
>> /<xsl:value-of select="name()"/>
> </xsl:for-each>
> </p>
> </xsl:for-each>
> </xsl:variable>
> 
> <xsl:copy-of select="saxon:node-set($x)/p[not(.=following-sibling::p)]"/>
> </xsl:template>
> 
> 
> </xsl:stylesheet>
> 
> $ saxon path.xml path.xsl
> <?xml version="1.0" encoding="utf-8"?>
> <p>/a/b/c</p>
> <p>/a/b/d</p>
> <p>/a/c/d/e</p>
> 

-- 
There are no blueprints for friendships, each one is custom made.
-- Robert Scotellaro 


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


Current Thread