RE: [xsl] parsing version number strings

Subject: RE: [xsl] parsing version number strings
From: <Jarno.Elovirta@xxxxxxxxx>
Date: Wed, 20 Oct 2004 10:04:06 +0300
Hi,

> Has anyone out there come up with a method to parse an
> arbitrary version
> number string in an XSLT for numeric comparison?
>
> For example, I'm parsing some Doxygen output and I need to
> apply different
> templates based on which version of Doxygen produced the output. For
> example, I have something that needs to be applied only to
> versions 1.3.4
> and older.
>
> The version of Doxygen is stored in an attribute of the root <doxygen>
> element: <doxygen version="1.3.4">
>
> Here is a sequence of increasingly newer version numbers that
> illustrates
> some of the complexities of parsing this string:
>
> 1.2.9
> 1.2.10
> 1.2.10.1
> 1.3
> 1.3.1
> 1.3.2
> 1.3.2.1
>
> There doesn't seem to be an XPath function that gives me the
> position of a
> character within a string, which kind of hamstrings me, as
> far as I can
> tell.
>
> Anyone solved this problem before?

How about

  <xsl:template name="compare">
    <xsl:param name="v1"/>
    <xsl:param name="v2"/>
    <xsl:variable name="n1">
      <xsl:choose>
        <xsl:when test="contains($v1, '.')">
          <xsl:value-of select="substring-before($v1, '.')"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$v1"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:variable name="n2">
      <xsl:choose>
        <xsl:when test="contains($v2, '.')">
          <xsl:value-of select="substring-before($v2, '.')"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$v2"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="string(number($n1)) = 'NaN' and string(number($n2)) =
'NaN'">0</xsl:when>
      <xsl:when test="string(number($n1)) = 'NaN'">-1</xsl:when>
      <xsl:when test="string(number($n2)) = 'NaN'">1</xsl:when>
      <xsl:when test="number($n1) = number($n2)">
        <xsl:call-template name="compare">
          <xsl:with-param name="v1" select="substring-after($v1, '.')"/>
          <xsl:with-param name="v2" select="substring-after($v2, '.')"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:when test="$n1 &lt; $n2">-1</xsl:when>
      <xsl:when test="$n1 &gt; $n2">1</xsl:when>
    </xsl:choose>
  </xsl:template>

which will return -1 if $v1 is less than $v2, 0 is they're equal, and 1 if $v1
is greater than $v2. Was that what you were after?

Cheers,

Jarno - Nick Rafferty: Live Mix

Current Thread