Die Aufgabe ist ganz einfach: ich möchte eine in.xml einlesen, dort ein Element hinzufügen und als out.xml speichern.
Code: Alles auswählen
def get_root():
filename = 'in.xml'
ns = dict([node for _, node in ET.iterparse(filename, events=['start-ns'])])
tree = ET.parse(filename)
root = tree.getroot()
for key in ns.keys():
ET.register_namespace(key, ns[key])
return root, ns, tree
Code: Alles auswählen
def writeXML(root, ns, tree):
prettify(root)
tree.write('out.xml', xml_declaration=True, encoding='UTF-8', method='xml')
return
Code: Alles auswählen
<?xml version='1.0' encoding='UTF-8'?>
<gml:FeatureCollection
xmlns:okstra="http://www.okstra.de/okstra/2.022"
xmlns:okstra-basis="http://www.okstra.de/okstra/2.022/okstra-basis"
xmlns:okstra-typen="http://www.okstra.de/okstra/2.022/okstra-typen"
xmlns:gml="http://www.opengis.net/gml/3.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xlink="http://www.w3.org/1999/xlink"
xsi:schemaLocation="http://www.okstra.de/okstra/2.020 http://www.okstra.de/schema/2022/okstra.xsd"
gml:id="ID_666">
<gml:metaDataProperty>
<okstra-basis:OKSTRAMetaDaten>
<okstra-basis:timestamp>2025-07-16T10:45:28</okstra-basis:timestamp>
</okstra-basis:OKSTRAMetaDaten>
</gml:metaDataProperty>
<gml:featureMember>
<okstra:Testelement gml:id="Testelement_000001" />
</gml:featureMember>
</gml:FeatureCollection>
Code: Alles auswählen
<gml:FeatureCollection
xmlns:gml="http://www.opengis.net/gml/3.2"
xmlns:okstra="http://www.okstra.de/okstra/2.022"
xmlns:okstra-basis="http://www.okstra.de/okstra/2.022/okstra-basis"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.okstra.de/okstra/2.020 http://www.okstra.de/schema/2022/okstra.xsd"
gml:id="ID_666">
<gml:metaDataProperty>
<okstra-basis:OKSTRAMetaDaten>
<okstra-basis:timestamp>2025-07-16T10:45:28</okstra-basis:timestamp>
</okstra-basis:OKSTRAMetaDaten>
</gml:metaDataProperty>
<gml:featureMember>
<okstra:Testelement gml:id="Testelement_000001">
<okstra:Dokument Objektklasse="Dokument" xlink:href="#Dokument_2" />
</okstra:Testelement>
</gml:featureMember>
<gml:FeatureMember>
<okstra:Dokument gml:id="Dokument_2">
<okstra:Name>meinname</okstra:Name>
<okstra:zu_Testelement Objektklasse="Testelement" xlink:href="#Testelement_000001" />
</okstra:Dokument>
</gml:FeatureMember>
</gml:FeatureCollection>
Die Datei "out.xml" ist keine gültige XML und kann nicht mehr von einem Parser gelesen werden. Fehler ist, dass der Ausdruck "xlink:href" nicht interpretiert werden kann, da der zugehörige Namespace fehlt.
Wie man vielleicht sieht, sind in "in.xml" insgesamt 8 Namespaces definiert. In "out.xml" kommen aber nur 6 an. Meine Vermutung: Namespaces, die in der Datei "in.xml" zwar definiert sind, jedoch im Body nicht benutzt werden, werden bei bei der Funktion tree.write() "wegoptimiert" und kommen somit in "out.xml" nicht an.
Wenn ich nämlich z.B. in "in.xml" das Element <okstra-basis:OKSTRAMetaDaten> weglasse, kommt auch der zugehörige Namespace nicht in "out.xml" an.
Wenn das so ist, wie kann ich denn tree.write() dazu zwingen den vollen originalen Namespace zu schreiben? Oder ist das ein anderer bölder Fehler, hab ich nur irgendwo ein Komma falsch gesetzt? Ein nochmaliges Registrieren des kompletten Namespace eine Zeile vor tree.write() bringt nichts.
Grüße
I.H.