Seite 1 von 1

XML mit mehreren Tables verarbeiten

Verfasst: Donnerstag 29. April 2021, 12:52
von KayJu
Hallo,
Wenn es hier falsch ist, habt bitte Nachsicht mit mir, ich bin neu in diesem Forum.

Ich habe ein Problem mit dem auslesen einer XML Datei.
Die Datei, welche ich verwenden möchte, besteht aus mehreren Tables, (6 Stück) in Table 3 ändert sich jedoch der Inhalt von der Anzahl her. Nun bin ich auf der Suche nach einer Möglichkeit, am besten aus der xml immer nur eine table zu importieren, und diese dann zu verarbeiten.

Hier ein Muster des Aufbaus mit 2 Tables:

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8"?>
<Table name="Namen">
<Data type="STRING" header="Name1"/>
<Data type="STRING" header="Name2"/>
<Data type="STRING" header="Name3"/>
<Data type="STRING" header="Name4"/>
<Data type="STRING" header="Name5"/>
<Row>
</Row>
<Row>
<Column value="Datensatz_Name1"/>
<Column value="Datensatz_Name2"/>
<Column value="Datensatz_Name3"/>
<Column value="Datensatz_Name4"/>
<Column value="Datensatz_Name5/>
<Table name="Farbe">
<Data type="STRING" header="Farbe1"/>
<Data type="STRING" header="Farbe2"/>
<Data type="STRING" header="Farbe3"/>
<Row>
</Row>
<Row>
<Column value="Rot"/>
<Column value="Gelb/>
<Column value="Gruen"/>
</Row>
</Table>
Mein bisheriger versuch:

Code: Alles auswählen

from xml.dom import minidom


xmldoc = minidom.parse('Test.xml')


itemlist = xmldoc.getElementsByTagName('Column') 

print(len(itemlist))


Name1 = itemlist[0].attributes['value'].value
print(Name1)

Name2 = itemlist[1].attributes['value'].value
print(Name2)
Auf diese Weise bekomme ich hard codiert alle Daten aus dieser einen xml eingelesen, da ich nach dem Inhalt der einzelnen columns suche... Allerdings bekomme ich so Probleme, wenn sich eine table in ihrer Anzahl der Datensätze verändert...
Daher mein Wunsch, zum Beispiel nur die 2. Tabelle "Farben" Einzulesen...

Habe da gerade eine ziemliche "Denkblockade"... vielleicht kann mir ja jemand helfen...
Dankeschön :-)

Re: XML mit mehreren Tables verarbeiten

Verfasst: Donnerstag 29. April 2021, 13:14
von Sirius3
Das was Du da zeigst, ist kaputtes XML. Das ist wenig hilfreich, wenn man nicht den Aufbau der XML-Datei kennt.

minidom verwendet man nicht, sondern ElementTree. Dann sucht man auch nicht nach allen Columns, sondern geht die Baumstruktur der XML-Datei durch.
Aber da Du ja deine XML-Datei nicht zeigst, kann man da nur raten: Du gehst die Table-Elemente durch, suchst von da nach Row-Elementen und nimmst dann deren Column-Elemente.
Column scheint so eigentlich sowas wie Cell zu sein. Wer hat denn das XML-Format erfunden?

Re: XML mit mehreren Tables verarbeiten

Verfasst: Donnerstag 29. April 2021, 15:58
von KayJu
Entschuldige bitte, habe es bisher erfolgreich geschafft mich vor der Arbeit mit XML "zu drücken" da ich das Format schrecklich finde...

Die komplette Originaldatei kann ich leider nicht teilen, da es sich um sensible Daten handelt. Ich habe hier die einzelnen Einträge mal durch xxx ersetzt. Sie sollte aber komplett sein.
Die Datei bekomme ich so zugeschickt und muss die dann auswerten und die darin enthaltenen Daten weiter verteilen auf ander API's.
Vielleicht hilft das ja mehr.

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8"?>
<Table name="xxxx">
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Row>
</Row>
<Row>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx "/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx "/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Table name="xxxx">
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Row>
</Row>
</Table>
<Table name="xxxx">
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Row>
</Row>
</Table>
<Table name="xxxx">
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Row>
</Row>
<Row>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
</Row>
</Table>
<Table name="xxxx">
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Row>
</Row>
</Table>
<Table name="xxxx">
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Row>
</Row>
<Row>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
</Row>
<Row>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
</Row>
<Row>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
</Row>
</Table>
</Row>
</Table>


Re: XML mit mehreren Tables verarbeiten

Verfasst: Donnerstag 29. April 2021, 16:17
von Sirius3
Es ist also so, dass ein Table in einer Row einer anderen Table vorkommen kann?
Nach welchen Kriterien sind denn die Tabellen ineinander verschachtelt?
Bleibt natürlich die allgemeine Aussage, dass Du den Baum durchlaufen mußt.
Wie soll denn die Ausgabe aussehen?

Re: XML mit mehreren Tables verarbeiten

Verfasst: Donnerstag 29. April 2021, 20:19
von KayJu
Am liebsten hätte ich so etwas in der Art:
Daten1 = "Column value"
sodass ich mit dem Wert der "Zelle" weiterarbeiten kann

