¿Cómo encontrar elementos XML a través de XPath en Python de una manera independiente del espacio de nombres?

Dado que tuve este molesto problema por segunda vez, pensé que preguntar sería útil.

A veces tengo que obtener elementos de documentos XML, pero las formas de hacerlo son incómodas.

Me gustaría conocer una biblioteca de Python que haga lo que quiero, una forma elegante de formular mis XPaths, una forma de registrar los espacios de nombres en prefijos automáticamente o una preferencia oculta en las implementaciones XML incorporadas o en lxml para eliminar espacios de nombres por completo. La aclaración sigue a menos que ya sepa lo que quiero

Ejemplo-doc:

<root xmlns="http://really-long-namespace.uri"
  xmlns:other="http://with-ambivalent.end/#">
    <other:elem/>
</root>
Que puedo hace

The ElementTree API es el único integrado (que sé) que proporciona consultas XPath. Pero requiere que use "UNames". Esto se ve así:/{http://really-long-namespace.uri}root/{http://with-ambivalent.end/#}elem

Como puede ver, estos son bastante detallados. Puedo acortarlos haciendo lo siguiente:

default_ns = "http://really-long-namespace.uri"
other_ns   = "http://with-ambivalent.end/#"
doc.find("/{{{0}}}root/{{{1}}}elem".format(default_ns, other_ns))

Pero esto es tanto {{{feo}}} como frágil, ya quehttp…end/#http…end#http…end/http…end, ¿y quién soy yo para saber qué variante se utilizará?

Además, lxml admite prefijos de espacio de nombres, pero no utiliza los del documento ni proporciona una forma automatizada de tratar con los espacios de nombres predeterminados. Todavía tendría que obtener un elemento de cada espacio de nombres para recuperarlo del documento. Los atributos del espacio de nombres no se conservan, por lo que tampoco hay forma de recuperarlos automáticamente de ellos.

También hay una forma independiente de espacio de nombres para las consultas XPath, pero es a la vez verbosa / fea y no está disponible en la implementación integrada:/*[local-name() = 'root']/*[local-name() = 'elem']

Lo que quiero hace

Quiero encontrar una biblioteca, una opción o una función genérica de transformación de XPath para lograr los ejemplos anteriores escribiendo un poco más que lo siguiente ...

Unnamespaced:/root/elem Prefijos de espacio de nombres del documento:/root/other:elem

… Más quizás algunas declaraciones de que realmente quiero usar los prefijos del documento o quitar los espacios de nombres.

Aclaración adicional: aunque mi caso de uso actual es tan simple como eso, tendré que usar otros más complejos en el futuro.

¡Gracias por leer

Resuelto

El usuario samplebias dirigió mi atención a py-dom-xpath; Exactamente lo que estaba buscando. Mi código actual ahora se ve así:

#parse the document into a DOM tree
rdf_tree = xml.dom.minidom.parse("install.rdf")
#read the default namespace and prefix from the root node
context = xpath.XPathContext(rdf_tree)

name    = context.findvalue("//em:id", rdf_tree)
version = context.findvalue("//em:version", rdf_tree)

#<Description/> inherits the default RDF namespace
resource_nodes = context.find("//Description/following-sibling::*", rdf_tree)

De acuerdo con el documento, simple, compatible con el espacio de nombres; Perfecto

Respuestas a la pregunta(2)

Su respuesta a la pregunta