Sorting in XSLT
by Bob DuCharme
|
Pages: 1, 2, 3, 4
Let's look at how the xsl:for-each instruction can use xsl:sort. The following stylesheet takes the same winelist document above and lists the wines. When it gets to a Chardonnay, it lists all the other Chardonnays alphabetically.
<!-- xq439.xsl: converts xq436.xml into xq440.txt -->
<!DOCTYPE stylesheet [
<!ENTITY space "<xsl:text> </xsl:text>">
]>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes" indent="no"/>
<xsl:template match="wine">
<xsl:apply-templates select="winery"/>&space;
<xsl:apply-templates select="product"/>&space;
<xsl:apply-templates select="year"/>&space;
<xsl:apply-templates select="@grape"/>
<xsl:if test="@grape = 'Chardonnay'">
<xsl:text>
other Chardonnays:
</xsl:text>
<xsl:for-each
select="preceding-sibling::wine[@grape = 'Chardonnay'] |
following-sibling::wine[@grape = 'Chardonnay']">
<xsl:sort select="winery"/>
<xsl:text> </xsl:text>
<xsl:value-of select="winery"/>&space;
<xsl:value-of select="product"/><xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:if>
</xsl:template>
Before we examine how the stylesheet does this, let's take a look at the result:
Lindeman's Bin 65 1998 Chardonnay
other Chardonnays:
Benziger Carneros
Kendall Jackson Vintner's Reserve
Benziger Carneros 1997 Chardonnay
other Chardonnays:
Kendall Jackson Vintner's Reserve
Lindeman's Bin 65
Duckpond Merit Selection 1996 Cabernet
Kendall Jackson Vintner's Reserve 1998 Chardonnay
other Chardonnays:
Benziger Carneros
Lindeman's Bin 65
(First, notice the "&space;" entity references throughout the stylesheet. Instead of writing "<xsl:text> </xsl:text>" over and over because I needed single spaces in so many places, it was easier to declare an entity named space in the DOCTYPE declaration with this xsl:text element as content and to then plug it in with an entity reference whenever I needed it.) The xsl:template template rule for the wine element has xsl:apply-templates instructions for its winery, product, and year element children followed by one for its grape attribute. Then, if the grape attribute has a value of "Chardonnay", it adds the text "other Chardonnays:" to the result tree followed by the list of Chardonnays, which are added to the result tree using an xsl:for-each instruction.
The select attribute of the xsl:for-each attribute selects all the nodes that are either preceding siblings of the current node with a grape value of "Chardonnay" or following siblings of the current node with the same grape value. (The "|" symbol is the "or" part.) For each wine element that meets this select attribute's condition, the template first adds some white space indenting with an xsl:text element, then the value of the wine element's winery child, a space, and the value of its product child. The first instruction in this xsl:for-each element is an xsl:sort element, which tells the XSLT processor to sort the nodes selected by the xsl:for-each instruction alphabetically in "winery" order. That's how they look in the result: after the first "other Chardonnays:" label, "Kendall Jackson" comes after "Benziger"; after the second, "Lindeman's" comes after "Kendall Jackson"; and after the last one, "Lindeman's" comes after "Benziger".
Because the xsl:for-each instruction lets you grab and work with any node set that you can describe using an XPath expression, the ability to sort one of these node sets makes it one of XSLT's most powerful features.
Next month, we'll see how xsl:sort can help find the first, last, biggest, and smallest value in a document according to a certain criteria. (If you can't wait, see my book XSLT Quickly, from which these columns are excerpted.)
Have you found interesting uses for xsl:sort? Share your discoveries in our forum.
(* You must be a member of XML.com to use this feature.)
Comment on this Article
| Titles Only | Titles Only | Newest First |
- great article thanks
2009-05-09 09:14:10 jixel [Reply]
i wasn't sure if/how to do a cascading sort and truthfully this article is the best one out there on the subject
- xsl:sort
2007-07-13 06:16:06 ArsenyX [Reply]
In my XML text is in CDATA.
What do I need to sort text on alphabet?
Thanks in advance.
- sort
2005-11-28 12:51:49 harvy [Reply]
Is it possible to sort by order of nodes as they are in the xml list?
ie if teh xml file is:
a
b
c
and i want to reverse the order so that it displays
c
b
a
what do i sort with?
- Custom built xsl:sort
2005-09-06 18:49:53 srinivasvemuri [Reply]
Hi,
How do i proceed if i were to sort say using Time Period, where my values are Early Bronze, A.D.,BYZANTINE, IRON I. i.e., Sorting with domain knowledge!!!
- Custom built xsl:sort
2005-09-06 19:23:45 Bob DuCharme [Reply]
XSLT sorts alphabetically or numerically. It would be an interesting exercise to map your values to alphanumeric key values and trying to sort by those, though.
- Custom built xsl:sort
2005-09-07 12:22:45 srinivasvemuri [Reply]
Thanks for the suggestion. Could you explain in detail. I have a different xml file that maps each time period to an integer.
ex. period.xml --->
<entry period="middlebronze">1</entry>
<entry period="byzantine">2</entry>
<entry period="Roman">3</entry>
<entry period="islamic">4</entry>
How do above file in xslt sort based on time period? I am trying something like this!!!!
<xsl:for-each select="timeperiod">
<xsl:sort select='key(?,?)' />
</xsl:for-each>
- Custom built xsl:sort
2005-09-07 14:02:01 Bob DuCharme [Reply]
I haven't followed through on this myself, and doing so and then providing a detailed explanation will take more time than I have available right now. I suggest you try the XSL-list at http://www.mulberrytech.com/xsl/xsl-list/.
- Custom built xsl:sort
- Custom built xsl:sort
- Custom built xsl:sort
- Xml and XSLT
2004-04-27 00:52:07 bertcox [Reply]
hello,
I'm using C# to display Xml-data in a datagrid. Now i want the datagrid to be sorted. I heard the best way to sort the xml-file is to use XSLT. I'm new to c#,xml and xslt so i don't really know what to do. I read your article and it's defenitely the best i've found. But there are some things i do not understand. I can call the XSLT-file in C#? Does it create a new Xml-file? Or just sorts the original and saves it?
Thx a lot in advance,
Bert Cox
- Xml and XSLT
2004-05-29 06:56:13 Kitsuneymg [Reply]
to associate an xml file with an xsl file include this line in the xml file right after the <?xml version=......?>
<<?xml-stylesheet alternate="no" href="myxsl.xsl" type="text/xsl"?>
- Xml and XSLT
- static or dynamic...?
2004-01-10 13:10:05 john clariond [Reply]
XSLT is well explain, OK.
I understand that the result is static, informations are seen like the XSLT stylesheet is write, because we must call the XML file...OK ?
and in this XML file is the hard reference to the XSLT stylesheet...!
But... how can we insert a choice in the web pages...?
Thank'a a lot.
- static or dynamic...?
2004-05-29 06:58:01 Kitsuneymg [Reply]
read the article at http://www.xmlfiles.com/xsl/xsl_client.asp
- static or dynamic...?
- Parameters
2002-09-04 03:53:25 Dave Goodman [Reply]
Great article, but one omission - How do you pass through the direction or attribute to sort on dynamically - e.g. as a parameter to the url, e.g.
http://www.mysite.com/sorted.xml?direction=Ascending
Regards
Dave
- Parameters
2004-05-29 07:00:03 Kitsuneymg [Reply]
try looking for javascript, php, asp, or jsp solutions
- Parameters
2004-04-20 04:43:04 SK [Reply]
Hi
- Parameters
2004-04-20 04:37:28 SK [Reply]
- Parameters
2004-04-20 04:34:39 SK [Reply]
Hi
- Parameters
- Use of xsl:sort
2002-07-04 05:38:50 Raj Krishnan [Reply]
This is a very good article. A simple concept explained well. THe arrangement of the subject in a porgressively advanced format makes it interesting and allows the reader to use the sort function in several ways.
Good work!
