You are sorting a string as number. It won't sort correctly.
Also, you want to order strings by character order, and the numbers by numerical order. To achieve this you have to separate the terms and order strings and numbers separately. You can do this with two xsl:sort
s:
<xsl:for-each select="item">
<xsl:sort data-type="text" select="substring-before(@name, ' ')"/>
<xsl:sort data-type="number" select="substring-after(@name, ' ')"/>
<item><xsl:value-of select="@name"/></item>
</xsl:for-each>
This will work considering you have one word followed by one number, since substring-before
and substring-after
will return the strings before or after the first space.
UPDATE
You edited your question with new requirements:
- there is one number and it can appear anywhere in the text;
- the text may have spaces anywhere.
You can still use the two xs:sort
expressions. You just have to find a way to extract the numbers and the strings to use them in ordering. If you can use XSLT 2.0 then you can use a regular expression for that. This code removes the digits or the non-digits to obtain the sorting data for each case:
<xsl:for-each select="item">
<xsl:sort data-type="text" select="normalize-space(replace(@name, '\d+',''))"/>
<xsl:sort data-type="number" select="normalize-space(replace(@name, '\D+',''))"/>
<item><xsl:value-of select="@name"/></item>
</xsl:for-each>