How do I parse and write XML using Python's ElementTree without moving namespaces around?
<p>Our project gets from upstream XML of this form:</p>

<pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;configuration&gt;
  &lt;runtime&gt;
    &lt;assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"&gt;
      &lt;dependentAssembly&gt;
        &lt;assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" /&gt;
        &lt;bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="7.0.0.0" /&gt;
      &lt;/dependentAssembly&gt;
    &lt;/assemblyBinding&gt;
  &lt;/runtime&gt;
  &lt;appSettings&gt;
    &lt;add key="foo" value="default"&gt;
    ...
  &lt;/appSettings&gt;
&lt;/configuration&gt;
</code></pre>

<p>It then reads/parses this XML using ElementTree, and then for every app setting matching a certain key ("foo"), it writes a new value that <em>it</em> knows about that the upstream process doesn't ( in this case key "foo" should have the value "bar").</p>

<p>The <em>downstream</em> process consuming the filtered XML is, aaahhhh... <em>fragile</em>. It expects to receive the XML in <em>exactly</em> the form above.</p>

<p>If I parse this XML without registering a namespace, then ElementTree mangles my tree like this on input:</p>

<pre><code>&lt;configuration xmlns:ns0="urn:schemas-microsoft-com:asm.v1"&gt;
  &lt;runtime&gt;
  &lt;ns0:assemblyBinding&gt;
    &lt;ns0:dependentAssembly&gt;
      &lt;ns0:assemblyIdentity culture="neutral" name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" /&gt;
      &lt;ns0:bindingRedirect newVersion="7.0.0.0" oldVersion="0.0.0.0-6.0.0.0" /&gt;
    &lt;/ns0:dependentAssembly&gt;
  &lt;/ns0:assemblyBinding&gt;
 &lt;/runtime&gt;
 &lt;appSettings&gt;
    &lt;add key="foo" value="default"&gt;
    ...
 &lt;/appSettings&gt;
&lt;/configuration&gt;
</code></pre>

<p>The downstream process can't handle this, because it's no clever enough to realize that, semantically, this is the same thing. So, I decide to register the namespace I know the upstream process will provide as a default namespace to avoid the prefixes showing up everywhere, and now I get this:</p>

<pre><code>&lt;configuration xmlns="urn:schemas-microsoft-com:asm.v1"&gt;
 &lt;runtime&gt;
  &lt;assemblyBinding&gt;
    &lt;dependentAssembly&gt;
      &lt;assemblyIdentity culture="neutral" name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" /&gt;
      &lt;bindingRedirect newVersion="7.0.0.0" oldVersion="0.0.0.0-6.0.0.0" /&gt;
    &lt;/dependentAssembly&gt;
  &lt;/assemblyBinding&gt;
 &lt;/runtime&gt;
 &lt;appSettings&gt;
    &lt;add key="foo" value="default"&gt;
    ...
 &lt;/appSettings&gt;
&lt;/configuration&gt;
</code></pre>

<p>I don't know much about XML, but this also the downstream component cries about, and it seems to me that doesn't now mean this default <code>xmlns</code> now apply to <em>all</em> included elements inside <code>&lt;configuration&gt;</code>, whereas before it <em>only</em> applied to the <code>&lt;assemblyBinding&gt;</code> element?</p>

<p>Is there anyway, <em>using ElementTree</em>, to handle this namespace so that I can take in the upstream's XML, set <code>foo</code>'s value, and then pass that on downstream, without moving the namespace around, and leaving it exactly as I found it?</p>

<ul>
<li><p>I could use an lxml-based solution, which seems to handle this, <em>however</em>, lxml has a dependency on C which the downstream component would really like not to have to support: a pure Python solution is preferable.</p></li>
<li><p>I could read the document as HTML which would ignore the namespace attribute, let me manipulate the value I want, and then pass on the document; <em>however</em>, I have yet to find a Python parser that doesn't downcase all the element names, and my downstream component requires the casing on all element names to be preserved.</p></li>
<li><p>I could resort to string parsing and regular expressions. I would rather not write my own parser.</p></li>
</ul>

<p>The only advice I could find so far about namespace handling in ElementTree suggests the "register a default namespace to avoid prefixes" approach, which I assumed would be suitable, but ElementTree then insists on moving the <code>xmlns</code> declaration up to the root node upon dumping.</p>

<p>I could also be clever build up a string that dumps the tree out in stages and in exactly the right order to put the <code>xmlns</code> declaration back on the "right node", but that strikes me, also, as pretty darned fragile.</p>

<p>Has anyone managed to get past a problem like this?</p>