xslt条件和十进制值

时间:2018-02-16 09:07:12

标签: xml xslt

我想比较使用xsl的两个软件版本,例如1.13和1.4,我希望1.13大于1.4。

但是,以下xslt条件将失败。

<xsl:if test="1.13 >= 1.4">

相反,我选择了一个approacah,我使用substring-after()删除整数部分,以便在比较中只使用余数(假设现在整数部分相同)。

<xsl:if test="substring-after(1.13, ".") >= substring-after(1.4, ".")">

(实际上我必须这样写)

<xsl:if test="substring-after(1.13, &quot;.&quot;) >= substring-after(1.4, &quot;.&quot;)">

适用于值1.13和1.4。但是,当我比较值1.10和1.4时,比较失败。

有没有更好的方法进行比较?

2 个答案:

答案 0 :(得分:2)

您可以尝试将版本转换为字符串或整数,然后执行比较。例如。版本1.13将转换为0113,版本1.4将转换为0104,然后0113将与0104进行比较。

XSLT下面使用XSLT 1.0来执行单个.分隔符的比较。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" />
    <xsl:strip-space elements="*" />

    <xsl:template match="Versions">
        <xsl:variable name="oldVersion">
            <xsl:call-template name="convert-ver-to-string">
                <xsl:with-param name="ver" select="OldVersion"/>
            </xsl:call-template>
        </xsl:variable>
        <xsl:variable name="newVersion">
            <xsl:call-template name="convert-ver-to-string">
                <xsl:with-param name="ver" select="NewVersion"/>
            </xsl:call-template>
        </xsl:variable>
        <xsl:choose>
            <xsl:when test="$newVersion &gt; $oldVersion">
                <Out>New greater than Old</Out>
            </xsl:when>
            <xsl:otherwise>
                <Out>Old greater than New</Out>
            </xsl:otherwise>
        </xsl:choose> 
    </xsl:template>

    <xsl:template name="convert-ver-to-string">
        <xsl:param name="ver" />
        <xsl:variable name="updVer">
            <xsl:choose>
                <xsl:when test="contains($ver, '.')">
                    <xsl:value-of select="$ver" />
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="concat($ver, '.0')" />
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <xsl:value-of select="format-number(substring-before($updVer, '.'), '00')" />
        <xsl:value-of select="format-number(substring-after($updVer, '.'), '00')" />
    </xsl:template>
</xsl:stylesheet>

示例输入XML

<Versions>
    <OldVersion>1.3</OldVersion>
    <NewVersion>1.12</NewVersion>
</Versions>

输出

<Out>New greater than Old</Out>

答案 1 :(得分:2)

这取决于您使用的XSLT处理器和版本。有了Saxon,你可以做到

  <xsl:template match="/" name="main">
     <out>
       <xsl:value-of select="compare('1.13', '1.4', 'http://saxon.sf.net/collation?alphanumeric=yes')"/>
     </out>
  </xsl:template>

返回1,表示第一个参数被认为大于第二个参数。你也可以写

<xsl:if test="'1.13' < '1.4'" 
        default-collation="http://saxon.sf.net/collation?alphanumeric=yes"/>

如果您不想依赖依赖于处理器的归类URI,那么在XSLT 3.0中您可以使用fn:sort()函数,它允许您提供一个函数来计算您自己的排序键,在这种情况下可能是tokenize($x, '\.')!xs:integer(.)

使用早期的XSLT版本并且没有依赖于处理器的功能,请使用xsl:sort,使用substring-before和substring-after计算多个排序键。