[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Re-Organize and Sort Source Tree (Muenchian Method

Subject: Re: Re-Organize and Sort Source Tree (Muenchian Method)
From: Anton Triest <anton@xxxxxxxx>
Date: Wed, 29 Sep 2004 21:53:56 +0200
xsl key sort
Hi Ethan,

Here's a stylesheet that produces the desired output, by using the identity transform
to copy all elements, and additional templates to match the elements you want to change:


<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">


   <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
   <xsl:strip-space elements="*"/>

   <!-- keys by city name -->
   <xsl:key name="cities" match="city" use="."/>
   <xsl:key name="offices" match="office" use="cities/city"/>

   <!-- identity transform: copy all elements -->
   <xsl:template match="*">
       <xsl:copy>
           <xsl:copy-of select="@*"/>
           <xsl:apply-templates/>
       </xsl:copy>
   </xsl:template>

   <!-- sort divisions by @id -->
   <xsl:template match="divisions">
       <divisions>
           <xsl:apply-templates select="division">
               <xsl:sort select="@id"/>
           </xsl:apply-templates>
       </divisions>
   </xsl:template>

   <!-- sort regions and countries by @name -->
   <xsl:template match="regions|countries">
       <xsl:copy>
           <xsl:apply-templates select="region|country">
               <xsl:sort select="@name"/>
           </xsl:apply-templates>
       </xsl:copy>
   </xsl:template>

<!-- reorganize 'country' elements -->
<xsl:template match="country">
<country>
<xsl:copy-of select="@*"/>
<cities>
<!-- group 'city' elements -->
<xsl:apply-templates select="offices/office/cities/city[count(.|key('cities',.)[1])=1]">
<xsl:sort select="."/>
</xsl:apply-templates>
</cities>
</country>
</xsl:template>


   <!-- new 'city' elements -->
   <xsl:template match="city">
       <city>
           <name><xsl:value-of select="."/></name>
           <offices>
               <xsl:apply-templates select="key('offices',.)">
                   <xsl:sort select="name"/>
               </xsl:apply-templates>
           </offices>
       </city>
   </xsl:template>

   <!-- new office elements -->
   <xsl:template match="office">
       <office>
           <xsl:copy-of select="@*"/>
           <!-- copy all children except 'cities' -->
           <xsl:apply-templates select="*[local-name()!='cities']"/>
       </office>
   </xsl:template>

</xsl:stylesheet>

Note however, the Muenchian grouping will only work properly if there are no cities
with the same name in different countries (the 'cities' key matches all city elements
throughout the document). If that's a problem you'll have to include additional
information in the key's 'use' value, something like:


<xsl:key name="cities" match="city" use="concat(ancestor::country/@name,'-',.)"/>

and then of course, use the same test in the Muenchian grouping predicate:

[count(.|key('cities',concat(ancestor::country/@name,'-',.))[1])=1]

Cheers,
Anton

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.