Modificar espacios de nombres en un documento xml dado con lxml

Tengo un documento xml que se ve así:

  ...    ...    

Todo lo que quiero hacer es cambiar http://someurl/Oldschema a http://someurl/Newschema y http://someurl/Oldframework a http://someurl/Newframework y dejar el documento restante sin cambios. Con algunas ideas de este hilo lxml: agregar espacio de nombres al archivo de entrada , intenté lo siguiente:

 def fix_nsmap(nsmap, tag): """update the old nsmap-dict with the new schema-urls. Example: fix_nsmap({"framework": "http://someurl/Oldframework", None: "http://someurl/Oldschema"}) == {"framework": "http://someurl/Newframework", None: "http://someurl/Newschema"}""" ... from lxml import etree root = etree.parse(XMLFILE).getroot() root_tag = root.tag.split("}")[1] nsmap = fix_nsmap(root.nsmap) new_root = etree.Element(root_tag, nsmap=nsmap) new_root[:] = root[:] # ... fix xsi:schemaLocation return etree.tostring(new_root, pretty_print=True, encoding="UTF-8", xml_declaration=True) 

Esto produce los ‘atributos’ correctos en la etiqueta raíz, pero falla completamente para el rest del documento:

   ...    ...   

¿Qué hay de malo con mi enfoque? ¿Hay alguna otra manera de cambiar los espacios de nombres? Tal vez podría usar xslt?

¡Gracias!

Denis

Todo lo que quiero hacer es cambiar http://someurl/Oldschema a http://someurl/Newschema y http://someurl/Oldframework a http://someurl/Newframework y dejar el documento restante sin cambios.

Haría una simple operación textual de búsqueda y reemplazo. Es mucho más fácil que jugar con los nodos XML. Me gusta esto:

 with open("input.xml", "r") as infile, open("output.xml", "w") as outfile: data = infile.read() data = data.replace("http://someurl/Oldschema", "http://someurl/Newschema") data = data.replace("http://someurl/Oldframework", "http://someurl/Newframework") outfile.write(data) 

La otra pregunta que te inspiró es acerca de agregar un nuevo espacio de nombres (y mantener los antiguos). Pero estás intentando modificar las declaraciones de espacio de nombres existentes. Crear un nuevo elemento raíz y copiar los nodos secundarios no funciona en este caso.

Esta línea:

 new_root[:] = root[:] 

convierte los elementos secundarios del elemento raíz original en elementos secundarios del nuevo elemento raíz. Pero estos nodos secundarios todavía están asociados con los espacios de nombres antiguos. Así que tienen que ser modificados / recreados también. Supongo que podría ser posible encontrar una manera razonable de hacerlo, pero no creo que lo necesites. La búsqueda y reemplazo textuales es suficiente, IMHO.