Welcome to WebmasterWorld Guest from

Forum Moderators: httpwebwitch

xsl:sort within xsl:sort

sort then sub-sort

6:45 pm on Jul 8, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member

I have an xml that contains the names and addresses of companies. Short xml:
<state option="1"></state>

I want the output to sort the companies first by state THEN within each state, sort the company names alphabetically:

Company A
Company B
Company M
Company S
Company Y
Company F
Company L
Company P
And so on.

I tried
<xsl:sort select="state"/>
<xsl:sort select=companyname"/>
but what happens is it sorts by company name, not by state. If I remove <xsl:sort select=companyname"/>, it sorts perfectly by state, but the comapny names are in the order they fall in the xml. I am sure the solution is simple, but I am missing it. Any help would be appreciated.


7:50 pm on Jul 8, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member

Maybe this [webmasterworld.com] may shed some light?

According to this [xml.com], I think your technique should work.

<xsl:sort select=companyname"/>

I spy, with my little eye, a typo...

5:12 am on Jul 9, 2007 (gmt 0)

WebmasterWorld Senior Member 5+ Year Member

From memory I think the sort is tied closely to the for-each, that is it sorts the RAW for-each set, so you may need to do.

for-each by state
<xsl:sort select="state"/>
for-each by company
<xsl:sort select="companyname"/>

Is it possible to specify multiple selects in one sort? This may be the way to go if nested loops not appropriate.

5:31 am on Jul 9, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member


I think what you're describing is multiple templates in the XSLT. That's the one trick I have not tried yet, but probably will when I get time.

cmarshall, OOPS! I was tired.

Anyway, what complicates the problem is that the XML also has the states listed. In <companyname>, is the name of the state and in <state> is the abbreviation, and the <state> has an option, either 1 or 2. The XSL contains two <if> statements, to the effect:
<xsl:if test="state[@option = '2']"> it makes the <companyname>, hence the state's name, a bookmark on the output.
<xsl:if test="state[@option = '1']"> it makes the <companyname> a link. I tried using a <choose> for this, but the results were the same.

I think there ought to be a <sort> tag with a "then" function, kind of like:
<xsl:sort test="state 'then' companyname"/> (or some symbol for 'then', say an 'x' or '+'. But that would make it too easy :)

I'll keep trying and let all of you know if I get it to work. Thanks for your help.


I should add that the problem boils down to this:
If a company whose name begins with an "L" is located in Nevada (NV), then the output looks like this when I add the sort by companyname:
Company L in NV
Company M in NV
Company S in NV
and so on.

The problem is to get the state's name first regardless of the company names. Make sense?

[edited by: Marshall at 5:49 am (utc) on July 9, 2007]

6:22 am on Jul 9, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member

Found the solution!

I added a tag to the XML <statename></statename> and moved the name of the state to that tag. I deleted all text from the <companyname> tag where the state name was. In the XSL, instead of having it <xsl:value-of select="title"/> under the first <if> statement, it now has <xsl:value-of select="statename"/>. Since the <companyname> tag is blank, it will always come first.

Thanks for all your help. Hope this can help someone else.



Featured Threads

My Threads

Hot Threads This Week

Hot Threads This Month