I'm trying to create an XML file so that it has the following skeleton, preferably using the xml.etree modules in Python 2.7:
<?xml version="1.0"?>
<foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" thing1="this" thing2="that">
....
<somedata bar="1">
<moredata whatsit="42"></moredata>
</somedata>
....
</foo>
It's the "foo ...." line that vexes me. I tried using nsmap for bringing in xsi and xsd, but that led to a "cannot serialize" error.
I could construct or otherwise hack that line's text to be exactly as I want it, but I'd like to learn to do this programmatically using xml.etree (pulling in an external library is not preferable in this situation).
I'd think this is a common pattern but I'm just not finding it anywhere for Python and etree.
When you use multiple namespaces in an XML document, you can define one namespace as the default namespace to create a cleaner looking document. The default namespace is declared in the root element and applies to all unqualified elements in the document. Default namespaces apply to elements only, not to attributes.
The xml. etree. ElementTree module implements a simple and efficient API for parsing and creating XML data. Changed in version 3.3: This module will use a fast implementation whenever available.
As defined by the W3C Namespaces in XML Recommendation , an XML namespace is a collection of XML elements and attributes identified by an Internationalized Resource Identifier (IRI); this collection is often referred to as an XML "vocabulary."
If the prefixes are used in the document; you could call register_namespace()
to add them:
import sys
import xml.etree.ElementTree as etree
xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsd = "http://www.w3.org/2001/XMLSchema"
ns = {"xmlns:xsi": xsi, "xmlns:xsd": xsd}
for attr, uri in ns.items():
etree.register_namespace(attr.split(":")[1], uri)
foo = etree.Element("foo",
dict(thing1="this", thing2="that")) # put `**ns))` if xsi, xsd are unused
somedata = etree.SubElement(foo, "somedata", dict(bar="1"))
etree.SubElement(somedata, "moredata",
{"whatsit": "42", etree.QName(xsi, "type"): etree.QName(xsd, "string")})
etree.ElementTree(foo).write(sys.stdout, xml_declaration=True)
Otherwise, you could set the attributes explicitly (ns
dict) if you need it.
import xml.etree.ElementTree as et
foo = et.Element('foo', **{'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance'}, **{'xmlns:xsd': 'http://www.w3.org/2001/XMLSchema'})
somedata = et.SubElement(foo, 'somedata', bar='1')
moredata = et.SubElement(somedata, 'moredata', whatsit='42')
tree = et.ElementTree(foo)
tree.write('file.xml')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With