aus XML-Datei Daten ausgelesen - nun neue reinschreiben

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.
BlackJack

Montag 21. Juli 2008, 15:12

Bitte die Schleife vereinfachen. Das ist Python und nicht C, Pascal, oder eine andere Sprache wo man für so etwas einen Index braucht.

Code: Alles auswählen

for x, y in punkt_liste:
     point = etree.SubElement(points, 'point', x='%d' % x, y='%d' % y)
Daniela
User
Beiträge: 73
Registriert: Donnerstag 19. Juni 2008, 07:32

Montag 21. Juli 2008, 15:16

Na dann werd ich das machen.

Nur ich hatte es so schon ein paar mal im Forum gesehen und dachte, dass es passen würde.

Und wie kann ich jetzt die Ausgabe so hinbekommen, dass alles vernünftig verschachtelt ist, ohne dass alles in eine Zeile geschrieben wird. Also so dass eine lesbare XML-Struktur entsteht?
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

Montag 21. Juli 2008, 15:32

Daniela hat geschrieben:Und wie kann ich jetzt die Ausgabe so hinbekommen, dass alles vernünftig verschachtelt ist, ohne dass alles in eine Zeile geschrieben wird. Also so dass eine lesbare XML-Struktur entsteht?
Die Frage hatte ich auch schonmal gestellt ;)

http://www.python-forum.de/topic-11945.html
Daniela
User
Beiträge: 73
Registriert: Donnerstag 19. Juni 2008, 07:32

Montag 21. Juli 2008, 15:35

Danke für den hinweis
Daniela
User
Beiträge: 73
Registriert: Donnerstag 19. Juni 2008, 07:32

Dienstag 22. Juli 2008, 09:21

Ich muss nochmal kurz stören.

Bei elementtree gibt es ja eigentlich eine Funktion namens "Comment", nur wenn ich jetzt diese nutzen will, um einen Kommentar zu verfassen für meine XML-Datei, wird der Kommentar aber gar nicht in die Datei geschrieben.

Muss man da noch irgendwas besonderes beachten? Bisher hab ich das so geschrieben:

Code: Alles auswählen

kommentar = etree.Comment("DOCTYPE roadmap SYSTEM \"roadmap.dtd\"")
Ohne doppelte Anführungsstriche kommt ein Fehler, mit einfachen Apostrophen wird das auch nichts. Der Kommentar soll gleich in der 2. Zeile stehen, gleich hinter der "Versions und Kodierungs-Zeile", also diese proceeding instruction.
Ich hab mir auch schon diesen Beitrag durchgelesen, aber ich will mir ja keine Liste vorher erstellen, sondern gleich beim Schreiben der Datei einen Kommentar mit einfügen.

Danke schonmal

LG

Daniela
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Dienstag 22. Juli 2008, 12:25

Das der Kommentar nicht auftaucht ist ja nicht verwunderlich, denn du hast ihn ja auch nicht zum Tree hinzugefügt; der Kommentar ist also "freifliegend" - er weiß ja nicht mal zu welchem Baum er gehören sollte.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Daniela
User
Beiträge: 73
Registriert: Donnerstag 19. Juni 2008, 07:32

Dienstag 22. Juli 2008, 13:05

Klingt logisch, nur irgendwie weiß ich im Moment grad nicht, wo ich das anhängen soll.

Code: Alles auswählen

doc = open('datei.rm', 'rw')
tree = etree.parse(doc) # einlesen der vorhandenen XML-Datei
root = tree.getroot() # Bestimmung des Wurzelelements

stations = tree.getroot().find("stations") # erster Knoten wird ausgelesen

kommentar = etree.Comment("DOCTYPE roadmap SYSTEM \"roadmap.dtd\"") # wo muss der rangehängt werden?
...
tree = etree.ElementTree(root)
tree.write('datei.rm', encoding='UTF-8')
Irgendwie häng ich grad.

Daniela
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

Dienstag 22. Juli 2008, 13:51

Ich wüsste nur diese Lösung:

Code: Alles auswählen

