Xml 在xslt中添加两个有时可能为空的值

Xml 在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

我想使用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是否为空,但假设我无法检查它。我怎样才能解决这个问题

我想做的是,如果“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')就更容易了