Seite 1 von 1

SAX XML parse und modify

Verfasst: Mittwoch 4. Mai 2011, 11:27
von frank_b
...

Re: SAX XML parse und modify

Verfasst: Mittwoch 4. Mai 2011, 19:50
von Hyperion
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!

Re: SAX XML parse und modify

Verfasst: Mittwoch 4. Mai 2011, 23:34
von 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.

Re: SAX XML parse und modify

Verfasst: Donnerstag 5. Mai 2011, 12:15
von frank_b
...

Re: SAX XML parse und modify

Verfasst: Donnerstag 5. Mai 2011, 12:45
von frank_b
...

Re: SAX XML parse und modify

Verfasst: Donnerstag 5. Mai 2011, 13:13
von 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 ;)

Re: SAX XML parse und modify

Verfasst: Donnerstag 5. Mai 2011, 13:48
von frank_b
...

Re: SAX XML parse und modify

Verfasst: Donnerstag 5. Mai 2011, 15:48
von deets
Es baut ein dictionary auf, dessen Schluessel die ID ist, und dessen Wert ein dictionary der anderen Attribute ist.

Re: SAX XML parse und modify

Verfasst: Dienstag 10. Mai 2011, 20:33
von frank_b
...

Re: SAX XML parse und modify

Verfasst: Dienstag 10. Mai 2011, 20:43
von 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.