ich有以下XML:
<item>
<number>1</number>
<value>2</value>
</item>
<item>
<number>2</number>
<value>22</value>
</item>
<item>
<number>1</number>
<value>4</value>
</item>
我想用xslt 1.0将xml转换为:
<item>
<number>1</number>
<value>6</value>
</item>
<item>
<number>2</number>
<value>22</value>
</item>
必须将相同项目编号的值相加,最后我想合并同一项目的元素。可以有n个具有相同编号的多个项目。在这个例子中,数字1的项目在xml中是两次,因此这两个将是一个条目,值(2,4)将被添加到6。
答案 0 :(得分:3)
这是一个非常基本的分组问题。在XSLT 1.0中,使用the Muenchian method进行分组。
以identity transform ...
开头<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
使用item
创建xsl:key匹配number
,按item
对所有number
进行分组...
<xsl:key name="items" match="item" use="number"/>
从所有item
的父级的上下文(以doc
为例)输出元素的副本并将模板应用于第一个item
在组(和任何属性)......
<xsl:template match="doc">
<xsl:copy>
<xsl:apply-templates select="@*|item[count(.|key('items',number)[1])=1]"/>
</xsl:copy>
</xsl:template>
添加与item
匹配的模板并输出其副本。将模板应用于任何属性和number
元素。然后创建一个新的value
元素,其中所有item
的总和与该键匹配...
<xsl:template match="item">
<xsl:copy>
<xsl:apply-templates select="@*|number"/>
<value><xsl:value-of select="sum(key('items',number)/value)"/></value>
</xsl:copy>
</xsl:template>
完整示例......
XML输入(添加了一个根元素doc
以使输入格式正确)
<doc>
<item>
<number>1</number>
<value>2</value>
</item>
<item>
<number>2</number>
<value>22</value>
</item>
<item>
<number>1</number>
<value>4</value>
</item>
</doc>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="items" match="item" use="number"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="doc">
<xsl:copy>
<xsl:apply-templates select="@*|item[count(.|key('items',number)[1])=1]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="item">
<xsl:copy>
<xsl:apply-templates select="@*|number"/>
<value><xsl:value-of select="sum(key('items',number)/value)"/></value>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
XML输出
<doc>
<item>
<number>1</number>
<value>6</value>
</item>
<item>
<number>2</number>
<value>22</value>
</item>
</doc>