I want to use ElementTree to modify an XML-document and to keep it comparable, I want to have the same namespace-prefixes in the new file as in the old file.
However, the default_namespace=
argument of ET.tostring
and ET.write
causes errors with even simple documents.
Here is an example:
Example test.xml
file:
<?xml version="1.0"?>
<test xmlns="http://www.example.com/blabla/">
<item name="first" />
</test>
Test:
Python 3.11.5 (tags/v3.11.5:cce6ba9, Aug 24 2023, 14:38:34) [MSC v.1936 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import xml.etree.ElementTree as ET
>>> xml = ET.parse("test.xml")
>>> ET.tostring(xml, default_namespace="http://www.example.com/blabla/")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python311\Lib\xml\etree\ElementTree.py", line 1098, in tostring
ElementTree(element).write(stream, encoding,
File "C:\Python311\Lib\xml\etree\ElementTree.py", line 741, in write
qnames, namespaces = _namespaces(self._root, default_namespace)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Python311\Lib\xml\etree\ElementTree.py", line 856, in _namespaces
add_qname(key)
File "C:\Python311\Lib\xml\etree\ElementTree.py", line 833, in add_qname
raise ValueError(
ValueError: cannot use non-qualified names with default_namespace option
Is there any way to write the XML-File the way it is shown?
You have to use register_namespace()
:
See also the xml.etree.ElementTree documentation.
import xml.etree.ElementTree as ET
xml_ = """\
<?xml version="1.0"?>
<test xmlns="http://www.example.com/blabla/">
<item name="first" />
</test>"""
root = ET.fromstring(xml_)
ET.register_namespace('','http://www.example.com/blabla/')
tree = ET.ElementTree(root)
ET.indent(tree, space=' ')
tree.write("out.xml", xml_declaration=True, encoding='utf-8')
ET.dump(tree)
# Alternative to dump
# print(ET.tostring(root).decode())
Output:
<test xmlns="http://www.example.com/blabla/">
<item name="first" />
</test>