[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

[xsl] Sort by one attribute & use Muenchian technique to group by another attribute?


Subject: [xsl] Sort by one attribute & use Muenchian technique to group by another attribute?
From: "Newman, John W" <newmanjw@xxxxxxxx>
Date: Wed, 10 Jun 2009 12:23:08 -0400

Hello,

I am using XSLT 1.0 - I cannot upgrade to 2.0 at this time.  If the author of
Saxon 9.0 would upload the releases to the central maven2 repository, myself
and many more users might be able to do that.  Hint hint if he is reading
this.  =)

Processor details:
Name: org/apache/xalan
Comment: Main Xalan engine implementing TrAX/JAXP
Specification-Title: Java API for XML Processing
Specification-Vendor: Sun Microsystems Inc.
Specification-Version: 1.2
Implementation-Title: org.apache.xalan
Implementation-Version: 2.6.0

Anyway, I could really use some help or guidance here.  I have two sets of
nodes that are intermixed - I need to output them ordered by a sort order
attribute, and group them by a key attribute such that the key only shows up
when it changes from the previously sorted item.  Here's a simplified
example:

Test.xml:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="Test.xsl" type="text/xsl"?>

<root>
                <red order="1" key="F" text="red 1 B" />
                <red order="3" key="F" text="red 3 B" />
                <red order="4" key="C" text="red 4 C" />
                <red order="6" key="D" text="red 6 D" />
                <red order="9" key="E" text="red 9 E" />
                <red order="10" key="F" text="red 10 F" />
                <blue order="2" key="B" text="blue 2 B" />
                <blue order="5" key="D" text="blue 5 D" />
                <blue order="7" key="D" text="blue 7 D" />
                <blue order="8" key="E" text="blue 8 E" />
                <blue order="11" key="F" text="blue 11 F" />
                <blue order="12" key="G" text="blue 12 G" /> </root>

Expected output:
F:
red 1 B
B:
blue 2 B
F:
red 3 B
C:
red 4 C
D:
blue 5 D
red 6 D
blue 7 D
E:
blue 8 E
red 9 E
F:
red 10 F
blue 11 F
G:
blue 12 G
 
Notice how @order is how they are sorted there, and the @key is only output
when it is different from the previous one.
 

Using this stylesheet, I've been able to produce something *close but still a
ways off.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
       
         <xsl:key name="keyRedBlue" match="red|blue" use="@key"/>
         
         <xsl:template match="root">
               <xsl:apply-templates select="(red|blue)[generate-id() =
generate-id(key('keyRedBlue', @key))]" mode="distinct-start">
                       <xsl:sort select="@order" data-type="number" />
               </xsl:apply-templates>
        </xsl:template>
       
        <xsl:template match="red|blue" mode="distinct-start">
               <xsl:value-of select="@key" />:<br />
               <xsl:apply-templates select="key('keyRedBlue', @key)">
                       <xsl:sort select="@order" data-type="number" />
               </xsl:apply-templates>
        </xsl:template>
               
        <xsl:template match="red">
               <xsl:value-of select="@text" /><br />
        </xsl:template>
       
        <xsl:template match="blue">
               <xsl:value-of select="@text" /><br />
        </xsl:template>
</xsl:stylesheet>


produces:

F:
red 1 B
red 3 B  < WRONG
red 10 F
blue 11 F
B:
blue 2 B
C:
red 4 C
D:
blue 5 D
red 6 D
blue 7 D
E:
blue 8 E
red 9 E
G:
blue 12 G

So how can I do this?  Is it even possible?  Previous-sibling isn't an option
since they are not ordered in the document.  I am not willing to use 2 xsl
sheets for this.  A brute-force style for-each in the leaf templates could go
and check the previous sorted one's key I guess, but that is pretty lousy.  If
I could just change the value of an xsl:variable this would have not even
required any thought, but I understand that is done for parser efficiency so I
am semi-ok with that.  And if there were any real options for xslt 2.0 in java
we could move to that and use the new group features.

Thanks for reading and any help is tremendously appreciated!
-John


Current Thread
Keywords