XML-Datei auslesen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
yuyu
User
Beiträge: 10
Registriert: Mittwoch 12. Dezember 2018, 21:07

Hallo Forum,

ich möchte gerne aus einer XML Eingabedatei viele Daten auslesen und dann in eine Textdatei schreiben.

### Eingabedatei ###
<Name>Max</Name>
<Age>23</Age>
<Number>1234567</Number>
<Name>Jenny</Name>
<Age>19</Age>
<Number>7654321</Number>
### Eingabedatei ###


### Textdatei###
Name: Max
Age: 23
Number: 1234567

Name: Jenny
Age: 19
Number: 7654321
### Textdatei###

Habe vorher nix mit Python gemacht, könntet ihr mir bitte helfen :?:
Benutzeravatar
sparrow
User
Beiträge: 4184
Registriert: Freitag 17. April 2009, 10:28

Wie lautet denn deine konkrete Frage?
Was hast du probiert, was geht nicht?
Benutzeravatar
__blackjack__
User
Beiträge: 13068
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@yuyu: Für Grundlagen von Python gibt es in der Python-Dokumentation ein Tutorial, welches Du durcharbeiten kannst.

Wenn die Grundlagen da sind, könntest Du mal in die Standardbibliothek schauen, was es da für XML an Modulen gibt. Insbesondere `xml.etree`.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@yuyu: die Eingbedatei ist kein XML, und sieht auch sonst nicht wie schönes XML aus. Wie sieht das XML wirklich aus, und woher kommt das?
yuyu
User
Beiträge: 10
Registriert: Mittwoch 12. Dezember 2018, 21:07

das ist nur ein kleines Beispiel, natürlich muss das so aussehen:
<data>
<Name>Max</Name>
<Age>23</Age>
<Number>1234567</Number>
<Name>Jenny</Name>
<Age>19</Age>
<Number>7654321</Number>
<\data>
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Abgesehen davon, dass das schließende Tag falsch ist, bringt uns das ja auch nicht weiter. Was hast du bisher probiert, um das XML einzulesen?
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

... was immer noch kein gültiges XML ist. Die Frage ist, warum Name, Age, Number immer wiederholt werden, ohne irgendeine Unterstrukturierung.
yuyu
User
Beiträge: 10
Registriert: Mittwoch 12. Dezember 2018, 21:07

besteht die Hoffnung einfach nur nach den Tags zu suchen, ohne den ganzen XML-Tree vorzugeben?
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Hast Du Dir schon die Dokumentation zu ElementTree durchgelesen? Was hast Du schon versucht? Code? Wo gibt es konkret ein Problem?
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Hoffnung besteht ja immer. Und natürlich kann ich mir 3 Tage frei nehmen, und ein 100seitiges Traktat über Dutzende formen von XML Dokumenten, von denen ich hoffe, dass sie deinem Problem nah kommen, und deren programmatische Behandlung, verfassen.

Alternativ könntest du deine Hausaufgaben machen, und konkrete, gültige Dokumente zeigen, damit man beurteilen kann, ob und wie das geht. Und welchen Code du schon hast.

Das ganze kostet dann alle Beteiligten weniger Zeit & nerven.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Hier ein Beispiel zur besseren Orientierung:

Code: Alles auswählen

from xml.etree import ElementTree

source = """<data>
<Name>Max</Name>
<Age>23</Age>
<Number>1234567</Number>
<Name>Jenny</Name>
<Age>19</Age>
<Number>7654321</Number>
</data>"""

root = ElementTree.fromstring(source)
for node in root:
    print(f'{node.tag}: {node.text}')
    # Bei Python < 3.6 dies nehmen:
    # print('{0.tag}: {0.text}'.format(node))
Wie meine Vorposter schon schrieben, bräuchte man für eine genauere Hilfe schon die tatsächliche Struktur der XML-Daten. Aber vielleicht reicht das Beispiel ja schon.
yuyu
User
Beiträge: 10
Registriert: Mittwoch 12. Dezember 2018, 21:07

