Seite 1 von 1

XML-Datei bearbeiten

Verfasst: Freitag 17. Oktober 2008, 11:39
von __marcus__

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from xml.dom import minidom

data = '''<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.5" generator="OpenStreetMap server">
  <bounds minlat="53.56382" minlon="9.98806" maxlat="53.56979" maxlon="9.99833"/>
<node id="254323278" lat="53.5639264" lon="9.9928837" user="FrankT" visible="true" timestamp="2008-03-27T19:31:52+00:00">
  <tag k="created_by" v="JOSM"/>
  <tag k="amenity" v="parking"/>
</node>
<node id="297307812" lat="53.5665602" lon="9.9885107" user="Divjo" visible="true" timestamp="2008-09-15T20:02:46+01:00"/>
<node id="300092980" lat="53.5649066" lon="9.9891504" user="Stephan Schildberg" visible="true" timestamp="2008-09-26T19:55:20+01:00"/>
<node id="283584342" lat="53.5643298" lon="9.994464" user="Zirbe" visible="true" timestamp="2008-08-05T11:22:30+01:00">
  <tag k="name" v="Fontenay"/>
  <tag k="highway" v="bus_stop"/>
</node>
<node id="21112777" lat="53.5664708" lon="9.9907035" user="Stephan Schildberg" visible="true" timestamp="2007-12-23T00:05:32+00:00">
  <tag k="created_by" v="JOSM"/>
</node>
</osm>'''

data = minidom.parseString(data)
nodes = data.getElementsByTagName('node')

for node in nodes:
	[node.removeChild(tag) for tag in node.getElementsByTagName('tag')]
		
data = data.toxml().split('\n')
for line in data:
	if '<' in line:
		print line
Ich hab da mal wieder n paar Fragen...

- Wenn ich aus den 'node' alle 'tag' entfernt habe, bekomme ich nicht <node ... />-Elemente sondern leere <node>...</node>. Ist aber glaube ich kein sauberes XML - ??? -, kann ich das ändern? (Ohne workaround...)
- Wenn ich statt dem in Zeilen 30-33 einfach print data.toxml() verwende, bekomme ich leere Zeilen angezeigt. Kann ich das verhindern?
- Gibt es auch eine Methode mit der ich die bearbeiteten Daten gleich wieder zurückschreiben kann. (Ich hab die nicht gefunden, kann mir aber nicht vorstellen, dass sie nicht da ist.)

Verfasst: Freitag 17. Oktober 2008, 12:43
von BlackJack
Du bekommst keine "leeren" `node`-Tags und "leere" Zeilen, da ist Text drin, nämlich Leerzeichen und Zeilenumbrüche. Das sind Daten, die nicht einfach so automatisch weg geworfen werden können, das muss man schon explizit machen. Und vielleicht besser die Textknoten im DOM und nicht Zeilen ohne '<' (!= Leerzeile!) in der serialisierten Form.

Verfasst: Freitag 17. Oktober 2008, 12:49
von __marcus__
BlackJack hat geschrieben:Du bekommst keine "leeren" `node`-Tags und "leere" Zeilen, da ist Text drin, nämlich Leerzeichen und Zeilenumbrüche. Das sind Daten, die nicht einfach so automatisch weg geworfen werden können, das muss man schon explizit machen. Und vielleicht besser die Textknoten im DOM und nicht Zeilen ohne '<' (!= Leerzeile!) in der serialisierten Form.
Das war der Hinweis, den ich brauchte. Danke.

Verfasst: Dienstag 11. November 2008, 10:25
von ronson2
Kann man mit minidom die xml auch ohne Leerzeichen und Zeilenumbrüche parsen? bzw. wie? Oder wie kann ich sie nach dem parsen löschen?

Problem:
Ähnlich wie oben parse die xml mit ...parse(), füge ein neues kind mit appendChild() hinzu und schreibe die xml mit writexml(datei, '\n', ' ').
(Benutze minidom)
Die Formatierung ist für das manuelle lesen!
Durch die Formatierung verschieben sich aber die schon vorhandenen Kinder immer weiter auseinander, je mehr ich hinzufüge.

So in etwa:
<x>


<child>


wert


</child>


<child>

wert

</child>

<child>
wert
</child>
</x>

Es gibt doch bestimmt eine leichte Lösung das zu umgehen?!

Verfasst: Dienstag 11. November 2008, 13:24
von cofi
Die leichte Lösung ist es lxml.etree zu verwenden.

Code: Alles auswählen

from lxml import etree
tree = etree.ElementTree("datei.name")
#Hier finden
#Änderungen statt
tree.write("datei.name", encoding="utf-8", pretty_print=True)

Verfasst: Dienstag 11. November 2008, 16:31
von Y0Gi
`<node />` und `<node></node>` sind dennoch gleichwertig.