¿Cómo analizo y escribo XML usando ElementTree de Python sin mover espacios de nombres?

Nuestro proyecto obtiene XML ascendente de esta forma:

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

Luego lee / analiza este XML usando ElementTree, y luego para cada configuración de aplicación que coincide con una determinada clave ("foo"), escribe un nuevo valor queeso sabe que el proceso ascendente no (en este caso, la clave "foo" debería tener el valor "bar").

losrío abajo proceso que consume el XML filtrado es, aaahhhh ...frágil. Espera recibir el XML enexactamente El formulario de arriba.

Si analizo este XML sin registrar un espacio de nombres, ElementTree destruye mi árbol de esta manera en la entrada:

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

El proceso posterior no puede manejar esto, porque no es lo suficientemente inteligente como para darse cuenta de que, semánticamente, esto es lo mismo. Entonces, decido registrar el espacio de nombres que sé que el proceso ascendente proporcionará como un espacio de nombres predeterminado para evitar que aparezcan los prefijos en todas partes, y ahora obtengo esto:

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

No sé mucho acerca de XML, pero este también el componente aguas abajo llora, y me parece que ahora no significa esto por defectoxmlns ahora aplique atodas elementos incluidos dentro<configuration>, mientras que antessolamente aplicado a la<assemblyBinding> ¿elemento?

Hay alguna manera,usando ElementTree, para manejar este espacio de nombres para que pueda tomar el XML del flujo ascendente, establezcafoo¿Cuál es el valor, y luego pasarlo corriente abajo, sin mover el espacio de nombres y dejarlo exactamente como lo encontré?

Podría usar una solución basada en lxml, que parece manejar esto,sin embargo, lxml tiene una dependencia de C que el componente descendente realmente no querría tener que soportar: es preferible una solución pura de Python.

Podría leer el documento como HTML, lo que ignoraría el atributo del espacio de nombres, me permitiría manipular el valor que quiero y luego transmitir el documento;sin embargo, Todavía tengo que encontrar un analizador de Python que no reduzca todos los nombres de elementos, y mi componente posterior requiere que se preserven las mayúsculas y minúsculas en todos los nombres de elementos.

Podría recurrir al análisis de cadenas y expresiones regulares. Prefiero no escribir mi propio analizador.

El único consejo que pude encontrar hasta ahora sobre el manejo del espacio de nombres en ElementTree sugiere el enfoque "registrar un espacio de nombres predeterminado para evitar prefijos", que supuse que sería adecuado, pero ElementTree luego insiste en mover elxmlns declaración hasta el nodo raíz al volcar.

También podría ser inteligente construir una cadena que arroje el árbol por etapas y exactamente en el orden correcto para poner elxmlns declaración de nuevo en el "nodo correcto", pero eso también me parece muy frágil.

¿Alguien ha logrado superar un problema como este?

Respuestas a la pregunta(0)

Su respuesta a la pregunta