?
Solved

xsl comparison of dotted decimal values

Posted on 2014-08-13
6
Medium Priority
?
296 Views
Last Modified: 2014-08-13
I am using xsl (through lxml.etree) to transform some XML.  One of the attributes I need to check is a required minimum version number, e.g. minVers="5.1.7".  I pass the current version number as a parameter to the XSL, so need to check that the passed-in version number is at or later than the minVers value.  As far as I know, the first component of the version number will rise slowly, and the 2nd and 3rd will reset to 0 when the one before them increments, then increment with each minor version.

I can't do a simple "less than" arithmetic comparison, because of the multiple dots.  I can't do a string comparison, because 4.12.4 will come out as earlier than 4.2.9.

I can see two options:

- pass the current version as a dotted value like this, then compare the dotted versions correctly (i.e. component by component).  I think this might be quite a complex comparison, and because of the way the XML is handled, I'll need to do it at least 4 times.

- change the passed-in current version to a single integer - assuming that the minor components won't exceed 99 (the highest I have seen in the past is "24"), you could do this by zero-padding the minor versions to 2 characters and combining them, so 4.7.2 -> 40702, and 6.13.1 -> 61301 (though other methods may exist).  I can do this easily in the calling code.  Then in the XSL, change the value stored in the attribute in the same way and do the simple arithmetic comparison.

So, unless someone comes up with a simple way to compare two dotted-decimal values in XSL, I think I'm looking for a good way to change the attribute value from dotted decimal to a single integer.

(Apparently the, to me, obvious solution of changing the values in the source XML file to be the single-integer version is not acceptable!)
0
Comment
Question by:simon3270
  • 4
  • 2
6 Comments
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 40257943
In XSLT1 you should use your own suggestion:
transform both values to a zero padded predictable form
4.7.2  => 04.07.02 for string comparison
or => 40702 for integer coparisson
0
 
LVL 20

Author Comment

by:simon3270
ID: 40257958
Thanks for the confirmation of my suggestion - it's nice to be right sometimes!

The question is, how do I do that transformation?

I currently have the attribute value in a variable, say $min_version.  How do I take that and format it into either of the above formats?
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 40258000
I would use a named template like this
    <xsl:template name="normalize-version-string">
        <xsl:param name="vers"/>
        <xsl:value-of select="format-number(substring-before($vers, '.'), '00')"/>
         <xsl:value-of select="format-number(substring-before(substring-after($vers, '.'), '.'), '00')"/>
        <xsl:value-of select="format-number(substring-after(substring-after($vers, '.'), '.'), '00')"/>
     </xsl:template>
    

Open in new window

0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 60

Accepted Solution

by:
Geert Bormans earned 2000 total points
ID: 40258015
using this test XML
<test minVersion="4.3.5">foo</test>

Open in new window


try this XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    
    <xsl:param name="this-version">4.2.6</xsl:param>
    
    <xsl:variable name="this-version-normalized">
        <xsl:call-template name="normalize-version-string">
            <xsl:with-param name="vers" select="$this-version"></xsl:with-param>
        </xsl:call-template>
    </xsl:variable>
    
    <xsl:template match="test">
        <xsl:variable name="version-ok">
            <xsl:call-template name="valid-version-attribute">
                <xsl:with-param name="version-attribute" select="@minVersion"></xsl:with-param>
            </xsl:call-template>
        </xsl:variable>
         <xsl:if test="$version-ok = 'true'">
            <xsl:text>OK</xsl:text>
        </xsl:if>
    </xsl:template>
    
    <xsl:template name="valid-version-attribute">
        <xsl:param name="version-attribute"/>
        <xsl:variable name="version-attribute-normalized">
            <xsl:call-template name="normalize-version-string">
                <xsl:with-param name="vers" select="$version-attribute"/>
            </xsl:call-template>
        </xsl:variable>
        <xsl:choose>
            <xsl:when test="number($version-attribute-normalized) >= number($this-version-normalized)">
                <xsl:value-of select="true()"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="false()"/>
            </xsl:otherwise>
        </xsl:choose>
        
    </xsl:template>
    
    <xsl:template name="normalize-version-string">
        <xsl:param name="vers"/>
        <xsl:value-of select="format-number(substring-before($vers, '.'), '00')"/>
         <xsl:value-of select="format-number(substring-before(substring-after($vers, '.'), '.'), '00')"/>
        <xsl:value-of select="format-number(substring-after(substring-after($vers, '.'), '.'), '00')"/>
     </xsl:template>
    
</xsl:stylesheet>

Open in new window

0
 
LVL 20

Author Closing Comment

by:simon3270
ID: 40258029
Excellent - thank you!
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 40258087
welcome
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Browsing the questions asked to the Experts of this forum, you will be amazed to see how many times people are headaching about monster regular expressions (regex) to select that specific part of some HTML or XML file they want to extract. The examp…
Many times as a report developer I've been asked to display normalized data such as three rows with values Jack, Joe, and Bob as a single comma-separated string such as 'Jack, Joe, Bob', and vice versa.  Here's how to do it. 
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…
As many of you are aware about Scanpst.exe utility which is owned by Microsoft itself to repair inaccessible or damaged PST files, but the question is do you really think Scanpst.exe is capable to repair all sorts of PST related corruption issues?
Suggested Courses

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question