Welcome to WebmasterWorld Guest from

Forum Moderators: httpwebwitch

Message Too Old, No Replies

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

Hot Threads This Week

Hot Threads This Month