In [16]: r = ET.Element("root")

In [17]: k = ET.Comment("Ich bin der Kommentar!")

In [18]: r.insert(0, k)

In [19]: ET.tostring(r)
Out[19]: '<root><!-- Ich bin der Kommentar! --></root>'
Daniela
User
Beiträge: 73
Registriert: Donnerstag 19. Juni 2008, 07:32

Dienstag 22. Juli 2008, 14:38

Danke dafür, es funktioniert.

wenn ich jetzt (noch) einen Docstring einfügen will, nach dem Muster

Code: Alles auswählen

<!DOCTYPE bla SYSTEM "keks.dtd">
würde ich das so machen:

Code: Alles auswählen

dockommentar = etree.XMLTreeBuilder.doctype('bla', 0, "keks.dtd")
Aber hier bekomme ich folgendes dann zurück:

Code: Alles auswählen

TypeError: unbound method doctype() must be called with XMLTreeBuilder instance as first argument (got str instance instead)
Wird der Docstring anders aufgerufen, bzw. die Klammern anders gefüllt? Ich hab mich an das gehalten, was in der API steht. Nur mit der "0" war ich mir nicht sicher. Eigentlich brauch ich die auch nicht.

Daniela
Daniela
User
Beiträge: 73
Registriert: Donnerstag 19. Juni 2008, 07:32

Mittwoch 23. Juli 2008, 15:21

Das mit dem Kommentar einfügen funktioniert ja soweit, nur dummerweise hatte ich übersehen, dass in das was ich da einfügen will kein Kommentar ist, sondern "Doctype-Deklaration".

im Elementtree-Modul gibt es ja die XML-TreeBuilder Objekte und mit diesem scheint man eigene Doctypes erstellen zu können, nur stellt sich für mich hier die Frage wie.
Denn die allgemeine Syntax sieht ja folgendes vor:

Code: Alles auswählen

doctype(name, pubid, system)
    #Handles a doctype declaration. name is the doctype name. pubid is the public identifier. system is the system identifier. 
Nur ich muss in meiner Datei nur einen Namen und das System angeben, ohne die "pubid".
Ich hab hier auch im Forum schon gelesen, dass solche Konstrukte "per Hand" eingefügt werden sollen/sollten. Nur kann ich mir nicht wirklich vorstellen, dass das so gut sein soll.

Gibt es irgendwie die Möglichkeit die Zeile entweder gleich aus der bestehenden Datei mit auszulesen, und dann in eine neue Datei mit reinzuschreiben, oder aber so in die neu zuschreibende Datei einfügen, dass es hinter der Kodierungszeile ist, aber vor der Wurzel des XML-Baums?

Danke schonmal für eure Hinweise

Daniela
Daniela
User
Beiträge: 73
Registriert: Donnerstag 19. Juni 2008, 07:32

Donnerstag 24. Juli 2008, 15:19

So ich hab mich jetzt mal daran versucht, das zu befolgen, was Y0Gi (vor einer Weile) geschrieben hat zu befolgen:
Y0Gi hat geschrieben:Mit ET kannst du einfach ein neues `Element` anlegen und das als Root verwenden, indem du einfach `SubElement`e dranhängst. Über das Root-Element wandelst du abschließend das Dokument in einen String um (mit der Funktion `tostring`)
Hab ich gemacht. mein komplettes XML-dokument ist nun in einem String

Code: Alles auswählen

wurzel = etree.tostring(root)
Y0Gi hat geschrieben:und kannst dann über normale String-Konkatenation den gewünschten Header davor setzen.
String-Konkatenation ist doch eigentlich nur das Verknüpfen 2er Strings mit einem "+"-Zeichen, oder???
Ich hab aber auch noch die Methode ``concat`` im Modul ``Operator`` gefunden, welche ja das gleiche Ergebniss liefert. Oder bin ich jetzt auf dem Holzweg.
Jedenfalls durch diese Verknüpfung (entweder +-Zeichen, oder conat-Methode) ist nun der Header mit entsprechender DOCTYPE-Anweisung/Deklaration in einem String gespeichert.

