如何修改XSLT实现XML转无重复记录的CSV(含尾行统计)
问题描述
需要将XML文件转换为CSV文件,要求:
- 尾行添加总记录数
- 将XML中部分同类型字段合并为一列
现有XSLT已实现上述功能,但输入XML存在重复记录,导致CSV输出包含重复行,且尾行统计的记录数错误。需修改XSLT去除重复记录并修正统计数。
示例输入XML
<root> <record> <id>1</id> <name>Alice</name> <tag>admin</tag> <tag>user</tag> </record> <record> <id>1</id> <name>Alice</name> <tag>admin</tag> <tag>user</tag> </record> <record> <id>2</id> <name>Bob</name> <tag>guest</tag> </record> </root>
现有XSLT代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="UTF-8"/> <xsl:strip-space elements="*"/> <!-- 表头 --> <xsl:template match="/"> ID,Name,Tags <xsl:apply-templates select="root/record"/> <!-- 统计记录数 --> Total Records: <xsl:value-of select="count(root/record)"/> </xsl:template> <!-- 处理每条记录 --> <xsl:template match="record"> <xsl:value-of select="id"/>,<xsl:value-of select="name"/>, <!-- 合并tag字段 --> <xsl:for-each select="tag"> <xsl:if test="position() > 1">;</xsl:if> <xsl:value-of select="."/> </xsl:for-each> </xsl:template> </xsl:stylesheet>
当前输出结果
ID,Name,Tags 1,Alice,admin;user 1,Alice,admin;user 2,Bob,guest Total Records: 3
期望输出结果
ID,Name,Tags 1,Alice,admin;user 2,Bob,guest Total Records: 2
修改后的XSLT代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="UTF-8"/> <xsl:strip-space elements="*"/> <!-- 定义键值用于去重,以id作为唯一标识,可根据实际规则调整 --> <xsl:key name="unique-record" match="record" use="id"/> <!-- 表头 --> <xsl:template match="/"> ID,Name,Tags <!-- 仅处理每组唯一记录的第一条 --> <xsl:apply-templates select="root/record[generate-id() = generate-id(key('unique-record', id)[1])]"/> <!-- 统计去重后的记录数 --> Total Records: <xsl:value-of select="count(root/record[generate-id() = generate-id(key('unique-record', id)[1])])"/> </xsl:template> <!-- 处理每条唯一记录 --> <xsl:template match="record"> <xsl:value-of select="id"/>,<xsl:value-of select="name"/>, <!-- 合并tag字段 --> <xsl:for-each select="tag"> <xsl:if test="position() > 1">;</xsl:if> <xsl:value-of select="."/> </xsl:for-each> </xsl:template> </xsl:stylesheet>
关键修改说明
- 添加去重键:用
<xsl:key>定义基于id的分组规则,把相同id的记录归为一组。如果重复判断需要多个字段组合,可修改use属性(比如use="concat(id, name)")。 - 过滤重复记录:在遍历记录时,只选择每组中的第一条(通过
generate-id()对比实现),避免重复输出。 - 修正统计数:统计总数时使用去重后的节点集,确保数值准确。
内容的提问来源于stack exchange,提问作者sandy
相关产品推荐
相关产品推荐

