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.


Czy możesz dodać przykładowy plik wejściowy?
aborruso

Czy możesz podać próbkę swojego problemu?
Lee


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

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"))
}

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.


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.