Jak mogę automatycznie konwertować wiele plików XML w CSV [zamknięte]

0

Mam około stu plików XML (o tej samej strukturze) i chcę je zaimportować w SAS. Niestety robiąc to mam pewne problemy związane z plikiem MAP plików XML (nie mam pliku MAP dla tych plików). Więc chciałbym przekonwertować te pliki w CSV przez Excel. Ale jeśli korzystam z tej ścieżki, potrzebuję czegoś, co jest w stanie przekonwertować masowo wszystkie moje pliki XML w CSV, ponieważ wyraźnie nie mogę konwertować osobno każdego pliku.

Ktoś wie, jak mogę rozwiązać?

Dzięki.

Giacomo Rosaspina
źródło
Czy możesz dodać przykładowy plik wejściowy?
aborruso
Czy możesz podać próbkę swojego problemu?
Lee
połączyć
Giacomo Rosaspina
Dodałem w komentarzu link do przykładu moich plików XML
Giacomo Rosaspina
1
połączony plik to plik XLSX (Excel), a nie plik XML. Czy chcesz przekonwertować XML - & gt; CSV lub XLSX - & gt; CSV?
Sir Adelaide

Odpowiedzi:

1

Rozwiązałem swój problem z tym skryptem 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
Giacomo Rosaspina
źródło
0

Ponieważ wydajesz się być zaznajomiony z SAS, albo będziesz musiał być wkrótce, użyję R, aby odczytać pliki Excel, a następnie ponownie je zapisać jako CSV.

Poniższy kod pozwala ustawić katalog roboczy, odczytać zawartość na liście i przeglądać listę, aby konwertować pliki w kilku wierszach.

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"))
}
Fernando Eblagon
źródło
0

Dla poniższego kodu możesz użyć dowolnego procesora XSLT-2.0 do konwersji XML na plik CSV.

Plik XML powinien mieć taką strukturę:

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

W tym przykładzie używam następującego pliku 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>

A to jest arkusz stylów XSLT-2.0, którego można użyć do przekształcenia wszystkich plików XML w pliki CSV. O ile to przetestowałem, działa na wszystkie przypadki opisane w specyfikacji . Ale szczerze mówiąc, nie mogę tego zagwarantować. Musisz to przetestować i przekazać tutaj swoją opinię.

Jednak oto kod XSLT-2.0, który konwertuje XML na CSV:

<?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>

Wynikiem tego jest:

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

Jeśli umieścisz tę transformację w pętli skryptu, możesz przekształcić wiele plików XML jednocześnie.

zx485
źródło
Gdzie muszę umieścić kod XSLT-2.0, który konwertuje XML na CSV?
Giacomo Rosaspina
Nie jestem pewien, czy rozumiem twoje pytanie. Kopiujesz kod do .xslt plik jak XML2CSV.xslt a następnie zastosuj go do wszystkich plików XML za pomocą skryptu bash wywołującego procesor XSLT lub coś takiego. Na przykład za pomocą polecenia for f in *.xml; do java -jar saxon9he.jar -xsl:XML2CSV.xslt "$f"; done. Wystarczy przekierować dane wyjściowe do żądanych plików.
zx485