Re: XML mit mehreren Tables verarbeiten

Verfasst: Donnerstag 29. April 2021, 20:37
von Sirius3
die Beschreibung ist für mich völlig unverständlich. Von welcher Zelle redest Du?

Re: XML mit mehreren Tables verarbeiten

Verfasst: Donnerstag 29. April 2021, 21:32
von KayJu
also ich verstehe die xml so:
Das was im "Data type="STRING" header="xxxx" ist die Bezeichung der Date, und was in der "row" darunter steht "Column value="xxxx" ist der Wert, den ich haben will...


Wenn ich mir mal diese Table als muster nehme:

Code: Alles auswählen

<Table name="xxxx">
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Data type="STRING" header="xxxx"/>
<Row>
</Row>
<Row>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
<Column value="xxxx"/>
</Row>
</Table>
habe ich ja 8 Header und 8 Values... die Values will ich haben...

(Entschuldige bitte, wenn ich mich etwas kompliziert ausdrücke, habe "Zelle" geagt, da ich hierbei eine "excel Tabelle" vor meinem Inneren Auge habe)

Re: XML mit mehreren Tables verarbeiten

Verfasst: Donnerstag 29. April 2021, 22:22
von __deets__
Das ist schon so richtig, passt nur nicht mit deinem Wunsch, Daten1 zu bekommen. Denn es ist eine Liste von Listen. Also

Code: Alles auswählen

[
["A", "B"],
[1, 2],
[3, 4],
]

Re: XML mit mehreren Tables verarbeiten

Verfasst: Freitag 30. April 2021, 08:49
von Sirius3
Um an die Daten der obersten Tabelle zu kommen, braucht es nur eine doppelte Schleife:

Code: Alles auswählen

import xml.etree.ElementTree as et

tree = et.ElementTree(file='xx.xml')
root = tree.getroot()
for row in root.findall('Row'):
    cells = [cell.attrib['value'] for cell in row.findall('Column')]
    print(cells)

Re: XML mit mehreren Tables verarbeiten

Verfasst: Freitag 30. April 2021, 10:10
von KayJu
Danke, in die Richtung hatte ich mich gestern Abend auch noch versucht. Die Idee mit der doppelten Schleife ist gut. Die Listenausgabe gefällt mir auch besser als minidom...

Irgendwie schaffe ich es aber nicht über die erste Table hinaus, die anderen zu finden.

Ist mein Gedankengang da jetzt richtig:
Ich würde eine "dreifache Schleife" bauen, als erstes nach "Table" suchen, und danach dann die rows und Cells?

Re: XML mit mehreren Tables verarbeiten

Verfasst: Freitag 30. April 2021, 10:15
von Sirius3
Ja, wenn Du die anderen Tabellen finden möchtest, brauchst Du drei Schleifen.

Re: XML mit mehreren Tables verarbeiten

Verfasst: Montag 3. Mai 2021, 10:46
von KayJu
Ich muss leider nochmal nerven...

Code: Alles auswählen

for table in root.findall('Table'):
    for row in table.findall('Row'):
        cells = [cell.attrib['value'] for cell in row.findall('Column')]
        print(cells)
Ist mein Denkansatz so richtig? Bzw. besser, was mache ich falsch, dass die Ausgabe mir nichts raus gibt?

bzw. irgendwie müsste ich dem ja auch die Indexnummer der Tabelle geben, welche ich gerade durchsuchen möchte.. Würde das so versuchen:

Code: Alles auswählen

for table in root.findall('Table'):
    for row in table[1].findall('Row'):
        cells = [cell.attrib['value'] for cell in row.findall('Column')]
        print(cells)
oder besser anders?

Re: XML mit mehreren Tables verarbeiten

Verfasst: Montag 3. Mai 2021, 11:00
von __blackjack__
@KayJu: Warum musst Du die Indexnummer der Tabelle angeben? `table` ist jeweils die Tabelle die gerade verarbeitet wird. Also wenn `root.findall("Table")` denn Ergebnisse hätte. Das sucht *im* `root` nach *direkten* <Table>-Kindknoten. Die gibt es aber nicht, deshalb wird auch nichts verarbeitet.

Re: XML mit mehreren Tables verarbeiten

Verfasst: Montag 3. Mai 2021, 11:12
von KayJu
Weil die XML ja mehrere Tables hat, und ich gerne Die Daten geziehlt aus einer Table ziehen möchte. wenn ich jetzt zum Beispiel aus Tabelle 3 Die Daten brauche, dass ich nicht in Tabelle 2 suche... Deshalb hätte ich jetzt über eine Indexierung nachgedacht...

Re: XML mit mehreren Tables verarbeiten

Verfasst: Montag 3. Mai 2021, 11:25
von Sirius3
Ein komplexes Problem löst man dadurch, dass man es in mehrere Schritte aufteilt. Den Teil, die Daten aus einer Table herauszulesen, hast Du schon, jetzt mußt Du Dich darauf konzentrieren, die das richtige Table-Element zu finden. In Deinem Beispiel-XML sind die Tables im zweiten Row-Element.