Umwandlung XML in CSV

Du suchst ein Programm für einen bestimmten Zweck?
Antworten
Richard
Beiträge: 639
Registriert: 11.10.2012 14:18:37
Lizenz eigener Beiträge: GNU General Public License

Umwandlung XML in CSV

Beitrag von Richard » 22.05.2017 18:38:54

Hallo,

ich suche für Linux ein Tool um aus XML eine CSV zu wandeln. Es soll wohl mit xsltproc gehen, hier finde ich aber nichts für apt-get.

Wie man die Templates erstellt lese ich mir gerade durch.

Falls jemand ein Tool kennt das mit Drap&Drop aus XML eien Tabelle oder CSV machen kann ohne separate XSL-Datei würde ich die auch mal testen.

Richard

Benutzeravatar
heisenberg
Beiträge: 3542
Registriert: 04.06.2015 01:17:27
Lizenz eigener Beiträge: MIT Lizenz

Re: Umwandlung XML in CSV

Beitrag von heisenberg » 22.05.2017 18:48:09

XML besitzt hierarchisches Format und CSV eine flache zeilenoriente Struktur. Das geht erst mal nicht zusammen.

Mit einem einfachen Shellscript mit Hilfe von xmllint kann man das aber bestimmt hinbekommen.

Am besten zu stellst mal ein Beispiel Deiner Ausgangsdatei als Auszug zur Verfügung und auch wie die resultierende CSV aussehen soll.
Zuletzt geändert von heisenberg am 22.05.2017 18:50:57, insgesamt 1-mal geändert.
Jede Rohheit hat ihren Ursprung in einer Schwäche.

schwedenmann
Beiträge: 5528
Registriert: 30.12.2004 15:31:07
Wohnort: Wegberg

Re: Umwandlung XML in CSV

Beitrag von schwedenmann » 22.05.2017 18:48:39

Hallo

Muß es unbedingt ein deb sein ?


jar-file zum Konvertieren gibt es auch (google nach xml2csv) oder auch pythonscripts per google lassen sich finden.

mfg
schwedenmann

Richard
Beiträge: 639
Registriert: 11.10.2012 14:18:37
Lizenz eigener Beiträge: GNU General Public License

Re: Umwandlung XML in CSV

Beitrag von Richard » 22.05.2017 21:00:44

heisenberg hat geschrieben:Mit einem einfachen Shellscript mit Hilfe von xmllint kann man das aber bestimmt hinbekommen.
Im Grunde würde mir folgendes reichen. Aus:

Code: Alles auswählen

<datenbank>
    <ebene1>
        <name>mustermann</name>
        <vorname>max</vorname>
        <noten>
                    <klasse1>
                         <mathe>1</mathe>
                    </klasse1>
        </noten>
    </ebene1>
</datenbank>
soll werden

Code: Alles auswählen

name,vorname,mathe
mustermann,max,1
Wie bekomme ich die Inhalte der 1. Ebene und die 2 Ebenen tiefer zusammen?

Benutzeravatar
TRex
Moderator
Beiträge: 8069
Registriert: 23.11.2006 12:23:54
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: KA

Re: Umwandlung XML in CSV

Beitrag von TRex » 22.05.2017 22:07:35

Code: Alles auswählen

~$ xmlstarlet sel -T -t -m "/datenbank/ebene1" -v "concat(name, ';', vorname, ';', noten/klasse1/mathe)" -n datenbank.xml
schwede;alter;2
mustermann;max;1
Eiskalt geklaut von http://www.joyofdata.de/blog/transformi ... mlstarlet/
Jesus saves. Buddha does incremental backups.
Windows ist doof, Linux funktioniert nichtDon't break debian!Wie man widerspricht

Richard
Beiträge: 639
Registriert: 11.10.2012 14:18:37
Lizenz eigener Beiträge: GNU General Public License

Re: Umwandlung XML in CSV

Beitrag von Richard » 23.05.2017 18:59:34

@ TRex

Interessant. Im Gegensatz zu einem XSL-Template scheint das sogar für mich verständlich - falls ich jetzt nicht total daneben liege.

Mit

Code: Alles auswählen

concat(name, ';', vorname, ';', noten/klasse1/mathe)
gibt man die Tags und die Ebene der Tags an. Wenn jetzt angenommen danach noch ein Tag aber nur eine Ebene tiefer folgen soll müsste das hier gehen?

Code: Alles auswählen

concat(name, ';', vorname, ';', noten/klasse1/mathe, ';' [b]kopfnoten/mitarbeit[/b])
?

Der Tag 'kopfnoten' wäre auf der gleichen Ebene wie 'name' und 'mitarbeit' eine Ebene tiefer.

edit
Geht tatsächlich. Nur die Tabellentitel werden nicht übernommen, die muss man ja aber nur einmal anlegen, das geht auch manuell. Das massenhafte Auslesen der ganzen Inhalte ist das Problem. Danke für den Tipp. Ich teste das jetzt nochmal mit einer größeren xml.

Richard
Beiträge: 639
Registriert: 11.10.2012 14:18:37
Lizenz eigener Beiträge: GNU General Public License

Re: Umwandlung XML in CSV

Beitrag von Richard » 24.05.2017 16:04:54

Was leider nicht geht ist wenn es mehrere gleiche Untertags gibt, z. B.

