Xml 在xslt中添加两个有时可能为空的值
我想使用xslt将xml中的值添加到另一个xml中。我使用的是xml版本1Xml 在xslt中添加两个有时可能为空的值,xml,xslt,xslt-1.0,Xml,Xslt,Xslt 1.0,我想使用xslt将xml中的值添加到另一个xml中。我使用的是xml版本1 <xsl:value-of select="number(/fields/field[@name='value1'])+number(/fields/field[@name='value2'])"/> 如果value1或value2有时为空并生成和NaN,我该怎么做 我知道我可以使用if和when来查看value1或value2是否为空,但假设我无法检查它。我怎样才能解决这个问题 我想做的是,如果“nu
<xsl:value-of select="number(/fields/field[@name='value1'])+number(/fields/field[@name='value2'])"/>
如果value1或value2有时为空并生成和NaN,我该怎么做
我知道我可以使用if和when来查看value1或value2是否为空,但假设我无法检查它。我怎样才能解决这个问题
我想做的是,如果“number(/fields/field[@name='value2'])会产生一个NaN,那么它应该是数字0,那么它就会工作
致意
Joe您可以尝试xpath
布尔值(数字(//number1))
如果值是数字,则返回true。
您可以创建一个存储值转换器或0(如果为NAN)的变量,然后求和(sotty表示我的英语)
如果“number(/fields/field[@name='value2'])将生成一个NaN值,那么它
应该是数字0
您可以尝试以下方法:
<xsl:decimal-format name="coerce" NaN="0" />
...
<xsl:variable name="a" select="format-number(/fields/field[@name='value1'], '#', 'coerce')"/>
<xsl:variable name="b" select="format-number(/fields/field[@name='value2'], '#', 'coerce')"/>
...
<xsl:value-of select="$a + $b"/>
...
...
注意:示例中使用的格式假定为整数输入。@michael.hor257k已经给出了正确的解决方案-请接受他的答案。这只是对该方法的一个说明 如您所见,使用
格式编号
与使用常见的xsl:choose
来确定字段
的内容是否为数字具有相同的效果(似乎您明确决定不使用xsl:choose
)
输入XML
<?xml version="1.0" encoding="utf-8"?>
<fields>
<pair>
<field name="value1">2</field>
<field name="value2">3</field>
</pair>
<pair>
<!--number as strings-->
<field name="value1">"2"</field>
<field name="value2">"3"</field>
</pair>
<pair>
<!--empty-->
<field name="value1"/>
<field name="value2"/>
</pair>
</fields>
2.
3.
"2"
"3"
样式表
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/fields">
<xsl:for-each select="pair">
<xsl:variable name="summands">
<xsl:for-each select="field">
<field>
<xsl:choose>
<xsl:when test="number(.) != .">0</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</field>
</xsl:for-each>
</xsl:variable>
<result-a>
<xsl:value-of select="sum($summands/field)"/>
</result-a>
</xsl:for-each>
<xsl:apply-templates select="//pair" mode="b"/>
</xsl:template>
<xsl:decimal-format name="coerce" NaN="0" />
<xsl:template match="pair" mode="b">
<xsl:variable name="a" select="format-number(field[1], '#', 'coerce')"/>
<xsl:variable name="b" select="format-number(field[2], '#', 'coerce')"/>
<result-b>
<xsl:value-of select="$a + $b"/>
</result-b>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<result-a>5</result-a>
<result-a>0</result-a>
<result-a>0</result-a>
<result-b>5</result-b>
<result-b>0</result-b>
<result-b>0</result-b>
0
输出
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/fields">
<xsl:for-each select="pair">
<xsl:variable name="summands">
<xsl:for-each select="field">
<field>
<xsl:choose>
<xsl:when test="number(.) != .">0</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</field>
</xsl:for-each>
</xsl:variable>
<result-a>
<xsl:value-of select="sum($summands/field)"/>
</result-a>
</xsl:for-each>
<xsl:apply-templates select="//pair" mode="b"/>
</xsl:template>
<xsl:decimal-format name="coerce" NaN="0" />
<xsl:template match="pair" mode="b">
<xsl:variable name="a" select="format-number(field[1], '#', 'coerce')"/>
<xsl:variable name="b" select="format-number(field[2], '#', 'coerce')"/>
<result-b>
<xsl:value-of select="$a + $b"/>
</result-b>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<result-a>5</result-a>
<result-a>0</result-a>
<result-a>0</result-a>
<result-b>5</result-b>
<result-b>0</result-b>
<result-b>0</result-b>
5.
0
0
5.
0
0
我发现这种方法适用于特殊情况,即您确定每个节点都将包含一个有效的数字,或者节点将丢失
<xsl:value-of select="sum(/fields/field[@name='value1'] | /fields/field[@name='value2'])"/>
这将通过合并两个字段来创建节点集,然后对节点集中的节点求和。如果某个节点丢失,它将从节点集中被忽略,并且不会导致NaN
。如果缺少所有节点,它将返回0
限制是存在,但空节点会导致
NaN
,包含文本的节点也会如此。为什么您不能“检查”?我自己的解决方案是翻译(数字(/fields/field[@name='value1']),'NaN','',以备将来参考。嗯,如果value1=5和value2为空,我想您会看到这两种方法之间的差异。如果其中一种为空,则没有差异,如果我没有弄错的话。结果a为0,结果b为5。这不是你得到的吗?啊,你是对的。我想我误解了OP的意图。当前,如果两个字段中的一个为空,则整个总和为0,而不是仅输出另一个字段的值。我将编辑我的帖子。只需使用translate(value1,'NaN','0')就更容易了