【问题标题】:what is correct way to test for xs:decimal in XSL?在 XSL 中测试 xs:decimal 的正确方法是什么?
【发布时间】:2010-09-29 18:21:39
【问题描述】:

我正在尝试根据传入的数据显示不同的信息。如果是整数,我只想显示数字,如果是小数,我想使用 0.00# 模式。是的,我知道,有点混淆,但这是开发规范。 :>

我在这个特定部分有以下 XSL,但我看不到 xsl:when 的错误消息

"预期的表达式结束,找到 '浇注料'。数字(SAVG)->可铸造

<xsl:choose>
    <xsl:when test="number(SAVG) > 0">
        <xsl:choose>
            <xsl:when test="number(SAVG) castable as xs:decimal">
                <xsl:value-of select="format-number(SAVG, '###,###,##0.00#')"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="format-number(SAVG, '###,###,##0.###')"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:when>
    <xsl:when test="number(SAVG) = 0">
        <xsl:text disable-output-escaping="yes">&amp;lt;</xsl:text>1
    </xsl:when>
    <xsl:otherwise>N/A</xsl:otherwise>
</xsl:choose>

我尝试寻找/寻找答案,我尝试过“实例”,我尝试过使用 xsl:if 等,但我似乎无法让它工作。任何帮助将不胜感激。

谢谢。

来自 cmets:

是的,我们使用的是 1.0。对不起我是 刚接触 XSL 处理,我该怎么做 粘合您的 XSL 和输入以生成 html?

【问题讨论】:

  • 这是 XSLT 2.0。如果您使用 XSLT 1.0 处理器运行它,请这样说。
  • 好问题 (+1)。有关简短而完整的 XSLT 2.0 解决方案,请参阅我的答案。
  • 我已在我的答案中添加了 XSLT 1.0 解决方案。

标签: xslt


【解决方案1】:

我。 XSLT 1.0

XSLT 1.0 使用的 XPath 1.0 数据模型中没有 xs:integer 和 xs:decimal。

这是你可以使用的代码 sn-p

    <xsl:choose> 
        <xsl:when test="not(floor(SAVG) = SAVG)"> 
            <xsl:value-of select="format-number(SAVG, '###,###,##0.00#')"/> 
        </xsl:when> 
        <xsl:otherwise> <!-- Integer value -->
            <xsl:value-of select="SAVG"/> 
        </xsl:otherwise> 
    </xsl:choose> 

注意:要测试数值是否为整数,我们使用以下测试:

 floor($someNum) = $someNum

这是一种方法:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output method="text"/>

 <xsl:template match="/">
  <xsl:sequence select=
   "for $num in (3, 3.14)
     return
       if($num instance of xs:integer)
         then ($num, ' is xs:integer', '&#xA;')
         else if($num instance of xs:decimal)
           then ($num, ' is xs:decimal', '&#xA;')
           else ($num, ' is something else', '&#xA;')
   "/>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于任何 XML 文档(未使用)时,会产生所需的正确结果

3  is xs:integer 
3.14  is xs:decimal 

或者,按照您的示例使用 format-number() 函数

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output method="text"/>

 <xsl:template match="/">
  <xsl:sequence select=
   "for $num in (3, 3.14)
     return
       if($num instance of xs:integer)
         then (format-number($num, '###,###,##0.###'), '&#xA;')
         else if($num instance of xs:decimal)
           then (format-number($num, '###,###,##0.00#'), '&#xA;')
           else ()
   "/>
 </xsl:template>
</xsl:stylesheet>

产生

3 
3.14 

【讨论】:

  • @Dimitre:+1 我更喜欢这个 XSLT 2.0。
  • @Dimitre:OP 知道他/她现在需要 XSLT 1.0
  • @Alejandro:我还添加了一个 XSLT 1.0 解决方案。
  • @Dimitre:如果可以的话,我会 +1 fn:floor 数字测试。
  • @themanwhosoldtheworld,如果您可以使用 XSLT 2.0 (XPath 2.0),在您的情况下:100.00 instance of xs:integer 的计算结果为 false(),这正是您所需要的。整数的经典数学定义可以使用:100.00 castable as xs:integer——计算结果为true()。无论如何,XPath 1.0 中真正的数字类型始终是double——XPath 1.0 中没有xs:decimalxs:integer 类型。这意味着任何这样的表达式只能帮助我们确定给定的双精度值是否恰好是整数值。
【解决方案2】:

这个 XSLT 1.0 样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="test">
        <xsl:choose>
            <!-- Not number or number less than zero -->
            <xsl:when test="0 > SVGA or number(SVGA) != SVGA">
                <xsl:text>N/A</xsl:text>
            </xsl:when>
            <!-- Number zero -->
            <xsl:when test="SVGA = 0">
                <xsl:text>&lt;1</xsl:text>
            </xsl:when>
            <!-- Integer number -->
            <xsl:when test="floor(SVGA) = SVGA">
                <xsl:value-of select="format-number(SVGA,'###,###,##0.###')"/>
            </xsl:when>
            <!-- Double number -->
            <xsl:otherwise>
                <xsl:value-of select="format-number(SVGA,'###,###,##0.00#')"/>
            </xsl:otherwise>
        </xsl:choose>
        <xsl:text>&#xA;</xsl:text>
    </xsl:template>
</xsl:stylesheet>

有了这个输入:

<root>
    <test>
        <SVGA>0</SVGA>
    </test>
    <test>
        <SVGA>12131</SVGA>
    </test>
    <test>
        <SVGA>123.5654</SVGA>
    </test>
    <test>
        <SVGA>-12.1</SVGA>
    </test>
    <test>
        <SVGA>-7528</SVGA>
    </test>
    <test>
        <SVGA>zero</SVGA>
    </test>
</root>

输出:

&lt;1
12,131
123.565
N/A
N/A
N/A

编辑 3:更好的测试顺序(加上 Dimitre 的表达式)、更好的测试用例、更接近提问者的输入样本。

【讨论】:

  • 是的,我们使用的是 1.0。对不起,我是 XSL 处理的新手,我如何粘合您的 XSL 和输入以生成 html?
  • @PHenry:请参阅我对 XSLT 1.0 解决方案的编辑。我不明白你所说的glue (...) to generate the html 是什么意思。请发布输入样本和所需的输出。
  • 重新粘合,哦,对不起,我的意思是我需要用这些线做什么?我认为 XSL 进入了 XSL 文件,而 html 部分进入了 html 文件,但我不确定如何从 html 中引用 xsl。如果这完全是古怪的,我很抱歉,我正在努力学习。
  • @PHenry:我认为您之前已经进行过转换...您应该将您的 xsl:choose 指令替换为一个人的 Dimitre 或者我已经发布(在适当的时候替换,即 .SAVG 在我的)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-12
  • 2017-01-11
  • 1970-01-01
  • 2015-12-13
  • 1970-01-01
  • 2021-03-24
相关资源
最近更新 更多