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

如何修改XSLT实现XML转CSV时Details子节点单独换行

解决XML转CSV时子节点单独成行的问题

以下是针对需求修改后的XSLT代码,实现每个Details节点内容单独占一行的带引号CSV输出,同时兼容字段中含双引号的转义处理:


输入XML示例

<Root>
  <TrRecords>
    <TrID>TR001</TrID>
    <TrDate>2024-05-20</TrDate>
    <Details>
      <ItemID>ITEM001</ItemID>
      <Qty>5</Qty>
      <Price>10.99</Price>
    </Details>
    <Details>
      <ItemID>ITEM002</ItemID>
      <Qty>2</Qty>
      <Price>15.50</Price>
    </Details>
  </TrRecords>
  <TrRecords>
    <TrID>TR002</TrID>
    <TrDate>2024-05-21</TrDate>
    <Details>
      <ItemID>ITEM003</ItemID>
      <Qty>1</Qty>
      <Price>29.99</Price>
    </Details>
  </TrRecords>
</Root>

修改后的XSLT代码

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

  <!-- 转义CSV中的双引号:将单个"替换为"" -->
  <xsl:template name="escape-quotes">
    <xsl:param name="text"/>
    <xsl:choose>
      <xsl:when test="contains($text, '&quot;')">
        <xsl:value-of select="substring-before($text, '&quot;')"/>
        <xsl:text>&quot;&quot;</xsl:text>
        <xsl:call-template name="escape-quotes">
          <xsl:with-param name="text" select="substring-after($text, '&quot;')"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$text"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template match="/">
    <!-- 输出CSV表头 -->
    <xsl:text>"TrID","TrDate","ItemID","Qty","Price"&#10;</xsl:text>
    
    <!-- 遍历每个父交易记录节点 -->
    <xsl:for-each select="Root/TrRecords">
      <!-- 缓存父节点固定字段,避免重复查询 -->
      <xsl:variable name="tr-id">
        <xsl:call-template name="escape-quotes">
          <xsl:with-param name="text" select="TrID"/>
        </xsl:call-template>
      </xsl:variable>
      <xsl:variable name="tr-date">
        <xsl:call-template name="escape-quotes">
          <xsl:with-param name="text" select="TrDate"/>
        </xsl:call-template>
      </xsl:variable>

      <!-- 为每个Details节点单独输出一行 -->
      <xsl:for-each select="Details">
        <xsl:text>"</xsl:text><xsl:value-of select="$tr-id"/><xsl:text>","</xsl:text>
        <xsl:value-of select="$tr-date"/><xsl:text>","</xsl:text>
        
        <xsl:text>"</xsl:text>
        <xsl:call-template name="escape-quotes">
          <xsl:with-param name="text" select="ItemID"/>
        </xsl:call-template>
        <xsl:text>","</xsl:text>
        
        <xsl:text>"</xsl:text>
        <xsl:call-template name="escape-quotes">
          <xsl:with-param name="text" select="Qty"/>
        </xsl:call-template>
        <xsl:text>","</xsl:text>
        
        <xsl:text>"</xsl:text>
        <xsl:call-template name="escape-quotes">
          <xsl:with-param name="text" select="Price"/>
        </xsl:call-template>
        <xsl:text>"&#10;</xsl:text>
      </xsl:for-each>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

关键逻辑说明

  1. 换行控制:通过&#10;输出换行符,确保每个Details节点对应单独一行
  2. 字段转义:新增escape-quotes模板,严格遵循CSV规范处理含双引号的字段
  3. 性能优化:缓存父节点的TrID和TrDate字段,避免在遍历Details时重复查询

预期CSV输出

"TrID","TrDate","ItemID","Qty","Price"
"TR001","2024-05-20","ITEM001","5","10.99"
"TR001","2024-05-20","ITEM002","2","15.50"
"TR002","2024-05-21","ITEM003","1","29.99"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 12:10:00