Code: Alles auswählen

zsgf = header + baum
Wie kriege ich jetzt diesen (langen) String in eine Datei geschrieben/gespeichert?



Sorry übrigends für mein Dreifach-Posting, aber ich arbeite mich eben langsam an die Lösung ran.

Für Hinweise oder Vorschläge wäre ich sehr dankbar.

Daniela
DasIch
User
Beiträge: 2452
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Donnerstag 24. Juli 2008, 16:15

Daniela hat geschrieben:

Code: Alles auswählen

dockommentar = etree.XMLTreeBuilder.doctype('bla', 0, "keks.dtd")
Aber hier bekomme ich folgendes dann zurück:

Code: Alles auswählen

TypeError: unbound method doctype() must be called with XMLTreeBuilder instance as first argument (got str instance instead)
Lies noch einmal die Fehlermeldung und dann mach mal folgendes:

Code: Alles auswählen

print etree.XMLTreeBuilder
print etree.XMLTreeBuilder()
Fällt dir etwas auf?
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Donnerstag 24. Juli 2008, 18:42

Daniela hat geschrieben:
Y0Gi hat geschrieben:und kannst dann über normale String-Konkatenation den gewünschten Header davor setzen.
String-Konkatenation ist doch eigentlich nur das Verknüpfen 2er Strings mit einem "+"-Zeichen, oder???
Ich hab aber auch noch die Methode ``concat`` im Modul ``Operator`` gefunden, welche ja das gleiche Ergebniss liefert. Oder bin ich jetzt auf dem Holzweg.
Jein. Die Funktionen die in ``operator`` definiert sind, sind eigentlich nicht dafür gedacht direkt aufgerufen zu werden, dafür gibt es ja die normalen Operatoren. Sie sind vielmehr dazu gedacht in partielle Funktionen oder als Funktionen höherer Ordnung verwendet zu werden; sie direkt zu verwenden geht ist aber unnötig kompliziert.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Daniela
User
Beiträge: 73
Registriert: Donnerstag 19. Juni 2008, 07:32

Freitag 25. Juli 2008, 07:58

DasIch hat geschrieben:Lies noch einmal die Fehlermeldung und dann mach mal folgendes:

Code: Alles auswählen

print etree.XMLTreeBuilder
print etree.XMLTreeBuilder()
Fällt dir etwas auf?
Ja, ich hab nie mit der Instanz gearbeitet. :oops:

Was ich aber trotzdem bei der Deklarierung von doctype nicht verstehe, ist dieser "public identifier". Besteht dieser einfach aus einer Zahl, Zeichenkette, oder sonst was? Was muss man angeben, wenn man ihn eigentlich nicht haben will/braucht? Irgendwas muss man ja angeben, sonst kommt folgendes zurück:

Code: Alles auswählen

dockommentar = etree.XMLTreeBuilder().doctype('bla', "keks.dtd") 
TypeError: doctype() takes exactly 4 arguments (3 given)
Das noch ein Argument benötigt wird, ist mir wenn ich das lese auch klar, aber was ist, wenn ich es in dem letztlichen Ergebniss (in der XML-Datei) nicht benötige?

Bisher hab ich es so geschrieben:

Code: Alles auswählen

dockommentar = etree.XMLTreeBuilder().doctype('bla', "public", "keks.dtd")
Wie wird jetzt diese Zeile in die Datei eingefügt, VOR dem Wurzelelement, aber NACH der Kodierungszeile?
Denn nach dem Schema von Zap funktioniert es nicht.

Code: Alles auswählen

dockommentar = etree.XMLTreeBuilder().doctype('bla','public', "keks.dtd") 
etree.insert(0, dockommentar)
etree.tostring(root)
Da wird dann gesagt:

Code: Alles auswählen

AttributeError: 'module' object has no attribute 'insert'
Und wie dann, ich meine wie bekomme ich jetzt diesen docstring in die XML rein, und dann noch an die richtige Stelle?

@Leonidas

gut zu wissen. Danke für den Hinweis


Daniela
Antworten