【问题标题】:How to convert XML into CSV using XSL如何使用 XSL 将 XML 转换为 CSV
【发布时间】:2022-01-09 21:09:00
【问题描述】:

我有一个这样的 XML 文件

<Tester author="Name" id="16384543">
  <insert tableName="sampletable">
    <column name="id" valueNumeric="2"/>
    <column name="name" value="kathy"/>
    <column name="active" valueBoolean="true"/>
    <column name="age" valueNumeric="2"/>
  </insert>
  <insert tableName="sampletable">
    <column name="id" valueNumeric="23"/>
    <column name="name" value="Queen"/>
    <column name="active" valueBoolean="true"/>
    <column name="age" valueNumeric="29"/>
  </insert>
  <insert tableName="sampletable">
    <column name="id" valueNumeric="25"/>
    <column name="name" value="varshan"/>
    <column name="active" valueBoolean="false"/>
    <column name="age" valueNumeric="5"/>
  </insert>
</Tester>

我需要将 XML 转换为 CSV,如下所示:

id,name,active,age
2,kathy,TRUE,2
23,Queen,TRUE,29
25,varshan,FALSE,5

要求:

这些列属性将是动态的,并且对于不同的 XML 会有所不同。有人可以帮忙吗?

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    这是一种可以做到的方法。

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        version="1.0">
    
      <xsl:output method="text"/>
    
      <xsl:template match="/">
        <!-- Header -->
        <xsl:apply-templates select="Tester/insert[1]">
          <xsl:with-param name="header">true</xsl:with-param>
        </xsl:apply-templates>
        <!-- Data -->
        <xsl:apply-templates select="Tester/insert"/>
      </xsl:template>
      
      <xsl:template match="insert">
        <xsl:param name="header"/>
        <xsl:for-each select="column">
          <!-- For the header take the name attribute, else take the attribute starting with value -->
          <xsl:choose>
            <xsl:when test="$header='true'">
              <xsl:value-of select="@name"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="@*[starts-with(name(),'value')]"/>
            </xsl:otherwise>
          </xsl:choose>
          <!-- Insert comma between values, except for last value insert new line -->
          <xsl:choose>
            <xsl:when test="position()=last()">
              <xsl:text>&#xa;</xsl:text>
            </xsl:when>
            <xsl:otherwise>
              <xsl:text>,</xsl:text>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:for-each>
      </xsl:template>
      
    </xsl:stylesheet>
    

    在这里查看它的工作原理:https://xsltfiddle.liberty-development.net/3MXNWN6

    【讨论】:

    • 感谢塞巴斯蒂安的帮助!我错过了添加标题,它是 并且它说 Error parsing XML input at 1:16 : Version number '1.1' is invalid。第 1 行,第 16 位.....对此有什么想法吗?
    • 我不知道为什么你有 XML version="1.1" 并且如果你的文档被声明为 Standalone="no" 那么它必须依赖于其他一些文档?正如您从我发布的代码中看到的那样,我发布的代码有效,很难知道为什么它在您的输入上不起作用而没有看到它。尝试将文件的标题修改为 version="1.0"。
    • XMl 文件是由 liquibase 生成的,它的版本是 1.1..所以无法更改版本号..但是想知道为什么 XSL 无法解析这个 XML 版本!!!
    • 您使用的是哪个 XSLT 引擎?
    • 我使用的是 Eclipse 版本:Neon.3 Release (4.6.3)。我回答你的问题了吗?
    猜你喜欢
    • 2013-06-23
    • 1970-01-01
    • 2022-01-11
    • 2016-02-13
    • 2011-12-31
    • 2012-02-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-22
    相关资源
    最近更新 更多