如何用XSLT 1.0合并多个top节点并聚合属性值
合并多个XML
<top>节点并聚合<attr>值(XSLT 1.0解决方案) 输入XML结构
<root> <top> <number>999</number> <attr attr-name="Numbervalue"> <value>184</value> </attr> <attr attr-name="Initials"> <value>A.C.</value> </attr> <attr attr-name="Givenname"> <value>Anne</value> </attr> <attr attr-name="Surname"> <value>Bakker</value> </attr> <attr attr-name="Function"> <value>Developer</value> </attr> </top> <top> <number>999</number> <attr attr-name="Numbervalue"> <value>1034</value> </attr> <attr attr-name="Initials"> <value>A.C.</value> </attr> <attr attr-name="Givenname"> <value>Anne</value> </attr> <attr attr-name="Surname"> <value>Bakker</value> </attr> <attr attr-name="Function"> <value>Consultant</value> </attr> </top> </root>
需求说明
将所有<top>子节点合并为一个<top>节点:
- 非
<attr>节点(如<number>)直接复制 - 相同
attr-name属性的<attr>节点聚合所有对应的<value>值(去重或保留重复值均可)
原有代码问题
你之前的XSLT代码丢失了<top>节点和<number>节点,原因是:
- 匹配
<top>的模板没有复制<top>本身,而是直接输出内部的<attr> - 未处理
<number>这类非<attr>节点
正确的XSLT 1.0解决方案(基于Muenchian分组)
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 身份模板:默认复制所有节点和属性 --> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template> <!-- 定义分组键:按attr-name属性分组所有attr节点 --> <xsl:key name="attr-by-name" match="attr" use="@attr-name"/> <!-- 匹配root节点,生成单个top节点 --> <xsl:template match="root"> <xsl:copy> <top> <!-- 复制第一个top里的number节点(假设所有top的number值一致) --> <xsl:apply-templates select="top[1]/number"/> <!-- 处理所有唯一的attr分组 --> <xsl:for-each select="top/attr[generate-id() = generate-id(key('attr-by-name', @attr-name)[1])]"> <xsl:copy> <!-- 复制attr的属性 --> <xsl:apply-templates select="@*"/> <!-- 输出当前分组下的所有value节点 --> <xsl:apply-templates select="key('attr-by-name', @attr-name)/value"/> </xsl:copy> </xsl:for-each> </top> </xsl:copy> </xsl:template> <!-- 如果需要去重value,取消以下注释即可 --> <!-- <xsl:key name="value-by-text" match="value" use="."/> <xsl:template match="value"> <xsl:if test="generate-id() = generate-id(key('value-by-text', .)[1])"> <xsl:copy-of select="."/> </xsl:if> </xsl:template> --> </xsl:stylesheet>
输出效果
保留所有value(含重复)的输出:
<root> <top> <number>999</number> <attr attr-name="Numbervalue"> <value>184</value> <value>1034</value> </attr> <attr attr-name="Initials"> <value>A.C.</value> <value>A.C.</value> </attr> <attr attr-name="Givenname"> <value>Anne</value> <value>Anne</value> </attr> <attr attr-name="Surname"> <value>Bakker</value> <value>Bakker</value> </attr> <attr attr-name="Function"> <value>Developer</value> <value>Consultant</value> </attr> </top> </root>
去重value后的输出(启用注释中的去重模板):
<root> <top> <number>999</number> <attr attr-name="Numbervalue"> <value>184</value> <value>1034</value> </attr> <attr attr-name="Initials"> <value>A.C.</value> </attr> <attr attr-name="Givenname"> <value>Anne</value> </attr> <attr attr-name="Surname"> <value>Bakker</value> </attr> <attr attr-name="Function"> <value>Developer</value> <value>Consultant</value> </attr> </top> </root>
内容的提问来源于stack exchange,提问作者Petro Hagenauw
相关产品推荐
相关产品推荐

