SAX XML parse und modify

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.
Antworten
frank_b
User
Beiträge: 7
Registriert: Mittwoch 4. Mai 2011, 11:07

...
Zuletzt geändert von frank_b am Mittwoch 25. Mai 2011, 19:38, insgesamt 1-mal geändert.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Also zunächst einmal wird mir nicht deutlich, wo Dein Problem jetzt liegt! Du solltest irgend wie eine Frage formulieren, was Du als Hilfe erwartest...

Zudem frage ich mich: Muss es denn wirklich SAX sein? Hast Du es mal mit lxml probiert? Das kann dank Iteratoren auch mit großen Dateien umgehen!
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
deets

Ich hab mal etwas begonnen:

Code: Alles auswählen


import xml.sax


test = """
<root>
<zone>
<seg xml:id='001' a='62' b='90' c='75' d='92'>aba</seg>
<seg xml:id='002' a='62' b='90' c='75' d='92'>abc</seg>
<seg xml:id='003' a='62' b='90' c='75' d='92'>abd</seg>
</zone>
<text>
<div>
<seg sameAs='#001'>aba</seg>
<seg sameAs='#002'>abc</seg>
<seg sameAs='#003'>abd</seg>
</div>
</text>
</root>
"""

class my_handler(xml.sax.ContentHandler):
    def __init__(self):
        self.id_mappings = {}
        self.in_zone = False
        self.in_text = False
        

    def startDocument(self):
        pass

    def endDocument(self):
        pass

    def startElement(self,name,attrs):
        print "startElement", name, attrs

        if name == "zone":
            assert not self.in_zone
            self.in_zone = True
        if name == "seg" and self.in_zone:
            self.id_mappings[attrs["xml:id"]] = dict((k, v) for k, v in attrs.items())
                             

    def endElement(self,name):
        if name == "zone":
            assert self.in_zone
            self.in_zone = False

    def startElementNS(self,name,qname,attrs):
        print "startElementNS", name, qname, attrs


    def endElementNS(self,name,qname):
        print "end", name, qname

    def characters(self,data):
        print "characters", data

    def ignorableWhitespace(self):
        print "ignorableWhitespace"


h = my_handler()
xml.sax.parseString(test, h)
print h.id_mappings
von da aus sollte es eigentlich einfach sein.

Ein Problem hast du aber noch: SAX ist nett zum einlesen von XML. Zum generieren weniger. Ich weiss, dass es in Java dazu moeglichkeiten gibt, sozusagen Filter zu bauen. Das geht in Python wahrscheinlich auch irgendwie, aber wie genau - kA.

Warum ich das erwaehne: einfach selbst XML zu schreiben wird ziemlich wahrscheinlich in die Hose gehen, weil du dann all die escaping-regeln usw verletzt. Da solltest du also nochmal nachschauen, wie das geht.
frank_b
User
Beiträge: 7
Registriert: Mittwoch 4. Mai 2011, 11:07

...
Zuletzt geändert von frank_b am Mittwoch 25. Mai 2011, 19:39, insgesamt 1-mal geändert.
frank_b
User
Beiträge: 7
Registriert: Mittwoch 4. Mai 2011, 11:07

...
Zuletzt geändert von frank_b am Mittwoch 25. Mai 2011, 19:39, insgesamt 1-mal geändert.
deets

Zum ersten: das was du ausgibst, ist nicht "nur" eine text-datei, sondern eben XML. Und das sollte man proper generieren.

Aber davon unabhaengig: das Programm zeigt doch recht deutlich, wie man auf die XML-tags zugreift, adaptiere das doch bitte selbst auf die Ausgabe des zweiten Bereiches. Wenn du einfach eine Loesung willst, dann musst du einfach Geld bezahlen ;)
frank_b
User
Beiträge: 7
Registriert: Mittwoch 4. Mai 2011, 11:07

...
Zuletzt geändert von frank_b am Mittwoch 25. Mai 2011, 19:39, insgesamt 1-mal geändert.
deets

Es baut ein dictionary auf, dessen Schluessel die ID ist, und dessen Wert ein dictionary der anderen Attribute ist.
frank_b
User
Beiträge: 7
Registriert: Mittwoch 4. Mai 2011, 11:07

...
Zuletzt geändert von frank_b am Mittwoch 25. Mai 2011, 19:40, insgesamt 1-mal geändert.
deets

Also machst du doch das, was in die Hose gehen wird aller Wahrscheinlichkeit nach: selbst "XML" ausgeben. Mit string-OPs. Das wird dir ziemlich sicher auf die Fuesse fallen, wenn du Daten hast, die escaped werden muessen.

Wie dem auch sei. Konkret auf deine Frage bezogen: alles, was du tun musst, ist dein "f" als Attribut auf deinem Handler immer wieder neu anzulegen, wenn du auf ein entsprechendes Tag stoesst. Und vorher natuerlich ein vorher da befindliches File schliessen. Mehr nicht.
Antworten