XSLT 1.0 累加、求和、乘法

发布于 2024-10-08 17:48:21 字数 567 浏览 0 评论 0原文

我有一组固定的节点:< d>。每个节点的值可以为 1 或 0。 此外,每个节点的权重分别为:1、2、3、4。不使用节点属性。 如何使用 XSLT 1.0 将每个节点的值乘以其权重求和?示例:

<a>0</a>
<b>1</b>
<c>0</c>
<d>1</d>

总和:6

<a>1</a>
<b>1</b>
<c>0</c>
<d>0</d>

总和:3

<a>0</a>
<b>1</b>
<c>1</c>
<d>1</d>

总和:9

I have a small fixed set of nodes: <a>, <b>, <c>, <d>. Each node can have a value of either 1 or 0.
Also, each node has a weight: 1, 2, 3, 4, respectively. Node attributes are not used.
How can I sum the value of each node multiplied by its weight using XSLT 1.0? Example:

<a>0</a>
<b>1</b>
<c>0</c>
<d>1</d>

Sum: 6

<a>1</a>
<b>1</b>
<c>0</c>
<d>0</d>

Sum: 3

<a>0</a>
<b>1</b>
<c>1</c>
<d>1</d>

Sum: 9

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

送你一个梦 2024-10-15 17:48:21

此 XSLT 1.0 转换

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/*">
  <xsl:call-template name="sumWeighted"/>
 </xsl:template>

 <xsl:template name="sumWeighted">
   <xsl:param name="pList" select="*"/>
   <xsl:param name="pIndex" select="1"/>
   <xsl:param name="pAccum" select="0"/>

   <xsl:choose>
    <xsl:when test="$pIndex > count($pList)">
     <xsl:value-of select="$pAccum"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:call-template name="sumWeighted">
        <xsl:with-param name="pList" select="$pList"/>
        <xsl:with-param name="pIndex"
             select="$pIndex+1"/>
        <xsl:with-param name="pAccum"
             select="$pAccum+$pList[$pIndex]*$pIndex"/>
      </xsl:call-template>
    </xsl:otherwise>
   </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

应用于提供的 XML 文档时

<t>
    <a>0</a>
    <b>1</b>
    <c>0</c>
    <d>1</d>
</t>

<t>
    <a>1</a>
    <b>1</b>
    <c>0</c>
    <d>0</d>
</t>

3

<t>
    <a>0</a>
    <b>1</b>
    <c>1</c>
    <d>1</d>
</t>

分别产生所需的结果:

6

9


参考

如果您想使用 XSLT 进行真正复杂的数学计算,请参阅:

http://fxsl.sourceforge.net/articles/xslCalculator/The%20FXSL%20Calculator.html


XPath 2.0 / XSLT 2.0 解决方案:

仅使用这个 XPath 2.0 一行:

   sum(/*/*/(number()*position()))

This XSLT 1.0 transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/*">
  <xsl:call-template name="sumWeighted"/>
 </xsl:template>

 <xsl:template name="sumWeighted">
   <xsl:param name="pList" select="*"/>
   <xsl:param name="pIndex" select="1"/>
   <xsl:param name="pAccum" select="0"/>

   <xsl:choose>
    <xsl:when test="$pIndex > count($pList)">
     <xsl:value-of select="$pAccum"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:call-template name="sumWeighted">
        <xsl:with-param name="pList" select="$pList"/>
        <xsl:with-param name="pIndex"
             select="$pIndex+1"/>
        <xsl:with-param name="pAccum"
             select="$pAccum+$pList[$pIndex]*$pIndex"/>
      </xsl:call-template>
    </xsl:otherwise>
   </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

when applied to the provided XML documents:

<t>
    <a>0</a>
    <b>1</b>
    <c>0</c>
    <d>1</d>
</t>

,

<t>
    <a>1</a>
    <b>1</b>
    <c>0</c>
    <d>0</d>
</t>

and

<t>
    <a>0</a>
    <b>1</b>
    <c>1</c>
    <d>1</d>
</t>

produces the wanted results, respectively:

6

3

9


Reference:

If you want to get your hands dirty with really complicated math calculations using XSLT, see this:

http://fxsl.sourceforge.net/articles/xslCalculator/The%20FXSL%20Calculator.html


XPath 2.0 / XSLT 2.0 Solution:

Use just this XPath 2.0 one-liner:

   sum(/*/*/(number()*position()))
旧话新听 2024-10-15 17:48:21

不太优雅,但这就是我的想法。

<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my"
exclude-result-prefixes="my">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>

<my:node-weight>
    <node name="a" weight="1"/>
    <node name="b" weight="2"/>
    <node name="c" weight="3"/>
    <node name="d" weight="4"/>
</my:node-weight>

<xsl:template match="root">
    <xsl:apply-templates select="*[1]" mode="sum"/>
</xsl:template>

<xsl:template match="*" mode="sum">
    <xsl:param name="sumNumber" select="0"/>
    <xsl:variable name="thisWeight" select="document('')/*/my:node-weight/node[@name = local-name(current())]/@weight"/>
    <xsl:choose>
        <xsl:when test="following-sibling::*">
            <xsl:apply-templates select="following-sibling::*[1]" mode="sum">
                <xsl:with-param name="sumNumber" select="$sumNumber + $thisWeight * number()"/>
            </xsl:apply-templates>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$sumNumber + $thisWeight * number()"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>

当应用于以下格式正确的文档时:

<root>
    <a>0</a>
    <b>1</b>
    <c>0</c>
    <d>1</d>
</root>

结果为 6

<root>
    <a>1</a>
    <b>1</b>
    <c>0</c>
    <d>0</d>
</root>

结果为 3

<root>
    <a>0</a>
    <b>1</b>
    <c>1</c>
    <d>1</d>
</root>

结果为 9

Not really elegant, but that's what came to my mind.

<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my"
exclude-result-prefixes="my">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>

<my:node-weight>
    <node name="a" weight="1"/>
    <node name="b" weight="2"/>
    <node name="c" weight="3"/>
    <node name="d" weight="4"/>
</my:node-weight>

<xsl:template match="root">
    <xsl:apply-templates select="*[1]" mode="sum"/>
</xsl:template>

<xsl:template match="*" mode="sum">
    <xsl:param name="sumNumber" select="0"/>
    <xsl:variable name="thisWeight" select="document('')/*/my:node-weight/node[@name = local-name(current())]/@weight"/>
    <xsl:choose>
        <xsl:when test="following-sibling::*">
            <xsl:apply-templates select="following-sibling::*[1]" mode="sum">
                <xsl:with-param name="sumNumber" select="$sumNumber + $thisWeight * number()"/>
            </xsl:apply-templates>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$sumNumber + $thisWeight * number()"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>

When applied to the following well-formed documents:

<root>
    <a>0</a>
    <b>1</b>
    <c>0</c>
    <d>1</d>
</root>

Result is 6

<root>
    <a>1</a>
    <b>1</b>
    <c>0</c>
    <d>0</d>
</root>

Result is 3

<root>
    <a>0</a>
    <b>1</b>
    <c>1</c>
    <d>1</d>
</root>

Result is 9

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文