Brauche Hilfe bei komplexer XML-Struktur
Verfasst: Donnerstag 4. August 2011, 19:26
Schönen guten Abend allerseits,
ich studiere Computerlinguistik und für ein Software-Projekt möchte ich mit einem morphologisch und syntaktisch annotierten Korpus arbeiten. Dieses Korpus liegt in XML vor. Die Struktur für einen Beispielsatz sieht folgendermaßen aus:
Ich möchte dieses XML nun in eine Python-Datenstruktur umwandeln, um damit leichter zu arbeiten. Als Output hab ich mir ungefähr folgendes vorgestellt:
Mein Problem ist jetzt, dass ich genau daran bisher gescheitert bin. Ich weiß, dass ich hier eine rekursive Herangehensweise wählen muss, aber mein Gehirn tut sich leider äußerst schwer damit.
Ich hab das XML schon mittels xml.etree.ElementTree geparst und ich weiß auch, wie ich auf die einzelnen Elemente zugreifen kann. Aber wie ich welche rekursiven Funktionen definieren muss, um mein Ziel zu erreichen, erschließt sich mir leider nicht so recht.
Grundsätzlich müsste man ja folgendes tun:
1. Identifiziere das root-Element im graph-Tag (hier 's5_504').
2. Suche nach demjenigen Nonterminal, dessen ID diesem root-Element entspricht.
3. Extrahiere die syntaktische Kategorie dieses Nonterminals (hier 'S') und initialisiere damit den neuen Baum.
4. Gehe rekursiv jeden Edge des Nonterminals entlang und finde mittels der idref-Tags die weiteren Subknoten.
5. Mache das so lange bis Du zu einem Terminal-Symbol kommst.
Also, in der Theorie ist mir das alles klar, aber mein Hirn kommt trotz vieler Versuche den ganzen Tag hindurch einfach nicht zu einer funktionierenden Lösung, da ich Schwierigkeiten mit rekursivem Denken habe. Ich habe bisher nur Erfahrung mit iterativer Programmierung.
Daher wende ich mich an euch: Könnt ihr mir einen Denkanstoß, ein Stück Code oder ähnlich Hilfreiches geben? Eine komplette Lösung kann ich von euch nicht verlangen, aber zumindest ein Grundgerüst, mit dem ich weitermachen kann, wäre sehr hilfreich für mich. Gibt es vielleicht sogar eine externe Bibliothek, die mir dabei helfen kann?
Herzlichen Dank im Voraus!
Beste Grüße und schönen Abend noch,
Dingels
ich studiere Computerlinguistik und für ein Software-Projekt möchte ich mit einem morphologisch und syntaktisch annotierten Korpus arbeiten. Dieses Korpus liegt in XML vor. Die Struktur für einen Beispielsatz sieht folgendermaßen aus:
Code: Alles auswählen
<s id="s5">
<graph root="s5_504">
<terminals>
<t id="s5_1" word="Die" pos="ART" morph="Def.Fem.Nom.Sg"/>
<t id="s5_2" word="Tagung" pos="NN" morph="Fem.Nom.Sg.*"/>
<t id="s5_3" word="hat" pos="VVFIN" morph="3.Sg.Pres.Ind"/>
<t id="s5_4" word="mehr" pos="PIAT" morph="--"/>
<t id="s5_5" word="Teilnehmer" pos="NN" morph="Masc.Akk.Pl.*"/>
<t id="s5_6" word="als" pos="KOKOM" morph="--"/>
<t id="s5_7" word="je" pos="ADV" morph="--"/>
<t id="s5_8" word="zuvor" pos="ADV" morph="--"/>
</terminals>
<nonterminals>
<nt id="s5_500" cat="NP">
<edge label="NK" idref="s5_1"/>
<edge label="NK" idref="s5_2"/>
</nt>
<nt id="s5_501" cat="AVP">
<edge label="CM" idref="s5_6"/>
<edge label="MO" idref="s5_7"/>
<edge label="HD" idref="s5_8"/>
</nt>
<nt id="s5_502" cat="AP">
<edge label="HD" idref="s5_4"/>
<edge label="CC" idref="s5_501"/>
</nt>
<nt id="s5_503" cat="NP">
<edge label="NK" idref="s5_502"/>
<edge label="NK" idref="s5_5"/>
</nt>
<nt id="s5_504" cat="S">
<edge label="SB" idref="s5_500"/>
<edge label="HD" idref="s5_3"/>
<edge label="OA" idref="s5_503"/>
</nt>
</nonterminals>
</graph>
</s>Code: Alles auswählen
[ 'S',
[ ('SB', 'NP'),
[ ('NK', 'ART'), 'Die' ],
[ ('NK', 'NN'), 'Tagung' ]
],
[ ('HD', 'VVFIN'), 'hat' ],
[ ('OA', 'NP'),
[ ('NK', 'AP'),
[ ('HD', 'PIAT'), 'mehr' ],
[ ('CC', 'AVP'),
[ ('CM', 'KOKOM'), 'als' ],
[ ('MO', 'ADV'), 'je' ],
[ ('HD', 'ADV'), 'zuvor' ]
]
],
[ ('NK', 'NN'), 'Teilnehmer' ]
]
]Grundsätzlich müsste man ja folgendes tun:
1. Identifiziere das root-Element im graph-Tag (hier 's5_504').
2. Suche nach demjenigen Nonterminal, dessen ID diesem root-Element entspricht.
3. Extrahiere die syntaktische Kategorie dieses Nonterminals (hier 'S') und initialisiere damit den neuen Baum.
4. Gehe rekursiv jeden Edge des Nonterminals entlang und finde mittels der idref-Tags die weiteren Subknoten.
5. Mache das so lange bis Du zu einem Terminal-Symbol kommst.
Also, in der Theorie ist mir das alles klar, aber mein Hirn kommt trotz vieler Versuche den ganzen Tag hindurch einfach nicht zu einer funktionierenden Lösung, da ich Schwierigkeiten mit rekursivem Denken habe. Ich habe bisher nur Erfahrung mit iterativer Programmierung.
Daher wende ich mich an euch: Könnt ihr mir einen Denkanstoß, ein Stück Code oder ähnlich Hilfreiches geben? Eine komplette Lösung kann ich von euch nicht verlangen, aber zumindest ein Grundgerüst, mit dem ich weitermachen kann, wäre sehr hilfreich für mich. Gibt es vielleicht sogar eine externe Bibliothek, die mir dabei helfen kann?
Herzlichen Dank im Voraus!
Beste Grüße und schönen Abend noch,
Dingels