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

Re: [xsl] Sorting and grouping unknown elements


Subject: Re: [xsl] Sorting and grouping unknown elements
From: David Carlisle <davidc@xxxxxxxxx>
Date: Fri, 21 Sep 2007 13:06:08 +0100

> I'm very new to xml/xsl transformation and am faced with the following
> problem. 

One of the main new features added in XSLT2 is explict support for
grouping, so for groupiung problems it's especially useful if you say
whether you are using XSLT2 or XSLT 1.

	<xsl:for-each select="//{name()}[not(. = following::{name()})]">

XPath expressions never use {} brackets (except in strings of course) so
I'm not sure what you intended here. Also beware using // it means
"search every element at arbitrary depth in the document" so typically
it's slow. If you start an XPath with / or // then it is starting teh
query from the top of the document each time, ignoring the current node
which is the child of the row element, so even if you fixed teh xpath
syntax error
	<xsl:for-each select="//anything">
		<xsl:sort/>
         zzzzzzzzz
	</xsl:for-each>

would produce identical output each time it was executed by the outer
for-each.	

sooo, in xslt2 you'd want

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:template match="rowset">
    <xsl:for-each-group select="row/*" group-by="name()">
      <xsl:sort select="name()"/>
      <select name="{current-grouping-key()}">
	<xsl:for-each select="current-group()">
	  <xsl:sort/>
	  <option><xsl:value-of select="."/></option>
	</xsl:for-each>
      </select>
    </xsl:for-each-group>
  </xsl:template>
</xsl:stylesheet>

$ saxon8 rs.xml rs2.xsl
<?xml version="1.0" encoding="UTF-8"?>
<select name="color">
   <option>Blue</option>
   <option>Red</option>
</select>
<select name="make">
   <option>Toyota</option>
   <option>Toyota</option>
</select>
<select name="model">
   <option>Corolla</option>
   <option>Yaris</option>
</select>


which in xslt1 would be

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:key  name="n" match="*" use="name()"/>
  <xsl:template match="rowset">
    <xsl:for-each select="row/*[generate-id(.)=generate-id(key('n',name()))]">
      <xsl:sort select="name()"/>
      <select name="{name()}">
	<xsl:for-each select="key('n',name())">
	  <xsl:sort/>
	  <option><xsl:value-of select="."/></option>
	</xsl:for-each>
      </select>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

$ saxon rs.xml rs1.xsl
<?xml version="1.0" encoding="utf-8"?>
<select name="color">
   <option>Blue</option>
   <option>Red</option>
</select>
<select name="make">
   <option>Toyota</option>
   <option>Toyota</option>
</select>
<select name="model">
   <option>Corolla</option>
   <option>Yaris</option>
</select>

________________________________________________________________________
The Numerical Algorithms Group Ltd is a company registered in England
and Wales with company number 1249803. The registered office is:
Wilkinson House, Jordan Hill Road, Oxford OX2 8DR, United Kingdom.

This e-mail has been scanned for all viruses by Star. The service is
powered by MessageLabs. 
________________________________________________________________________


Current Thread
Keywords