xsl comparison of dotted decimal values

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!)
LVL 20
simon3270Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Geert BormansInformation ArchitectCommented:
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
simon3270Author Commented:
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
Geert BormansInformation ArchitectCommented:
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
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

Geert BormansInformation ArchitectCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
simon3270Author Commented:
Excellent - thank you!
0
Geert BormansInformation ArchitectCommented:
welcome
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
XML

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.