假设我有以下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允许我通过添加到已经存在的变量中来动态替换变量值,我就可以做到这一点,但即使这样也会很混乱。我想有一种简单的方法让我错过了?
我只想要XSLT1.0的答案。
谢谢!
<TEST>
<xsl:value-of select="sum((A | B | C)[number(.) = .])"/>
</TEST>
也就是说,求元素A、B、C的子集的和,这些元素的内容可以用作数字。
请注意,number('')
产生NaN
,而(NaN = NaN)
为false,因此这将不包括没有文本内容的元素。
我们测试数字,如中所述https://stackoverflow.com/a/3854389/423105
LarsH答案的一个小变化:
sum((A|B|C)[number(.) = number(.)])
谓词中的表达式在XPath2.0中不会导致任何类型错误,因为=
的两个参数都属于同一类型xs:double。
还有:
对于XSLT1.0:
sum((A|B|C)[string(number())!='NaN'])
对于XSLT2.0:
sum((A,B,C)[string(number())!='NaN'])
出于兴趣,这里还有一个。它适用于XSLT1.0和2.0
sum((A|B|C)[number()>-99999999])
在上面的例子中,将-99999999替换为比可能值的下限少一个。这是因为NaN>任何东西总是返回false。这可能是迄今为止最有效的解决方案,但可能会被视为有点丑陋。
例如,如果你知道a、B或C都不是负值,你可以输入:
sum((A|B|C)[number()>0])
它看起来更干净了一点,而且仍然可读。
<xsl:value-of select="sum(/root/*[self::A or self::B or self::C][.!=''])"/>
这将在"根"元素下添加A、B和C中的值,只要该值不为空。