Sorting Elements

Sorting Elements

You can use <xsl: sort > to sort nodes. This element sets the order of node processing for <xsl:apply-templates> and <xsl:for-each> . The following list includes the attributes of <xsl:sort> :

  • select (optional). Sets to an XPath expression that returns a node set to sort. The default is string(.).

  • order (optional). Sets the sort order; set to ascending or descending.

  • case-order (optional). Determines whether upper-case letters come before lower-case letters . Set to upper-first or lower-first.

  • lang (optional). Sets the language whose sorting conventions are to be used. Set to a language code valid in the xml:lang attribute.

  • data-type (optional). Sets whether the sort should be alphabetical or numerical. Set to text, number, or a QName.

This element takes no content. You use it inside <xsl:apply-templates> or <xsl:for-each> elements to sort the node sets on which those elements work.

In the following example, I just sort the <PLANET> elements in planets.xml in ascending alphabetical order based on their names , using <xsl:for-each> in a simplified stylesheet:

Listing 5.9 Sorting Data
 <HTML xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xsl::version="1.0">      <HEAD>          <TITLE>             The Sorted Planets Table          </TITLE>      </HEAD>      <BODY>          <H1>             The Sorted Planets Table          </H1>          <TABLE BORDER="2">             <TR>                  <TD>Name</TD>                  <TD>Mass</TD>                  <TD>Radius</TD>                  <TD>Day</TD>             </TR>             <xsl:for-each select="//PLANET">                 <xsl:sort/>                 <TR>                     <TD><xsl:value-of select="NAME"/></TD>                     <TD><xsl:value-of select="MASS"/></TD>                     <TD><xsl:value-of select="RADIUS"/></TD>                     <TD><xsl:value-of select="DAY"/></TD>                 </TR>              </xsl:for-each>          </TABLE>      </BODY>  </HTML> 

And heres the result. Note that the planets are indeed sorted as Earth, Mercury, and then Venus:

 <HTML>      <HEAD>          <TITLE>             The Sorted Planets Table          </TITLE>      </HEAD>      <BODY>          <H1>             The Sorted Planets Table          </H1>          <TABLE BORDER="2">              <TR>                  <TD>Name</TD>                  <TD>Mass</TD>                  <TD>Radius</TD>                  <TD>Day</TD>              </TR>              <TR>                  <TD>Earth</TD>                  <TD>1</TD>                  <TD>2107</TD>                  <TD>1</TD>              </TR>              <TR>                  <TD>Mercury</TD>                  <TD>.0553</TD>                  <TD>1516</TD>                  <TD>58.65</TD>              </TR>              <TR>                  <TD>Venus</TD>                  <TD>.815</TD>                  <TD>3716</TD>                  <TD>116.75</TD>              </TR>          </TABLE>      </BODY>  </HTML> 

You can see this result in Figure 5.1.

Figure 5.1. Sorting using a simplified template.
graphics/05fig01.gif

You use the select attribute to specify what to sort on. For example, heres how I sort the planets based on density:

Listing 5.10 Sorting Planets Based on Density
 <?xml version="1.0"?>  <xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">      <xsl:template match="PLANETS">          <HTML>              <HEAD>                  <TITLE>                      Planets                  </TITLE>              </HEAD>              <BODY>                  <H1>Planets sorted by density</H1>                  <TABLE>                      <TR>                          <TD>Planet</TD>                          <TD>Mass</TD>                          <TD>Day</TD>                          <TD>Density</TD>                      </TR>                      <xsl:apply-templates>                          <xsl:sort select="DENSITY"/>                      </xsl:apply-templates>                  </TABLE>              </BODY>          </HTML>      </xsl:template>      <xsl:template match="PLANET">          <TR>              <TD><xsl:apply-templates select="NAME"/></TD>              <TD><xsl:apply-templates select="MASS"/></TD>              <TD><xsl:apply-templates select="DAY"/></TD>              <TD><xsl:apply-templates select="DENSITY"/></TD>          </TR>      </xsl:template>  </xsl:stylesheet> 

Here are the results of this transformation:

 <HTML>      <HEAD>          <TITLE>              Planets          </TITLE>      </HEAD>      <BODY>          <H1>              Planets sorted by density          </H1>          <TABLE>              </TR>                  <TD>Planet</TD>                  <TD>Mass</TD>                  <TD>Day</TD>                  <TD>Density</TD>              </TR>              <TR>                  <TD>Venus</TD>                  <TD>.815</TD>                  <TD>116.75</TD>                  <TD>.943</TD>              </TR>              <TR>                  <TD>Mercury</TD>                  <TD>.0553</TD>                  <TD>58.65</TD>                  <TD>.983</TD>              </TR>              <TR>                  <TD>Earth</TD>                  <TD>1</TD>                  <TD>1</TD>                  <TD>1</TD>              </TR>          </TABLE>      </BODY>  </HTML> 

By default, <xsl:sort> performs an alphabetic sort, which means that 10 comes before 2. You can perform a true numeric sort by setting the datatype attribute to number like this:

 <xsl:sort data-type="number" select="DENSITY"/> 

You can create descending sorts by setting the <xsl:sort> elements order attribute to descending. You can also sort on attribute values like this:

 <xsl:apply-templates select="PLANETS">      <xsl:sort select="@SIZE"/>  </xsl:apply-templates> 

Coming up in XSLT 2.0

One of the big issues in XSLT 2.0 is support for XML schemas, and just as you can sort on strings or numbers now, the W3C is planning to let you sort on any data type specified in a documents schema in XSLT 2.0.

Using Multiple Sort Criteria

Its also worth noting that you can use multiple sort criteria in your sorting operations. To do so, simply use multiple <xsl:sort> elements. The first <xsl:sort> element sorts on the major criterion, the next element can sort on the next major criterion, and so on. For example, heres how you could sort on distance first, then on planet density (which will order planets that were at the same distance from the sun by density) inside an <xsl:apply-templates> element:

 <xsl:apply-templates>      <xsl:sort select="DISTANCE"/>      <xsl:sort select="DENSITY"/>  </xsl:apply-templates> 

That completes this discussion of sorting; next Ill turn to an allied topic: numbering.



Inside XSLT
Inside Xslt
ISBN: B0031W8M4K
EAN: N/A
Year: 2005
Pages: 196

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net