J'ai du mal à utiliser l'attribut XPath Selector dans ElementTree, ce que je devrais être capable de faire selon 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 ([)
La syntaxe que vous essayez d'utiliser est nouvelle dans ElementTree 1..
Cette version est livrée avec Python 2.7 ou supérieur. Si vous avez Python 2.6 ou moins, vous avez toujours ElementTree 1.2.6 ou moins.
Il y a plusieurs problèmes dans ce code.
Le buildin ElementTree de Python (ET pour faire court) n'a pas de véritable support XPATH; seulement un sous-ensemble limité Par exemple, il ne prend pas en charge les expressions find-from-root comme //target
.
Remarque: la documentation mentionne " // ", mais uniquement pour les enfants: donc une expression comme .//target
est valable; //...
Ne l'est pas!
Il existe une implémentation alternative: lxml qui est plus riche. C'est la couture que la documentation est utilisée, pour le code intégré. Cela ne correspond pas/ne fonctionne pas.
La notation @name
Sélectionne les attributs xml - ; l'expression key=value
dans une balise xml.
Cette valeur de nom doit donc être 1 ou 2 pour sélectionner quelque chose dans le document donné. Ou, on peut rechercher des cibles avec un élément enfant 'a': target[a]
(Non @).
Pour le document donné, analysé avec le ElementTree intégré (v1.3) à la racine, le code suivant est correct et fonctionne:
root.findall(".//target")
Trouver les deux ciblesroot.findall(".//target/a")
Trouver deux éléments aroot.findall(".//target[a]")
Ceci trouve à nouveau les deux éléments cibles, car les deux ont un élément aroot.findall(".//target[@name='1']")
Trouver uniquement la cible d'abord. Notez que les guillemets autour de 1 sont nécessaires; sinon une SyntaxError est levéeroot.findall(".//target[a][@name='1']")
Également valide; pour trouver cet objectifroot.findall(".//target[@name='1']/a")
Recherche un seul élément a; ...