Question

Je ne parviens pas à utiliser l'attribut XPath Selector dans ElementTree, ce que je devrais pouvoir utiliser conformément à Documentation

Voici un exemple de code

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

Je reçois l'exception suivante:

expected path separator ([)
Était-ce utile?

La solution

La syntaxe que vous essayez d'utiliser est nouvelle dans ElementTree 1.3 .

Cette version est fournie avec Python 2.7 ou une version ultérieure. Si vous avez Python 2.6 ou moins, vous avez toujours ElementTree 1.2.6 ou moins.

Autres conseils

Il y a plusieurs problèmes dans ce code.

  1. La construction de Python ElementTree (ET en abrégé) n’a pas de réel support XPATH; par exemple, il ne prend pas en charge les expressions find-from-root telles que // target .

    Remarque: la documentation . mentionne " // ", mais uniquement pour les enfants: une expression comme .// la cible est valide; // ... n'est pas!

    Il existe une autre implémentation: lxml , qui est plus riche. C'est la documentation qui est utilisée pour le code intégré. Cela ne correspond pas à / travail.

  2. La notation @name sélectionne les attributs xml- ; l'expression key = value dans une balise xml.

    Donc, ce nom-valeur doit être 1 ou 2 pour sélectionner quelque chose dans le document donné. Vous pouvez également rechercher des cibles avec un élément 'a' : cible [a] (no @).

Pour le document donné, analysé avec root dans ElementTree (v1.3), le code suivant est correct et fonctionne:

  • root.findall (".// cible") Trouver les deux cibles
  • root.findall (".// cible / a") Recherche deux éléments a
  • root.findall (".// cible [a]") Ceci trouve à nouveau les deux éléments cible, car ils ont tous les deux un élément
  • root.findall (".// cible [@ name = '1']") Recherchez uniquement la première cible. Notez que les guillemets autour de 1 sont nécessaires; sinon une SyntaxError est levée
  • root.findall (".// cible [a] [@ name = '1']") Aussi valide; pour trouver cette cible
  • root.findall (".// cible [@ name = '1'] / a") Recherche un seul élément a; ...
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top