xsl-list
[Top] [All Lists]

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

2009-06-10 12:47:38
Newman, John W wrote:


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

Here is an XSLT 1.0 stylesheet that use the exsl:node-set extension function. As far as I know Xalan supports that or at least has an extension function in its own namespace that has the same result:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
  xmlns:exsl="http://exslt.org/common";
  exclude-result-prefixes="exsl"
  version="1.0">

  <xsl:output method="text"/>

  <xsl:param name="nl" select="'&#13;&#10;'"/>

  <xsl:template match="root">
    <xsl:variable name="sorted-elements">
     <root>
      <xsl:for-each select="red | blue">
        <xsl:sort select="@order" data-type="number"/>
        <xsl:copy-of select="."/>
      </xsl:for-each>
     </root>
    </xsl:variable>
<xsl:apply-templates select="exsl:node-set($sorted-elements)/root/*[1]"/>
  </xsl:template>

  <xsl:template match="blue | red">
    <xsl:if test="not(preceding-sibling::*[1]/@key = @key)">
      <xsl:value-of select="concat(@key, $nl)"/>
    </xsl:if>
    <xsl:value-of select="concat(@text, $nl)"/>
    <xsl:apply-templates select="following-sibling::*[1]"/>
  </xsl:template>

</xsl:stylesheet>

--

        Martin Honnen
        http://msmvps.com/blogs/martin_honnen/

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>