[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Collation for dotted decimal?

Subject: Re: Collation for dotted decimal?
From: cknell@xxxxxxxxxx
Date: Tue, 07 Feb 2006 11:06:20 -0500
dotted decimal format
Please help me understand this. I'll break the inquiry into several questions so I can keep things clear in my mind.

I think I'll start at the end and work my way back. There is a lot going on here:

<xsl:sort select="string-join(for $i in tokenize(.,'\.') return format-number(number($i),$vPattern),'.')"/>

that is unfamiliar to me.

Let's assume an xml file like this:

<xes>
 <x>1.2.3.9</x>
 <x>1.2.3.7</x>
 <x>1.2.3.10</x>
 <x>1.2.3.8</x>
 <x>1.2.3.6</x>
</xes>

Ordinary sorting of these elements as performed by <xsl:sort select="." />
would yield this:

<xes>
 <x>1.2.3.10</x>
 <x>1.2.3.6</x>
 <x>1.2.3.7</x>
 <x>1.2.3.8</x>
 <x>1.2.3.9</x>
</xes>

when what is wanted is this:

<xes>
 <x>1.2.3.6</x>
 <x>1.2.3.7</x>
 <x>1.2.3.8</x>
 <x>1.2.3.9</x>
 <x>1.2.3.10</x>
</xes>


First,


format-number(number($i),$vPattern),'.')

the variable $vPattern is a string that represents a kind of "template" to use in formatting the number returned by the "number()" function. The number represented by "$i" is produced by applying the "tokenize()" function to each <x>.

The "tokenize()" function has two arguments. The first is a dot (.) that represents each instance of <x>. The second argument is a string representing the character dot that separates the parts of the dotted-decimal string that is the text node of each <x> element.

The backslash in '\.' is an escape character, forcing the function to recognize the dot as a literal character rather than a regular expression metacharacter.

What "tokenize()" produces is a "sequence" by taking the first argument and splitting it into substrings at the points in the first argument where the second argument appears. Thus, "tokenize('1.2.3.10','\.')" will yield a sequence ("1", "2", "3", "10").

Now, this: "for $i in tokenize(.,'\.') return format-number(number($i),$vPattern),'.')" must be a function, and this is where I'm having my first problem in understanding this solution.

In order to get the output I want, it seems that between any two dots in the orginal dotted-decimal format, you would have to have the same number of digits. In order to get this it would be necessary to "left pad" each member of the sequence with zeros. Thus, "1.2.3.9" would become "1.2.3.09", or even "01.02.03.09" so that when compared to "01.02.03.10", it would come first in sorted order.

So this function must do this padding, is that correct?

Assuming that it is correct, the next question goes to the variable "$vPattern" which is produced by this:

<xsl:for-each select="*">
   <xsl:sort select="string-length(.)"/>
   <xsl:if test="position() = 1">
       <xsl:sequence select="translate(.,'123456789.', '000000000')"/>
    </xsl:if>
</xsl:for-each>

What I understand this to do is to select the shortest dotted-decimal in the document, and then create a sequence by replacing any non-zero digit or dot with a zero. And that's where I'm certain I'm lost. I can't picture the "template" it would produce and how applying that template would produce a left-padding of zeros.

--
Charles Knell
cknell@xxxxxxxxxx - email



-----Original Message-----
From:     Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Sent:     Tue, 7 Feb 2006 11:53:12 +1100
To:       xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject:  Re:  Collation for dotted decimal?

Couldn't resist to make David's solution general (not dependent on a
maximum digits in a number estimate) :o)    :


<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes"/> <xsl:template match="x"> <xsl:variable name="vPattern"> <xsl:for-each select="*"> <xsl:sort select="string-length(.)"/> <xsl:if test="position() = 1"> <xsl:sequence select="translate(.,'123456789.', '000000000')"/> </xsl:if> </xsl:for-each> </xsl:variable> <x> <xsl:perform-sort select="*"> <xsl:sort select="string-join(for $i in tokenize(.,'\.') return format-number(number($i),$vPattern),'.')"/> </xsl:perform-sort> </x> </xsl:template> </xsl:stylesheet>

--
Cheers,
Dimitre Novatchev
---------------------------------------
The significant problems we have cannot be solved at the same level of
thinking with which we created them.

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.