You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改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&#10;
    <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>
    &#10;
  </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&#10;
    <!-- 仅处理每组唯一记录的第一条 -->
    <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>
    &#10;
  </xsl:template>
</xsl:stylesheet>
关键修改说明
  1. 添加去重键:用<xsl:key>定义基于id的分组规则,把相同id的记录归为一组。如果重复判断需要多个字段组合,可修改use属性(比如use="concat(id, name)")。
  2. 过滤重复记录:在遍历记录时,只选择每组中的第一条(通过generate-id()对比实现),避免重复输出。
  3. 修正统计数:统计总数时使用去重后的节点集,确保数值准确。

内容的提问来源于stack exchange,提问作者sandy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 14:15:26