7

假设我有以下 XML

    <A>100</A>
    <B>200</B>
    <C>300</C>

和以下 XSLT

  <TEST>
    <xsl:value-of select="A + B + C"/>
  </TEST>

它产生以下输出

<TEST>600</TEST>

但是,当其中一个节点为空白时

    <A></A>
    <B>200</B>
    <C>300</C>

我得到以下。

<TEST>NaN</TEST>

我只想添加有效数字的节点。如果 xsl 允许我通过添加到已经存在的变量来动态替换变量值,我可以这样做,但即使这样也会很麻烦。我认为有一种简单的方法我错过了?

我只想要 XSLT 1.0 的答案。

谢谢!

4

4 回答 4

11
  <TEST>
    <xsl:value-of select="sum((A | B | C)[number(.) = .])"/>
  </TEST>

也就是说,将元素 A、B、C 的子集相加,这些元素的内容可以用作数字。

请注意,number('')yieldNaN(NaN = NaN)是 false,因此这将不包括没有文本内容的元素。

我们测试https://stackoverflow.com/a/3854389/423105中讨论的数字

于 2012-09-04T21:04:39.890 回答
5

LarsH 回答的一些变化

sum((A|B|C)[number(.) = number(.)])

谓词中的表达式在 XPath 2.0 中不会导致任何类型错误,因为 的两个参数=属于同一类型——xs:double。

于 2012-09-05T02:03:01.513 回答
3

还有:

对于 XSLT 1.0:

sum((A|B|C)[string(number())!='NaN'])

对于 XSLT 2.0:

sum((A,B,C)[string(number())!='NaN'])

出于兴趣,这是另一个。它适用于 XSLT 1.0 和 2.0

sum((A|B|C)[number()>-99999999])

在上面,将 -99999999 替换为比可能值的下限小一。这是因为 NaN > any-thing 总是返回 false。这可能是迄今为止最有效的解决方案,但它可能看起来有点难看。

例如,如果您知道 A、B 或 C 都不是负值,您可以输入:

sum((A|B|C)[number()>0])

...看起来更干净一些,并且仍然可以安静地阅读。

于 2012-09-05T04:41:50.820 回答
2
<xsl:value-of select="sum(/root/*[self::A or self::B or self::C][.!=''])"/>

只要值不为空,这将在“根”元素下添加来自 A、B 和 C 的值。

于 2012-09-04T19:57:26.427 回答