[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
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
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|