【问题标题】:removing/adding duplicates values from name value pair in XSLT从 XSLT 中的名称值对中删除/添加重复值
【发布时间】:2015-01-21 11:59:00
【问题描述】:

我有下面的xml

   <pair>
            <name>ABC</name>
            <value>10</value>
    </pair>
    <pair>
            <name>ABC</name>
            <value>50</value>
    </pair>
    <pair>
            <name>XYZ</name>
            <value>30</value>
    </pair>

应该转换成

<pair>
        <name>ABC</name>
        <value>60</value>
</pair>
<pair>
        <name>XYZ</name>
        <value>30</value>
</pair>

即名称值对中的名称是否相同。应在输出 xml 中添加针对相同名称的值。有人可以帮忙吗?

【问题讨论】:

  • 这是一个分组问题 - 进行搜索,这是这里最常被问到的问题之一。请注意,XSLT 1.0 或 2.0 的答案是不同的。

标签: xml xslt basicnamevaluepair


【解决方案1】:

XML:

<parent>
    <pair>
        <name>ABC</name>
        <value>10</value>
    </pair>
    <pair>
        <name>ABC</name>
        <value>50</value>
    </pair>
    <pair>
        <name>XYZ</name>
        <value>30</value>
    </pair>
</parent>

XSLT:

<xsl:template match="/">
        <parent>
            <xsl:for-each select="//parent/pair[not(name=preceding::pair/name)]">
                <xsl:variable name="curName" select="name" />
                <pair>
                <name>
                <xsl:value-of select="name"/>
                </name>
                <value>
                <xsl:value-of select="sum(/parent/pair[name = $curName]/value)"/>
                </value>
                </pair>
            </xsl:for-each>
        </parent>
</xsl:template>

或者:

<xsl:key name="pair-by-name" match="parent/pair" use="name" />
<xsl:template match="/">
    <parent>
        <xsl:for-each select="parent/pair[count(. | key('pair-by-name', name)[1]) = 1]">
             <xsl:sort select="name" />
            <pair>
            <name>
            <xsl:value-of select="name"/>
            </name>
            <value>
            <xsl:value-of select="sum(key('pair-by-name', name)/value)"/>
            </value>
            </pair>
        </xsl:for-each>
    </parent>
</xsl:template>

上面的代码应该可以工作。

【讨论】:

【解决方案2】:

假设您可以使用 XSLT 2.0 和像 Saxon 9 这样的 XSLT 2.0 处理器

<xsl:template match="/*">
  <xsl:copy>
    <xsl:for-each-group select="//pair" group-by="name">
      <xsl:copy>
        <xsl:copy-of select="name"/>
        <value><xsl:value-of select="sum(current-group()/value)"/></value>
      </xsl:copy>
    </xsl:for-each-group>
  </xsl:copy>
</xsl:template>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-06
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多