library example etree dict create python xml namespaces nunit elementtree

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



xml python 3 (0)

Nuestro proyecto se obtiene de XML 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>

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

El proceso descendente que consume el XML filtrado es, aaahhhh ... frágil . Espera recibir el XML exactamente en el formulario de arriba.

Si analizo este XML sin registrar un espacio de nombre, ElementTree transforma mi árbol de la siguiente 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 indirecto no puede manejar esto, porque no es lo suficientemente inteligente como para darse cuenta de que, semánticamente, esto es lo mismo. Por lo tanto, decido registrar el espacio de nombres que sé que el proceso en sentido ascendente proporcionará como espacio de nombre predeterminado para evitar que los prefijos aparezcan en todas partes, y ahora entiendo 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 sobre XML, pero esto también el componente downstream llora, y me parece que ahora no significa que estos xmlns predeterminados ahora se aplican a todos los elementos incluidos dentro de <configuration> , mientras que antes solo se aplicaba al <assemblyBinding> elemento?

¿Hay alguna forma, usando ElementTree , para manejar este espacio de nombres para que yo pueda tomar el XML de la fuente, establecer el valor de foo 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 en C, que el componente downstream realmente no desea soportar: una solución pura de Python es preferible.

  • Pude leer el documento como HTML que ignoraría el atributo de espacio de nombres, permítanme manipular el valor que quiero y luego pasar el documento; sin embargo , todavía tengo que encontrar un analizador de Python que no descarte todos los nombres de los elementos, y mi componente en sentido descendente requiere que se guarde el revestimiento de todos los nombres de los elementos.

  • Podría recurrir a análisis de cadenas y expresiones regulares. Preferiría 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 los prefijos", que asumí que sería adecuado, pero ElementTree insiste en mover la declaración xmlns al nodo raíz al momento del vertido.

También podría ser inteligente construir una cadena que descargue el árbol en etapas y en el orden correcto para volver a poner la declaración xmlns en el "nodo derecho", pero eso también me parece bastante frágil.

¿Alguien ha logrado superar un problema como este?