使用 XML 从 XML 转换为 CSV 时 CSV 文件中的标题

Posted

技术标签:

【中文标题】使用 XML 从 XML 转换为 CSV 时 CSV 文件中的标题【英文标题】:Title in CSV file when converting from XML to CSV using XML 【发布时间】:2019-10-15 04:44:43 【问题描述】:

我正在尝试使用 XSLT 将 XML 转换为 CSV,我正在获取记录,但我需要 CSV 文件中的标题。

例如:

Name    EmailAddress
Gaurav   Gaur@yopmail.com
Satya    Satya@yopmail.com

XML

<?xml version="1.0"?>
<SearchResults>
<Columns>
    <Column Label="Name">Name</Column>
    <Column Label="Email Addresses">EmailAddress</Column>
</Columns>
<Rows>
    <Row>
        <Name>Gaurav Joshi</Name>
        <EmailAddress>ybenipohe-3888@yopmail.com</EmailAddress>

    </Row>
    <Row>
        <Name>Satya</Name>
        <EmailAddress>eqaddoxoqu-8703@yopmail.com</EmailAddress>
     </Row>

XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <!-- This transform is used to generate a CSV file.-->
  <xsl:output method="text" indent="no" />
  <xsl:template match="/">
    <xsl:apply-templates select="/SearchResults/Rows/Row" />
  </xsl:template>
  <xsl:template match="/SearchResults/Rows/Row">
    <xsl:text>&quot;</xsl:text>
    <xsl:value-of select="position()" />
    <xsl:text>&quot;</xsl:text>
    <xsl:for-each select="*">
      <xsl:text>,&quot;</xsl:text>
      <xsl:value-of select="." />
      <xsl:text>&quot;</xsl:text>
    </xsl:for-each>
    <xsl:text>
    </xsl:text>
  </xsl:template>
  <xsl:template match="/SearchResults/Columns" />
</xsl:stylesheet>

【问题讨论】:

【参考方案1】:

您当前有一个匹配/SearchResults/Columns 的模板,这实际上是多余的,因为您没有任何模板明确选择这些(由于您在使用&lt;xsl:apply-templates select="/SearchResults/Rows/Row" /&gt;)。

但是你可以很容易地调整它来输出标题,然后你只需要一个xsl:apply-templates 来选择它。

试试这个 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <!-- This transform is used to generate a CSV file.-->
  <xsl:output method="text" indent="no" />

  <xsl:template match="/">
    <xsl:apply-templates select="/SearchResults/Columns" />
    <xsl:apply-templates select="/SearchResults/Rows/Row" />
  </xsl:template>

  <xsl:template match="Row">
    <xsl:text>"</xsl:text>
    <xsl:value-of select="position()" />
    <xsl:text>"</xsl:text>
    <xsl:for-each select="*">
      <xsl:text>,"</xsl:text>
      <xsl:value-of select="." />
      <xsl:text>"</xsl:text>
    </xsl:for-each>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>

  <xsl:template match="Columns">
    <xsl:text>"Row"</xsl:text>
    <xsl:for-each select="Column">
       <xsl:text>,"</xsl:text>
       <xsl:value-of select="@Label" />
       <xsl:text>"</xsl:text>
    </xsl:for-each>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>
</xsl:stylesheet>

但这使得(大?)假设每个Row 的子节点与相关Column 节点的顺序相同。如果不是这种情况,你有工作要做。尝试用这个替换匹配Row的模板

  <xsl:template match="Row">
    <xsl:text>"</xsl:text>
    <xsl:value-of select="position()" />
    <xsl:text>"</xsl:text>
    <xsl:variable name="Row" select="." />
    <xsl:for-each select="/SearchResults/Columns/Column">
      <xsl:text>,"</xsl:text>
      <xsl:value-of select="$Row/*[name() = current()]" />
      <xsl:text>"</xsl:text>
    </xsl:for-each>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>

【讨论】:

以上是关于使用 XML 从 XML 转换为 CSV 时 CSV 文件中的标题的主要内容,如果未能解决你的问题,请参考以下文章

在python中使用argparse将csv转换为xml

将 .CSV 文件转换为 .XML 的 PHP 脚本

有没有办法使用 KnockoutJS 将 XML 文件转换为 CSV?

是否可以使用 Azure Synapse 和 Azure 数据工厂将 CSV 转换为 XML?

XML 到 CSV 使用 XSLT 帮助

XML 到 CSV 格式