Based on the following XML, what is the best way to achieve an alphanumeric sort in XSL?
Edit: to clarify, the XML below is just a simple sample the real XML would contain much more variant values.
<colors> <item> <label>Yellow 100</label> </item> <item> <label>Blue 12</label> </item> <item> <label>Orange 3</label> </item> <item> <label>Yellow 10</label> </item> <item> <label>Orange 26</label> </item> <item> <label>Blue 117</label> </item> </colors>
E.g. I want a final outcome in this order:
Blue 12, Blue 117, Orange 3, Orange 26, Yellow 10, Yellow 100
This is ‘effectively‘ what I would want.
<xsl:apply-templates select='colors/item'> <xsl:sort select='label' data-type='text' order='ascending'/><!--1st sort--> <xsl:sort select='label' data-type='number' order='ascending'/><!--2nd sort--> </xsl:apply-templates> <xsl:template match='item'> <xsl:value-of select='label'/> <xsl:if test='position() != last()'>,</xsl:if> </xsl:template>
Splitting the label text into text and number part using
substring-beforeandsubstring-afterwill do in your example (however, this is not a general approach, but you get the idea):This gives the following output:
Update
A more generic way to solve your sorting problem would be to have the
selectattribute of thexls:sortelement contain a string which is sortable according to the sort rules that you expect. E.g. in this string all numbers could be padded with leading 0’s so that lexicgraphically sorting them asdata-type='text'will result in the correct alphanumeric order.If you are using the XSLT engine of .NET you could use a simple extension function in C# to pad numbers with leading 0’s: