XML-Datei bearbeiten

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.
__marcus__
User
Beiträge: 92
Registriert: Mittwoch 10. September 2008, 22:10
Wohnort: Hamburg

XML-Datei bearbeiten

Beitragvon __marcus__ » Freitag 17. Oktober 2008, 11:39

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

Beitragvon BlackJack » Freitag 17. Oktober 2008, 12:43

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.
__marcus__
User
Beiträge: 92
Registriert: Mittwoch 10. September 2008, 22:10
Wohnort: Hamburg

Beitragvon __marcus__ » Freitag 17. Oktober 2008, 12:49

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.
ronson2
User
Beiträge: 1
Registriert: Dienstag 11. November 2008, 09:52

Beitragvon ronson2 » Dienstag 11. November 2008, 10:25

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?!
Benutzeravatar
cofi
Moderator
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Beitragvon cofi » Dienstag 11. November 2008, 13:24

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)
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Beitragvon Y0Gi » Dienstag 11. November 2008, 16:31

`<node />` und `<node></node>` sind dennoch gleichwertig.

Wer ist online?

Mitglieder in diesem Forum: Google [Bot]