Code: Alles auswählen

<root>
  <record>
    <object>inhalt1</object>
    <object>inhalt2</object>
  </record>
  <record>
    <anderertag>inhalt3</anderertag>
  </record>
</root>
Hier gibt es im 1. record-Tag 2x den object-Tag. Wenn ich da z. B. das hier verwende

Code: Alles auswählen

xmlstarlet sel -T -t -m "/root" -v "concat(record/object, ';', record/object, ';', record/anderertag)" -n datenbank.xml
gibt er mit zwar 3 Inhalte aus, aber halt 2x "inhalt1" und 0x "inhalt2". Selbst wenn ich einen dritten (nicht vorhanden) object-Tag i die xmlstarlet-Abfrage einfüge bekomme ich wieder "inhalt1" statt nichts.

Benutzeravatar
heisenberg
Beiträge: 3542
Registriert: 04.06.2015 01:17:27
Lizenz eigener Beiträge: MIT Lizenz

Re: Umwandlung XML in CSV

Beitrag von heisenberg » 24.05.2017 16:17:02

Wenn Du reale Daten zeigst, dann geht das bestimmt besser. Zur Anonymisierung einfach bestimmte Werte ändern, aber die Struktur gleich lassen. Das geht bestimmt.

Hier mal ein Beispiel wie das gehen könnte:

Code: Alles auswählen

<datenbank>
    <ebene1>
        <name>Maus</name>
        <vorname>Meike</vorname>
        <noten>
                    <klasse1>
                         <mathe>2</mathe>
                    </klasse1>
        </noten>
        <kopfnoten typ="primaer">
                <lehrer>maier</lehrer>
                <mitarbeit>1</mitarbeit>
        </kopfnoten>
        <kopfnoten typ="sekundaer">
                <lehrer>mueller</lehrer>
                <mitarbeit>5</mitarbeit>
        </kopfnoten>
    </ebene1>
    <ebene1>
        <name>mustermann</name>
        <vorname>max</vorname>
        <noten>
                    <klasse1>
                         <mathe>1</mathe>
                    </klasse1>
        </noten>
        <kopfnoten typ="primaer">
                <lehrer>maier</lehrer>
                <mitarbeit>3</mitarbeit>
        </kopfnoten>
        <kopfnoten typ="sekundaer">
                <lehrer>mueller</lehrer>
                <mitarbeit>5</mitarbeit>
        </kopfnoten>
    </ebene1>
</datenbank>
Kopfnoten bei Lehrer Müller:

Code: Alles auswählen

 xmlstarlet sel -T -t -m "/datenbank/ebene1"                      \
        -v "concat(name, ';'                                      \
                  , vorname, ';'                                  \  
                  , noten/klasse1/mathe,';'                       \
                  , kopfnoten[lehrer='mueller']/mitarbeit)"       \
        -n test.xml 
Kopfnoten mit Eigenschaft "Primaer":

Code: Alles auswählen

 xmlstarlet sel -T -t -m "/datenbank/ebene1"                      \
        -v "concat(name, ';'                                      \
                  , vorname, ';'                                  \  
                  , noten/klasse1/mathe,';'                       \
                  , kopfnoten[@typ='primaer']/mitarbeit)"         \
        -n test.xml 
Jede Rohheit hat ihren Ursprung in einer Schwäche.

Richard
Beiträge: 639
Registriert: 11.10.2012 14:18:37
Lizenz eigener Beiträge: GNU General Public License

Re: Umwandlung XML in CSV

Beitrag von Richard » 25.05.2017 09:26:26

Ich habe aktuell keine echten Daten vorliegen, ich weiß nur wie es aussehen wird.

Das 1. Beispiel könnte funktionieren. Es müsste auch dann gehen, wenn innerhalb eines Tags mehrere gleiche Untertags sich befinden. Die Tags werden niemals zusätzliche Eigenschaften (typ="sekundaer") haben. Das ganze müsste gehen wenn es so aussieht (3 Untertags)

Code: Alles auswählen

<ebene1>
        <tag>inhalt1</tag>
        <tag>inhalt2</tag>
        <tag>inhalt3</tag>
</ebene1>
als auch so (nur 2 Untertags)

Code: Alles auswählen

<ebene1>
        <tag>inhalt1</tag>
        <tag>inhalt2</tag>
</ebene1>
Ich hab auch kein Problem damit einfach die Tags so oft einzulesen um alle möglichen Konstellationen mitzunehmen (denke mehr als 4 oder 5 sollten es nie sein), Hauptsache er holt sich dann keine Daten doppelt. Im 2. Beispiel sollte dann für den nicht vorhandenen 3. Tag gar nichts an der entsprechenden Stelle der CSV stehen (außer dem ; natürlich). LibreOffice sollte dann eine Zelle ohne Inhalt erstellen.

edit
Hab es mal mit dem 1. Beispiel versucht indem ich einfach mal 'typ=test' in die Tags eingefügt habe. Auch hier werden immer nur die Inhalte des 1. Untertags für alle weiteren Tags übernommen. In meinem Bsp. oben mit den 3 Tags würde jeder Tag den Inhalt 'inhalt1' bekommen und nicht 'inhalt2' bzw. 'inhalt3'. Das ist merkwürdig.

Antworten