Pergunta

Estou tendo problemas usando o atributo Selector XPath em ElementTree, que eu deveria ser capaz de fazer de acordo com o Documentação

Aqui está um código de exemplo

XML

<root>
 <target name="1">
    <a></a>
    <b></b>
 </target>
 <target name="2">
    <a></a>
    <b></b>
 </target>
</root>

Python

def parse(document):
    root = et.parse(document)
    for target in root.findall("//target[@name='a']"):
        print target._children

Estou recebendo a seguinte exceção:

expected path separator ([)
Foi útil?

Solução

A sintaxe que você está tentando usar é novo no ElementTree 1,3 .

Tal versão é fornecido com o Python 2.7 ou superior. Se você tiver Python 2.6 ou menos você ainda tem ElementTree 1.2.6 ou menos.

Outras dicas

Existem vários problemas neste código.

  1. O Python buildin ElementTree (ET para o short) não tem qualquer apoio real XPATH; apenas um subconjunto limitado por exemplo, ele não suporta encontrar-da-raiz expressões como //target.

    Aviso: documentação menciona " // ", mas apenas para as crianças: Então uma expressão como .//target é válido; //... não é!

    Há uma implementação alternativa: lxml que é mais rica. É costuras que a documentação é usada, para o build-in de código. Que não corresponde / trabalho.

  2. O @name notação selecciona em XML atributos ; a expressão key=value dentro de um xml-tag.

    Assim que o nome de valor tem de ser 1 ou 2 para selecionar algo no documento dado. Ou, pode-se procurar alvos com uma criança elemento 'a' :. target[a] (sem @)

Para o documento dado, analisado com o build-in ElementTree (v1.3) para a raiz, o seguinte código está correto e funcionando:

  • root.findall(".//target") Localizar ambas as metas
  • root.findall(".//target/a") encontrar dois um elemento
  • root.findall(".//target[a]") isto encontra tanto elemento alvo novamente, já que ambos têm um um-elemento
  • root.findall(".//target[@name='1']") Encontrar apenas o início alvo. Note as aspas em torno de 1 são necessários; então um SyntaxError é levantada
  • root.findall(".//target[a][@name='1']") também válido; para encontrar esse alvo
  • root.findall(".//target[@name='1']/a") Encontra apenas um elemento-; ...
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top