如何自动将多个 XML 文件转换为 CSV 文件

如何自动将多个 XML 文件转换为 CSV 文件

我有大约一百个 XML 文件(具有相同的结构),我想将它们导入 SAS。不幸的是,在这样做时,我遇到了一些与 XML 文件的 MAP 文件相关的问题(我没有这些文件的 MAP 文件)。所以我想通过 Excel 将这些文件转换为 CSV。但如果我使用这种方法,我需要能够将所有 XML 文件大规模转换为 CSV 的东西,因为显然我无法手动逐个转换每个文件。

有谁知道我该如何解决?

谢谢。

答案1

我已经用这个 VBA 脚本解决了我的问题:

Public Sub ConvertXmlToXlsx()

Application.DisplayAlerts = False

Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object

xmlFolder = "C:\Users\xxx\xxx\xxx\xxx\"
convFolder = "C:\Users\xxx\xxx\xxx\xxx\"


Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(xmlFolder)
For Each objFile In objFolder.Files
    If UCase(Right(objFile.Name, Len(XML))) = UCase(XML) Then
        NewFileName = convFolder & objFile.Name & ".xlsx"

        Workbooks.OpenXML (objFolder & "\" & objFile.Name), LoadOption:=xlXmlLoadImportToList
        ActiveWorkbook.SaveAs Filename:=NewFileName

        ActiveWorkbook.Close

    End If
Next objFile

End Sub

答案2

由于您似乎熟悉 SAS,或者您很快就会熟悉,我会使用 R 读出 Excel 文件,然后将它们再次写入 CSV。

下面的代码允许您设置工作目录,将内容读入列表并遍历列表以在几行中转换文件。

library(readxl)
setwd("The directory containing your files")
list <- list.files()
for(i in 1:length(list)) {
  Intermediate <- read_excel(list[i])
  write.csv(Intermediate, paste0(list[i],".csv"))
}

答案3

对于以下代码,您可以使用任何 XSLT-2.0 处理器将 XML 转换为 CSV 文件。

XML 文件应具有如下结构:

<AnyRoot>
  <AnyEntry>
    <Value1></Value1>
    <Value2></Value2>
    <Value3></Value3>
    ...
  </AnyEntry>
  <AnyEntry>
    <Value1></Value1>
    ...
  </AnyEntry>
  ...
</AnyRoot>

对于此示例,我使用以下 XML 文件:

<root>
    <Entry>
      <CSVValue1>A</CSVValue1>
      <CSVValue2>"B"</CSVValue2>
      <CSVValue3>C,D</CSVValue3>
      <CSVValue4>"E","F"</CSVValue4>
    </Entry>
    <Entry>
      <CSVValue1>G H</CSVValue1>
      <CSVValue2>""</CSVValue2>
      <CSVValue3></CSVValue3>
      <CSVValue4 />
    </Entry>
    <Entry>
      <CSVValue1>1996</CSVValue1>
      <CSVValue2>Jeep</CSVValue2>
      <CSVValue3>Grand Cherokee</CSVValue3>            
      <CSVValue4>MUST SELL!
air, moon roof, loaded</CSVValue4>
      <CSVValue5>4999.00</CSVValue5>            
    </Entry>
</root>

这是 XSLT-2.0 样式表,可用于将所有 XML 文件转换为 CSV 文件。据我测试,它适用于规范中描述的所有情况。但说实话,我不能保证。你必须测试一下并在这里给出一些反馈。

但是,这里是将 XML 转换为 CSV 的 XSLT-2.0 代码:

<?xml version='1.0' encoding='utf-8'?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" omit-xml-declaration="yes" indent="yes"/>
<!-- ================================================================= -->
<!-- XML to CSV Version 1.0 by zx485 on 30-01-2019@01:58               -->
<!-- Run it with java -jar saxon9he.jar -xsl:XML2CSV.xslt input.xml    -->
<!-- ================================================================= -->
    <xsl:variable name="csvItems">
      <xsl:for-each select="/*/*[1]/*">
        <Item name="{local-name()}" />
      </xsl:for-each>
    </xsl:variable>

    <xsl:template match="/*">
      <xsl:value-of select="$csvItems/Item/@name" separator="," />
      <xsl:text>&#xa;</xsl:text>
      <xsl:apply-templates select="*" />
    </xsl:template>      

    <xsl:template match="/*/*">
      <xsl:for-each select="*">
        <xsl:apply-templates select="." />
        <xsl:if test="position() != last()">
            <xsl:text>,</xsl:text>
        </xsl:if>
      </xsl:for-each>
      <xsl:text>&#xa;</xsl:text>
    </xsl:template>

    <xsl:template match="text()">
      <xsl:choose>
        <xsl:when test=".='&quot;&quot;'">
          <xsl:value-of select="'&quot;&quot;'" />
        </xsl:when>
        <xsl:when test="contains(.,',') or contains(.,'&#xa;')">
          <xsl:value-of select="concat('&quot;',.,'&quot;')" />
        </xsl:when>
        <xsl:when test="contains(.,'&quot;')">
          <xsl:value-of select="replace(.,'&quot;','&quot;&quot;')" />
        </xsl:when>
        <xsl:when test="contains(.,',') and contains(.,'&quot;')">
          <xsl:value-of select="concat('&quot;',replace(.,'&quot;','&quot;&quot;'),'&quot;')" />
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="." />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

输出结果为:

CSVValue1,CSVValue2,CSVValue3,CSVValue4
A,""B"","C,D",""E","F""
G H,"",,
1996,Jeep,Grand Cherokee,"MUST SELL!
air, moon roof, loaded",4999.00

如果将此转换放入脚本循环中,则可以一次转换多个 XML 文件。

相关内容