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

使用XSLT将XML转CSV时表头重复与换行问题求助

XSLT转换XML到CSV:解决表头重复与数据无换行问题

问题详情

使用XSLT将XML转换为CSV时,遇到两个问题:表头重复输出,且每条员工数据无法单独换行。相关代码与输出如下:

XML输入

<EmployeeDetails>
    <Employee>
        <FirstName>harry</FirstName>
        <SecondName>potter</SecondName>
        <Email>harrypotter@gmail.com</Email>
    </Employee>
    <Employee>
        <FirstName>tony</FirstName>
        <SecondName>stark</SecondName>
        <Email>tonystark@gmail.com</Email>
    </Employee>
</EmployeeDetails>

原XSLT代码

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8" />

<xsl:template match="/">
    <xsl:variable name="data" select="//*[not(*)]" />
    <!-- header -->
    <xsl:for-each select="$data">
        <xsl:value-of select="name()" />
        <xsl:if test="position()!=last()">
            <xsl:text>,</xsl:text>
        </xsl:if>
    </xsl:for-each>
    <xsl:text>&#10;</xsl:text>
    <!-- data -->
    <xsl:for-each select="$data">
        <xsl:value-of select="." />
        <xsl:if test="position()!=last()">
            <xsl:text>,</xsl:text>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

当前错误输出

FirstName,SecondName,Email,FirstName,SecondName,Email
harry,potter,harrypotter@gmail.com,tony,stark,tonystark@gmail.com

期望输出

FirstName,SecondName,Email 
harry,potter,harrypotter@gmail.com
tony,stark,tonystark@gmail.com

解决方案

修正后的XSLT代码

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8" />

<xsl:template match="/">
    <!-- 基于第一个Employee节点生成唯一表头 -->
    <xsl:for-each select="EmployeeDetails/Employee[1]/*">
        <xsl:value-of select="name()" />
        <xsl:if test="position() != last()">
            <xsl:text>,</xsl:text>
        </xsl:if>
    </xsl:for-each>
    <xsl:text>&#10;</xsl:text>
    
    <!-- 遍历每个Employee节点生成独立数据行 -->
    <xsl:for-each select="EmployeeDetails/Employee">
        <xsl:for-each select="*">
            <xsl:value-of select="." />
            <xsl:if test="position() != last()">
                <xsl:text>,</xsl:text>
            </xsl:if>
        </xsl:for-each>
        <!-- 每条数据后添加换行 -->
        <xsl:if test="position() != last()">
            <xsl:text>&#10;</xsl:text>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

问题解析

  1. 表头重复问题:原代码中$data变量选中了所有叶子节点(所有员工的字段),导致表头遍历了6个节点,重复输出两次表头。修正后仅取第一个Employee的子节点生成表头,保证表头唯一。
  2. 数据无换行问题:原代码直接遍历所有叶子节点拼接数据,导致所有员工数据在同一行。修正后改为外层遍历每个Employee节点,内层遍历该员工的字段,每个员工数据输出完成后添加换行,实现每行对应一条员工记录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 08:35:18