Seite 1 von 1

XML String Parsen mit xml.dom.minidom

Verfasst: Freitag 18. Februar 2011, 14:50
von TTS
Hi zusammen

Ich bin am verzweifeln. Ich bin an einem Python Projekt und komme einfach nicht weiter und mein Chef ist in nem Meeting und ich sollte das so schnell wie möglich erledigt haben.
Und zwar geht es darum automatisierte testScripts mit unittest zu schreiben.

Nun soll ich einen xml String auswerten und in ein 2d array zu schreiben. Das ganze muss mit der xml bibliothek passieren.

Ich habe einen XML String, der folgende form hat, nur etwas länger:

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8" ?>

<response>

<operation name="get" path="/unit-15/status/outputcircuittable">

  <execution status="success" />

  <OutputCircuitTable>

    <OutputCircuitTableRow>

      <OutputCircuit>tpo-1</OutputCircuit>

      <AppOutputSignal>cmd-1</AppOutputSignal>

      <IsCmdAlarmGenerated>false</IsCmdAlarmGenerated>

    </OutputCircuitTableRow>

    <OutputCircuitTableRow>

      <OutputCircuit>tpo-2</OutputCircuit>

      <AppOutputSignal>cmd-2</AppOutputSignal>

      <IsCmdAlarmGenerated>false</IsCmdAlarmGenerated>

    </OutputCircuitTableRow>

  </OutputCircuitTable>

</operation>

</response>
nun sollten die Daten in den outputCircuits, AppOutputSignal und IsCmdAlarmGenerated in ein 2d-Array geschrieben werden. Nur habe ich keine Ahnung wie ich das anstelle.

Könnt Ihr mir sagen wie ich den Wert der childNodes von OutputCircuitTableRow herauslösen kann?

Bisher bin ich so weit (Ich kann nun schon auf die 3 gewünschten Nodes zugreifen):

Code: Alles auswählen

xml = xml.dom.minidom.parseString(xmlString)
nodeResponse = xml.childNodes[0]
nodeOperation = nodeResponse.childNodes[1]
nodeTable = nodeOperation.childNode[3]
nodeTableRow = nodeTable.childNodes[1]
for node in nodeTableRow.childNodes:
    #Hier sollten dann die 3 childNodes von der <OutputCircuitTableRow> in ein array geschrieben werden
Könnt Ihr mir erklären wie ich den Wert zwischen den <> und </> herausbekomme?
evtl. ein Beispiel mit print oder in einer Variable speichern.

Danke für eure Hilfe

Re: XML String Parsen mit xml.dom.minidom

Verfasst: Freitag 18. Februar 2011, 19:46
von BlackJack
@TTS: Als erstes würde ich die Finger von `minidom` lassen. Mit der `ElementTree`-API gibt es einen IMHO schöneren und einfacheren Ansatz dazu in der Standardbibliothek.

Mit "2d array" meinst Du wahrscheinlich verschachtelte Listen. Wenn man bei Python von Arrays spricht, sind normalerweise nicht Listen gemeint, sondern `numpy`-Arrays, oder in selteneren Fällen auch das `array`-Modul aus der Standardbibliothek.

Auf XML-Knoten sollte man nur in Ausnahmefällen über Indizes zugreifen. Es ist unverständlicher als die Tag-Namen zu zu verwenden und unflexibel, weil sich die Struktur der Daten dann nicht verändern darf. Insbesondere weil man über Namensräume beliebige andere XML-Elemente in Dokumente einbetten darf, ist Code der sich auf absolute Positionen von Elementen in Form von Indizes verlässt, nicht besonders robust.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from xml.etree import ElementTree as etree


def main():
    def parse_row(node):
        return [node.find(n).text for n
                in ['OutputCircuit', 'AppOutputSignal', 'IsCmdAlarmGenerated']]
    
    doc = etree.parse('test.xml')
    table_node = doc.find('.//OutputCircuitTable')
    result = map(parse_row, table_node.getiterator('OutputCircuitTableRow'))
    print result


if __name__ == '__main__':
    main()

Re: XML String Parsen mit xml.dom.minidom

Verfasst: Montag 21. Februar 2011, 08:37
von TTS
[quote="BlackJack"]@TTS: Als erstes würde ich die Finger von `minidom` lassen. Mit der `ElementTree`-API gibt es einen IMHO schöneren und einfacheren Ansatz dazu in der Standardbibliothek.

Code: Alles auswählen

# -*- coding: utf-8 -*-
    doc = etree.parse('test.xml')
    table_node = doc.find('.//OutputCircuitTable')
    result = map(parse_row, table_node.getiterator('OutputCircuitTableRow'))
    print result
Danke BlackJack für deine Hilfe. Jedoch verlang die funktion etree.parse ein xml-File, doch den angegebenen xml-string erhalte ich direkt über eine Funktion von einem Gerät. Das heisst es wird nicht ein xmlFile erstellt sondern ist nur in einem string gespeichert. Und etree enthält keine Funktion wie z.B. minidom parseString.

oder ist es doch igendwie möglich statt einem File einen string zu parsen?

Re: XML String Parsen mit xml.dom.minidom

Verfasst: Montag 21. Februar 2011, 08:42
von BlackJack
@TTS: Ja das ist möglich. Such einfach die passende Funktion in der Dokumentation. :-)

Re: XML String Parsen mit xml.dom.minidom

Verfasst: Montag 21. Februar 2011, 08:45
von TTS
Vielen Dank mit der Funktion .fromString() erhalte ich genau das was ich brauche :D