XML Leere Zeilen erscheinen beim Einfügen eines neuen Knotens

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
malzbier
User
Beiträge: 13
Registriert: Mittwoch 25. November 2020, 09:42

Hallo zusammen,

ich will bei einem bestehenden XML Dokument am Wurzelknoten ein neues Element einfügen.
Der Code macht auch eigentlich was er soll, nur bekomme ich, wenn ich die Funktion ein zweites mal aufrufe
ein paar leere Zeilen und je öfter ich die Funktion aufrufe, desto mehr leere Zeilen erscheinen.
Der letzte Knoten sieht auch immer "normal" aus und jetzt weiter oben man kommt, dest mehr leere Zeilen gibt es.
Ich habe mal im Internet so geschaut, aber die Lösungen die ich dort gefunden habe, haben nicht wirklich geklappt :cry:
Hier der Code für Wurzelknoten machen und neuen Knoten einfügen:

def createRoot(self, nameFile, nameRoot):
dir = os.path.dirname(__file__)
dir = dir + "/Games/" + nameFile
data = ET.Element(nameRoot)
xmlstr = minidom.parseString(ET.tostring(data)).toprettyxml(indent=" ", newl='\r', encoding="utf-8")
myfile = open(dir, 'wb')
myfile.write(xmlstr)
myfile.close()

def addNode(self, nameFile, player, action, time):
dir = os.path.dirname(__file__)
dir = dir + "/Games/" + nameFile
tree = ET.parse(dir)
root = tree.getroot()

playerNode = ET.SubElement(root, 'player')
playerNode.set("time", time)
actionNode = ET.SubElement(playerNode, player)
actionNode.text = action
xmlstr = minidom.parseString(ET.tostring(root)).toprettyxml(indent=" ", newl='\r', encoding="utf-8")

myfile = open(dir, 'wb')
myfile.write(xmlstr)
myfile.close()


Danke schon mal fürs durchlesen :)

VG
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@malzbier: Ich würde statt `minidom` noch zusätzlich zu verwenden gleich `lxml` verwenden. Da gibt es neben ”pretty printing” auch gleich noch das praktische `builder`-Modul mit `E`.

Warum stecken diese beiden *Funktionen* in einer Klasse? Und warum haben hält sich das alles nicht an die Python-Namenskonventionen?

Der `my`-Präfix ist sinnlos. Und `nameFile` sollte wohl eher `filename` heissen. Ausser Du bist Yoda. `dir()` ist der Name einer eingebauten Funktion.

Ein `bytes`-Objekt `*str` zu nennen ist verwirrend. Man muss auch nicht jedes Zwischenergebnis an irgendeinen Namen binden.

Dateien sollte man mit ``with`` verwenden. Beziehungsweise kann man sich das öffnen der Dateien komplett sparen wenn man `pathlib.Path` verwenden würde. Und das sollte man, denn Pfadteile bastelt man nicht mit ``+`` zusammen.

Die beiden Funktionen enthalten auch sehr viel gemeinsamen Code.

"\r" als Zeilenende?

Ich hoffe mal `root_name` und `player` nehmen nur Werte aus einer festen Menge an, andernfalls ist der XML-Entwurf kaputt, weil Elementnamen nicht variabel sondern fest sind.

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python3
from pathlib import Path

from lxml import etree
from lxml.builder import E

GAMES_FOLDER_PATH = Path(__file__).absolute().parent / "Games"


def save_xml_document(path, root):
    path.write_bytes(etree.tostring(root, encoding="utf-8", pretty_print=True))


def create_root(filename, root_name):
    save_xml_document(GAMES_FOLDER_PATH / filename, etree.Element(root_name))


def add_node(filename, player, action, time):
    file_path = GAMES_FOLDER_PATH / filename
    root = etree.parse(file_path).getroot()
    root.append(E("player", E(player, action), time=time))
    save_xml_document(file_path, root)
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
malzbier
User
Beiträge: 13
Registriert: Mittwoch 25. November 2020, 09:42

Hi Blackjack,

vielen Dank für die schnelle Antwort.
Habe deinen Code mal getestet. Der hat bei Windows Path etwas gemeckert, aber das habe ich gefixt.
Wenn ich add_node aber mehrmals aufrufe, klappt das pretty_print nur beim ersten Einfügen des Knotens, danach wird alles in eine Zeile geschrieben. Ich werde mir mal etwas lxml anschauen. Danke für die Antwort
VG
Antworten