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

如何用XSL 1.0将逗号分隔行转换为XML(含带引号内容)

XSLT处理带引号的CSV文本转XML结构

需求场景

输入的XML包含一段CSV格式的文本,其中部分字段用双引号包裹(字段内包含逗号),需要将这段CSV文本拆分为<column>节点,保留原始字段内容并去掉包裹的双引号。

输入内容

<raw>
Value1,Value2,Value3,Value4,Value5,"Paris,France"
</raw>

期望输出

<raw>
<column>Value1</column>
<column>Value2</column>
<column>Value3</column>
<column>Value4</column>
<column>Value5</column>
<column>Paris,France</column>
</raw>

现有代码问题分析

你当前的代码假设输入已经是结构化的<RawData>、<row>、<column>节点,但实际输入是<raw>节点内的纯CSV文本,完全不匹配输入结构;同时没有处理带引号的字段,无法识别字段内的逗号不是分隔符。

正确的XSLT 1.0实现方案

下面是适配需求的XSLT代码,通过递归模板处理CSV拆分,同时支持带引号的字段:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- 匹配根节点,复制<raw>标签 -->
    <xsl:template match="raw">
        <raw>
            <!-- 调用拆分模板,处理<raw>内的文本内容 -->
            <xsl:call-template name="split-csv">
                <xsl:with-param name="text" select="normalize-space(.)"/>
            </xsl:call-template>
        </raw>
    </xsl:template>

    <!-- 递归拆分CSV的核心模板 -->
    <xsl:template name="split-csv">
        <xsl:param name="text"/>
        <xsl:param name="delimiter" select="','"/>

        <xsl:choose>
            <!-- 情况1:文本以双引号开头,处理带引号的字段 -->
            <xsl:when test="starts-with($text, '&quot;')">
                <!-- 找到闭合的双引号位置 -->
                <xsl:variable name="quote-end" select="substring-after($text, '&quot;')"/>
                <xsl:variable name="field" select="substring-before($quote-end, '&quot;')"/>
                <!-- 输出字段,去掉引号 -->
                <column><xsl:value-of select="$field"/></column>
                <!-- 处理剩余文本:跳过闭合引号后的分隔符,继续递归 -->
                <xsl:variable name="remaining" select="substring-after($quote-end, concat('&quot;', $delimiter))"/>
                <xsl:if test="$remaining != ''">
                    <xsl:call-template name="split-csv">
                        <xsl:with-param name="text" select="$remaining"/>
                    </xsl:call-template>
                </xsl:if>
            </xsl:choose>
            <!-- 情况2:普通字段,按分隔符拆分 -->
            <xsl:when test="contains($text, $delimiter)">
                <column><xsl:value-of select="substring-before($text, $delimiter)"/></column>
                <!-- 递归处理剩余文本 -->
                <xsl:call-template name="split-csv">
                    <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
                </xsl:call-template>
            </xsl:when>
            <!-- 情况3:最后一个字段,直接输出 -->
            <xsl:otherwise>
                <xsl:if test="$text != ''">
                    <column><xsl:value-of select="$text"/></column>
                </xsl:if>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <!-- 匹配文本节点,避免默认输出 -->
    <xsl:template match="text()"/>
</xsl:stylesheet>

关键逻辑说明

  • 匹配<raw>节点:保留外层<raw>标签,调用拆分模板处理内部文本,用normalize-space()去除首尾空白(包括换行)。
  • 递归拆分模板:
    • 优先处理以双引号开头的字段:先找到闭合的双引号,提取中间内容作为字段值,然后跳过引号后的分隔符,继续处理剩余文本。
    • 处理普通字段:按逗号分隔符拆分,提取第一个字段后递归处理剩余内容。
    • 处理最后一个字段:直接输出剩余的非空文本。
  • 抑制默认文本输出:最后一个模板匹配所有文本节点,避免原始CSV文本直接输出到结果中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 22:07:47