Sorting alphabetically & numerically


A

A.T.

Am trying to sort the following file with the <xsl:sort> function, but
can't get it to work properly. Would like the id column sorted
according both alphabetically & numerically. (e.g. A-01, A-02, B-02).
Currently the output, is a table display.

XML DOCUMENT
<root>
<version>
<id>A-01</id>
<!-- other elements -removed for ease of reading-->
</version>
<version>
<id>B-02</id>
</version>
<version>
<id>A-02</id>
</version>
</root>

STYLESHEET
<xsl:template match="version">
<xsl:for-each select="version">
<xsl:sort select="id" data-type="text"
order="ascending"></xsl:sort>
</xsl:for-each>
</xsl:template>
 
Ad

Advertisements

M

Martin Honnen

A.T. said:
Am trying to sort the following file with the <xsl:sort> function, but
can't get it to work properly. Would like the id column sorted
according both alphabetically & numerically. (e.g. A-01, A-02, B-02).
Currently the output, is a table display.

XML DOCUMENT
<root>
<version>
<id>A-01</id>
<!-- other elements -removed for ease of reading-->
</version>
<version>
<id>B-02</id>
</version>
<version>
<id>A-02</id>
</version>
</root>

I think the following stylesheet does what you want:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

<xsl:eek:utput method="xml" encoding="UTF-8" />

<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>

<xsl:template match="root">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:apply-templates select="version">
<xsl:sort data-type="text" order="ascending"
select="id" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

As long as you have the id format
x-dd
where x is a letter and d a digit the text comparison should yield the
correct result.
 
A

A.T.

As long as you have the id format
x-dd
where x is a letter and d a digit the text comparison should yield the >correct result.

How do you do the same sort with an id in the format x-dddd?
 
Ad

Advertisements

R

Richard Light

A.T. said:
How do you do the same sort with an id in the format x-dddd?

In the same way. If your numbers are left-padded with zeros, a text
sort will give you the expected result. Problems only arise where the
numbers within an element are _not_ left-padded.

If that were the case, you could split the element into its component
parts, and sort the numerical part as a number:

...
<xsl:apply-templates select="version">
<xsl:sort data-type="text" order="ascending"
select="substring-before(id, '-')" />
<xsl:sort data-type="number" order="ascending"
select="substring-after(id, '-')" />
</xsl:apply-templates>
...

(This only works with simple, consistent formats like the one you have
described: if you have an arbitrary mix of "text" and "number"
components in your sort strings you can't sort the numerical components
according to their integer value.)

Richard Light
 

Top