Danke, funktioniert. Kann ich die Ausgabe mit einer If-Abfrage steuern, also nur bei bestimmten Tag-Elementen?
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ja.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Meinst du so?

Code: Alles auswählen

from xml.etree import ElementTree

source = """<data>
<Name>Max</Name>
<Age>23</Age>
<Number>1234567</Number>
<Name>Jenny</Name>
<Age>19</Age>
<Number>7654321</Number>
</data>"""

root = ElementTree.fromstring(source)
for name in root.findall('Name'):
    print(name.text)
Ansonsten geht natürlich auch:

Code: Alles auswählen

for node in root:
    if node.tag == 'meintag':
        # ...
Würde ich aber nur bei verschiedenen Tags machen. Ansonsten ist findall() schon die bessere Wahl.
yuyu
User
Beiträge: 10
Registriert: Mittwoch 12. Dezember 2018, 21:07

Hallo,
lassen sich Name, Age und Number auch in beliebigen Unterstrukturen finden? Folgendes ergibt keine Ausgabe:

import xml.etree.ElementTree as ET
tree = ET.parse('c:/myfile.xml')
root = tree.getroot()

for child in root.findall('Minwert'):
print (child.text)
Benutzeravatar
__blackjack__
User
Beiträge: 13068
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@yuyu: Ja lassen sie sich. Lies doch einfach mal die Dokumentation zum `ElementTree`-Modul. Die fängt mit einem Tutorial an.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@yuyu: findall() unterstützt auch XPath-Syntax. Das ist für komplexere Abfragen meist besser geeignet, anstatt den Baum händisch zu durchlaufen. Im schon erwähnten Tutorial findest du die entsprechende Stelle hier: https://docs.python.org/3/library/xml.e ... th-support
yuyu
User
Beiträge: 10
Registriert: Mittwoch 12. Dezember 2018, 21:07

Tutorial durchgegangen.

Folgendes Beispiel funktioniert am kleinen Beispiel, aber nicht am größerern Beispiel.

Code: Alles auswählen

import xml.etree.ElementTree as ET
tree = ET.parse('c:/input.xml')

for elem in tree.iter():
    if elem.tag == 'Name':
        print (elem.text)
    if elem.tag == 'Age':
        print (elem.text)
Ich habe ein Root mit vielen Unterstrukturen.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

yuyu hat geschrieben: Samstag 15. Dezember 2018, 18:17 Tutorial durchgegangen.
Wohl eher überflogen als durchgegangen in der kurzen Zeit...

Wie schon erwähnt sind komplexe Abfragen mit der XPath-Syntax möglich:

Code: Alles auswählen

# Alle Namen auf allen Ebenen
names = root.findall('.//Name')

# Alle Altersangaben auf allen Ebenen
ages = root.findall('.//Age')
Im Gegensatz zu deinem Ansatz werden hierbei nicht nur die direkten Kind-Elemente angeschaut, sondern auch die tiefer verschachtelten.

Findet sich beim Link aus meinem vorherigen Post in der Tabelle (Beschreibung in der vierten Spalte). Sofern man da mal reinschauen möchte...
yuyu
User
Beiträge: 10
Registriert: Mittwoch 12. Dezember 2018, 21:07

Hallo,
mit:

Code: Alles auswählen

import xml.etree.ElementTree as ET
tree = ET.parse('c:/data.xml')
root = tree.getroot()

names = root.findall('.//Name')
print (names)
bekomme ich und nicht den text vom tag:
[<Element 'Name' at 0x009116F0>, <Element 'Name' at 0x009117B0>, <Element 'Name' at 0x00911870>]

Wenn ich das gleiche auf das eigentliche XML loslasse, dann sehe ich nur zwei Zeiche in der Ausgabe: [ ]
Antworten