XSLT sum 改为串联或相加 [英] XSLT sum is concatenated instead or summed

查看:25
本文介绍了XSLT sum 改为串联或相加的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一些 XSLT 代码的片段.

它输出的是连接而不是求和的结果.例如,它将找到以下匹配项:100200 并将输出 12002400.这是 100 * 12200 * 12 连接起来的.我需要 XMLField1 中的输出为 3600.

有人能指出我正确的方向并帮助解释我们做错了什么吗?我不是 XSLT 专家.

<xsl:template match="Root"><XMLField1><xsl:应用模板select="Row[contains(BenefitType, 'MyBenefit')]"/></XMLField1><xsl:template match="Row[contains(BenefitType, 'MyBenefit')]"><xsl:value-of select="sum(BenefitList/Premium) * 12"/></xsl:模板>

我正在寻找一个 XSLT 1.0 兼容的解决方案.

解决方案

您的第二个模板正在单独执行计算,但您并未将其用于任何用途.如果您只想要包含 MyBenefit 的行中所有 Premium 节点的总和,则 不需要第二个模板:

<XMLField1><xsl:value-ofselect="sum(Row[contains(BenefitType, 'MyBenefit')]/BenefitList/Premium) * 12"/></XMLField1></xsl:模板>

这将产生:

3600

更新:

您没有发布源 XML.我假设它有一个类似于这样的结构:

<行><BenefitType>MyBenefit</BenefitType><福利清单><Premium>100</Premium></福利清单></行><行><BenefitType>MyBenefit, OtherBenefit</BenefitType><福利清单><Premium>100</Premium></福利清单></行><行><BenefitType>OtherBenefit</BenefitType><福利清单><Premium>1000</Premium></福利清单></行><行><BenefitType>OtherBenefit</BenefitType><福利清单><Premium>1000</Premium></福利清单></行><行><BenefitType>MyBenefitSpecial</BenefitType><福利清单><Premium>100</Premium></福利清单></行></Root>

由于您使用的是 contains(),因此请务必注意它将匹配 contain MyBenefit(包括 MyBenefit, 其他福利, MyBenefitSpecial)

这是一个在线工作示例:http://xsltransform.net/bFukv8t/1<小时>

如果您创建第二个模板是因为您希望每一行的单独结果,那么您只需在模板中添加一些内容.也许是一个标签:

<小计><xsl:value-of select="sum(BenefitList/Premium) * 12"/></小计></xsl:模板>

这将产生我上面提供的样本输入:

<小计>1200</小计><小计>1200</小计><小计>1200</小计></XMLField1>

如果你改变你的other模板,你可以同时拥有总和和这个结果:

<XMLField1><total><xsl:value-ofselect="sum(Row[contains(BenefitType, 'MyBenefit')]/BenefitList/Premium) * 12"/></总计><xsl:apply-templates select="Row[contains(BenefitType, 'MyBenefit')]"/></XMLField1></xsl:模板>

现在您将获得:

<total>3600</total><小计>1200</小计><小计>1200</小计><小计>1200</小计></XMLField1>

希望您可以将这些示例应用到您的实际案例中,并获得您期望的结果.

Here is a snippet of some XSLT code.

It is outputting the results concatenated instead of summed. For example it will find the following matches: 100 and 200 and will output 12002400. Which is 100 * 12 and 200 * 12 concatenated. I need the output in XMLField1 to be 3600.

Can someone point me in the right direction and help explain what we are doing wrong? I'm not an XSLT expert.

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="Root">
    <XMLField1>
      <xsl:apply-templates
        select="Row[contains(BenefitType, 'MyBenefit')]" />
    </XMLField1>


  <xsl:template match="Row[contains(BenefitType, 'MyBenefit')]">
    <xsl:value-of select="sum(BenefitList/Premium) * 12" />
  </xsl:template>

I am looking for an XSLT 1.0 compliant solution.

解决方案

Your second template is performing calculations separately, but your aren't using that for anything. You don't need the second template if you just want the sum of all Premium nodes in rows that contain MyBenefit:

<xsl:template match="Root">
    <XMLField1>
        <xsl:value-of
            select="sum(Row[contains(BenefitType, 'MyBenefit')]/BenefitList/Premium) * 12" />
    </XMLField1>
</xsl:template>

This would produce:

<XMLField1>3600</XMLField1>

UPDATE:

You didn't post your source XML. I'm assuming it has a structure that resembles this:

<Root>
    <Row>
        <BenefitType>MyBenefit</BenefitType>
        <BenefitList>
            <Premium>100</Premium>
        </BenefitList>
    </Row>
    <Row>
        <BenefitType>MyBenefit, OtherBenefit</BenefitType>
        <BenefitList>
            <Premium>100</Premium>
        </BenefitList>
    </Row>
    <Row>
        <BenefitType>OtherBenefit</BenefitType>
        <BenefitList>
            <Premium>1000</Premium>
        </BenefitList>
    </Row>
    <Row>
        <BenefitType>OtherBenefit</BenefitType>
        <BenefitList>
            <Premium>1000</Premium>
        </BenefitList>
    </Row>
    <Row>
        <BenefitType>MyBenefitSpecial</BenefitType>
        <BenefitList>
            <Premium>100</Premium>
        </BenefitList>
    </Row>
</Root>

Since you are using contains() it's important to be aware that it will match strings that contain MyBenefit (including MyBenefit, OtherBenefit, MyBenefitSpecial)

Here is an online working example: http://xsltransform.net/bFukv8t/1


If you created a second template because you wanted separate results for each row, then you just have to add something in the template. A tag perhaps:

<xsl:template match="Row[contains(BenefitType, 'MyBenefit')]">
    <subtotal>
        <xsl:value-of select="sum(BenefitList/Premium) * 12" />
    </subtotal>
</xsl:template>

which would produce for the sample input I provided above:

<XMLField1>
    <subtotal>1200</subtotal>
    <subtotal>1200</subtotal>
    <subtotal>1200</subtotal>
</XMLField1>

You can have both the sum and this result if you change your other template:

<xsl:template match="Root">
    <XMLField1>
        <total><xsl:value-of
            select="sum(Row[contains(BenefitType, 'MyBenefit')]/BenefitList/Premium) * 12" />
        </total>
        <xsl:apply-templates select="Row[contains(BenefitType, 'MyBenefit')]"/>
    </XMLField1>
</xsl:template>

Now you will get:

<XMLField1>
   <total>3600</total>
   <subtotal>1200</subtotal>
   <subtotal>1200</subtotal>
   <subtotal>1200</subtotal>
</XMLField1>

Hopefully you can apply these examples to your real case scenario and obtain the results you are expecting.

这篇关于XSLT sum 改为串联或相加的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