Piet van Oostrum wrote:
jholg@gmx.de wrote:
nsmap={None: 'http://example.com', 'foo': 'http://example.com'} rootElem = etree.Element('Foo', {}, nsmap)
Note that this does not put Foo into the http://example.com NS. It creates an element Foo wit no namespace. The nsmap is rather a collection of known namespace prefixes in the context of an element.
But that means that the serialization:
<Foo xmlns="http://example.com"> Contents </Foo>
that etree.tostring produces is wrong.
Correct. This is actually an error case that we could catch at the API level: the new element has no namespace *and* the nsmap defines a default namespace, i.e. this should fail: el = etree.Element('thetag', nsmap={None : 'uri:some-namespace'}) We'd then need to make sure that you can write el = etree.Element('{}thetag', nsmap={None : 'uri:some-namespace'}) which would result in something like <ns0:thetag xmlns="uri:some-namespace" xmlns:ns0="" /> Similarly, adding a namespace-less subelement to a tree that defines a default namespace will not work 'as expected' (whatever a user may expect in doing that). In this case, we'd have to cut the default namespace definition by inserting a xmlns="" on the new element, so this case would not be an error. The same applies in the general case where you create a tree without namespaces and one that uses a default namespace, and then insert the namespace-less tree into the other one at some place. Another sick case: el1 = etree.fromstring( '<p:qualified xmlns:p="uri:myns"><nons/></p:qualified>') el2 = etree.Element("{uri:tns}thetag", nsmap={None: "uri:otherns"}) el2.append(el1) So it looks like we'd have to integrate something similar into the namespace fixing mechanism... Ugly, ugly... Stefan