Los espacios de nombres en XML son una forma de evitar conflictos de nombres al definir etiquetas personalizadas. En Python, puedes usar la biblioteca xml.etree.ElementTree para trabajar con XML. Sin embargo, trabajar con espacios de nombres puede ser un poco complicado porque necesitas definirlos explícitamente. Este artículo te guiará a través del proceso de cómo añadir un nuevo espacio de nombres a un XML.

Qué es un espacio de nombres en XML?

Un espacio de nombres en XML es una forma de categorizar etiquetas y atributos para evitar conflictos de nombres. Los espacios de nombres son útiles cuando tienes etiquetas personalizadas que podrían entrar en conflicto con las etiquetas estándar de XML. Un espacio de nombres se define con un prefijo y una URI (Uniform Resource Identifier) que suele tomar la forma de una URL.

Añadiendo un nuevo espacio de nombres en Python

Para añadir un nuevo espacio de nombres en Python, primero debes registrar el espacio de nombres usando el método register_namespace() de la biblioteca xml.etree.ElementTree. Este método toma dos argumentos: el prefijo del espacio de nombres y la URI del espacio de nombres. Por ejemplo, puedes registrar un espacio de nombres con el prefijo ‘xsi’ y la URI ‘http://www.w3.org/2001/XMLSchema-instance’ de la siguiente manera:

import xml.etree.ElementTree as ET

ET.register_namespace('xsi', "http://www.w3.org/2001/XMLSchema-instance")

Después de registrar el espacio de nombres, puedes usarlo en tu árbol XML. Por ejemplo, puedes crear un nuevo elemento con el espacio de nombres registrado de la siguiente manera:

root = ET.Element('{http://www.w3.org/2001/XMLSchema-instance}Author'

En este caso, {http://www.w3.org/2001/XMLSchema-instance} es el espacio de nombres que acabamos de registrar

Añadiendo un nuevo espacio de nombres a un XML existente

Si tienes un árbol XML existente y quieres añadir un nuevo espacio de nombres, puedes hacerlo de la siguiente manera:

def addNSToRoot(tree, id, ns):
    root = tree.getroot()

    # add ns
    nsmap = root.nsmap
    if id not in nsmap:
        nsmap[id] = ns

    # create new root tag
    rootNS = etree.Element(root.tag, nsmap=nsmap, **root.attrib)

    # add childrens
    for e in root.iterchildren():
        rootNS.append(e)
    return rootNS

En este caso, la función addNSToRoot toma tres argumentos: el árbol XML, el ID del espacio de nombres y el espacio de nombres en sí. La función obtiene la raíz del árbol XML, verifica si el ID del espacio de nombres ya existe en el mapa de espacios de nombres (nsmap) de la raíz. Si no existe, añade el ID y su correspondiente espacio de nombres al mapa de espacios de nombres. Luego, crea un nuevo elemento raíz con el mismo nombre que la antigua raíz y el nuevo mapa de espacios de nombres. Copia todos los atributos de la antigua raíz al nuevo elemento. Finalmente, añade todos los hijos de la antigua raíz al nuevo elemento raíz y devuelve el nuevo elemento raíz

Ejemplo de uso:

tree = etree.parse('file.xml')
root = addNSToRoot(tree, 'sc', 'http://schemas.microsoft.com/3dmanufacturing/securecontent/2019/04')