Como encontrar elementos XML via XPath em Python de forma independente de namespac

Desde que tive esse problema irritante pela 2ª vez, achei que pedir ajudari

s vezes, tenho que obter elementos de documentos XML, mas as maneiras de fazer isso são estranha

Gostaria de conhecer uma biblioteca python que faça o que eu quero, uma maneira elegante de formular meus XPaths, uma maneira de registrar os espaços para nome em prefixos automaticamente ou uma preferência oculta nas implementações XML incorporadas ou em lxml para remover completamente os espaços para nome. Esclarecimentos a seguir, a menos que você já saiba o que eu quero:)

Exemplo de documento:

<root xmlns="http://really-long-namespace.uri"
  xmlns:other="http://with-ambivalent.end/#">
    <other:elem/>
</root>
O que eu posso faze

A API ElementTree é a única (eu sei) incorporada que fornece consultas XPath. Mas isso exige que eu use “UNames”. Parece assim:/{http://really-long-namespace.uri}root/{http://with-ambivalent.end/#}elem

Como você pode ver, estes são bastante detalhados. Posso reduzi-los fazendo o seguinte:

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

Mas isso é {{{feio}}} e frágil, poishttp…end/#http…end#http…end/http…end e quem sou eu para saber qual variante será usada?

Além disso, o lxml suporta prefixos de namespace, mas não utiliza os do documento, nem fornece uma maneira automatizada de lidar com namespaces padrão. Eu ainda precisaria obter um elemento de cada espaço para nome para recuperá-lo do documento. Os atributos do espaço para nome não são preservados, portanto, também não há como recuperá-los automaticament

Existe também uma maneira independente de namespace de consultas XPath, mas é detalhada / feia e indisponível na implementação interna:/*[local-name() = 'root']/*[local-name() = 'elem']

O que eu quero faze

Eu quero encontrar uma biblioteca, opção ou função genérica de transformação XPath para obter os exemplos acima digitando pouco mais do que o seguinte…

Unnamespaced:/root/elem Prefixos de espaço para nome do documento:/root/other:elem

… Além de algumas declarações de que eu realmente quero usar os prefixos do documento ou remover os espaços para nom

Mais esclarecimentos: embora meu caso de uso atual seja simples assim, terei que usar casos mais complexos no futur

Obrigado pela leitura!

Resolvido

As samplebias de usuários direcionaram minha atenção para py-dom-xpath; Exatamente o que eu estava procurando. Meu código atual agora fica assim:

#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)

Consistente com o documento, simples, com reconhecimento de espaço para nome; perfeito

questionAnswers(2)

yourAnswerToTheQuestion