Werte in einer XML Datei ändern

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
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

Dienstag 28. Oktober 2008, 13:18

Hallo zusammen,

ich hab eine XML Datei und möchte nun diverse Werte von irgendwelchen Attributen (oder wie man das in einer XML nennt) ändern.
Also z.B:

Code: Alles auswählen

<test name = "Test1">
   <datensatz ID = "1">
       <daten 
              Vorname="hans"
              Nachname = "mustermann"/>
   </datensatz>
</test>
Jo und da jetzt eben zum Beispiel den Vorname ändern.
Weis überhaupt nicht, wie ich das Problem am besten angehe, kann mir jemand auf die Sprünge helfen?
BlackJack

Dienstag 28. Oktober 2008, 13:45

Mit `lxml` ginge das zum Beispiel so:

Code: Alles auswählen

from lxml import etree


def main():
    source = '''\
<test name = "Test1">
    <datensatz ID = "1">
        <daten
               Vorname="hans"
               Nachname = "mustermann"/>
    </datensatz>
</test>'''

    doc = etree.fromstring(source)
    for data in doc.xpath('/test/datensatz/daten'):
        data.set('Vorname', '((%s))' % data.get('Vorname'))
    etree.dump(doc)
Das Programm ersetzt alle `Vorname`-Attribute von `daten`-Knoten durch den Vornamen in doppelten runden Klammern eingefasst.
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

Dienstag 28. Oktober 2008, 13:54

Hallo,

danke erstmal.
Ist lxml einfach ein Modul, welches man in seiner Python Installation hinzufügen muss oder wie/woher bekommt man das lxml?
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

Dienstag 28. Oktober 2008, 14:11

Hab jetzt eine lxml-2.0.3 Installations-exe für mein python24 gefunden und drauf gemacht.
Wenn ich jetzt Dein Code ausführe, kommt folgende Fehlermeldung:

Traceback (most recent call last):
File "C:\Documents and Settings\f38372\Desktop\test.py", line 76, in ?
doc = etree.fromstring(source)
File "lxml.etree.pyx", line 2377, in lxml.etree.fromstring
File "parser.pxi", line 1354, in lxml.etree._parseMemoryDocument
File "parser.pxi", line 1243, in lxml.etree._parseDoc
File "parser.pxi", line 795, in lxml.etree._BaseParser._parseDoc
File "parser.pxi", line 452, in lxml.etree._ParserContext._handleParseResultDoc
File "parser.pxi", line 536, in lxml.etree._handleParseResult
File "parser.pxi", line 478, in lxml.etree._raiseParseError
lxml.etree.XMLSyntaxError: Start tag expected, 'Script terminated.
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

Dienstag 28. Oktober 2008, 14:21

Ok, da bin ich wieder :)
Also folgender Code wird zumindest fehlerfrei ausgeführt:

Code: Alles auswählen

from lxml import etree 


def main(): 
    source = ''' 
<test name = "Test1"> 
    <datensatz ID = "1"> 
        <daten 
               Vorname="hans" 
               Nachname = "mustermann"/> 
    </datensatz> 
</test>''' 

    doc = etree.fromstring(source) 
    for data in doc.xpath('/test/datensatz/daten'): 
        data.set('Vorname', '((%s))' % data.get('Vorname')) 
    etree.dump(doc)
Also dieses Slash \ musste am Anfang weg.
Aber wie ist das jetzt genau, ich hab ja normal eine XML Datei, also test.xml.
Muss ich die dann einfach mit

Code: Alles auswählen

open(str("test.xml",'w')
mit Schreibrechten öffnen und er editiert dann direkt in der Datei?

Also:

Code: Alles auswählen

source = open(str("test.xml",'w')
??
BlackJack

Dienstag 28. Oktober 2008, 15:01

Die beiden letzten Zeilen sind nicht einmal gültiges Python, da werden mehr Klammern geöffnet als geschlossen.

Und das funktioniert natürlich so nicht. Die `fromstring()`-Funktion möchte, wie der Name schon vermuten lässt, eine Zeichenkette und keine Datei. Um Dateien zu parsen, gibt's auch Funktionen in dem Modul.

Auch die verändern keine Dateien sondern lesen die XML-Datei ein und parsen sie zu Baumstruktur aus Objekten. Zum serialisieren dieser Struktur zu einer Zeichenkette oder in eine Datei gibt's auch wieder Funktionen und Methoden. Schau doch einfach mal in die Dokumentation.
blubber
User
Beiträge: 123
Registriert: Montag 19. März 2007, 09:08

Dienstag 28. Oktober 2008, 15:09

Naja mir gehts nur um Prinzip, also wie der Ablauf prinzipiell ist.

Muss ich also eine XML erst parsen, dieses dann entsprechend editieren und das ganze wieder in eine neue XML schreiben oder wie?
Ich dachte halt, es ist möglich, dass man eine XML File öffnet und direkt eine bestimmte Stelle in der Datei ändern kann?

Also ich hab bereits einen Parser für eine XML Datei mit diesem minidom geschrieben und der packt die ganze XML dann auch in eine Dictionary, nur dachte ich, dass ich unabhängig davon meine XML Datei bearbeiten kann...geht das also nicht?
BlackJack

Dienstag 28. Oktober 2008, 16:00

Nein das geht natürlich nicht. Man kann in Textdateien nicht einfach so auf der Platte etwas entfernen oder einfügen, oder ändern wenn sich die Länge dadurch ändert. Dadurch würden sich ja alle Bytes danach verschieben und das müsste man explizit tun. Beim Einfügen sogar *vor* dem Einfügen. Und dann ist da immer die Gefahr, dass währenddessen etwas passiert, z.B. ein Programmabsturz, und dann hat man irgend wo Müll in der Datei stehen.
Antworten