Domanda

Sto riscontrando problemi nell'uso dell'attributo XPath Selector in ElementTree, che dovrei essere in grado di fare secondo il Documentazione

Ecco un po 'di codice di esempio

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

Ricevo la seguente eccezione:

expected path separator ([)
È stato utile?

Soluzione

La sintassi che stai tentando di utilizzare è nuova in ElementTree 1.3 .

Tale versione viene fornita con Python 2.7 o versione successiva. Se hai Python 2.6 o meno hai ancora ElementTree 1.2.6 o meno.

Altri suggerimenti

Esistono diversi problemi in questo codice.

  1. ElementTree (in breve) buildin di Python non ha un vero supporto XPATH; solo un sottoinsieme limitato Ad esempio, non supporta le espressioni trova-da-radice come // target .

    Avviso: la documentazione menziona " // " ;, ma solo per i bambini: quindi un'espressione come .//target è valido; // ... non lo è!

    Esiste un'implementazione alternativa: lxml che è più ricco. È la giuntura che viene utilizzata la documentazione, per il codice incorporato. Ciò non corrisponde / funziona.

  2. La notazione @name seleziona xml- attributi ; l'espressione key = value all'interno di un tag xml.

    Quindi quel nome-valore deve essere 1 o 2 per selezionare qualcosa nel documento dato. Oppure, si possono cercare target con un elemento 'a' : target [a] (no @).

Per il documento dato, analizzato con ElementTree incorporato (v1.3) su root, il codice seguente è corretto e funzionante:

  • root.findall (" .// target ") Trova entrambi i target
  • root.findall (" .// target / a ") Trova due elementi a
  • root.findall (" .// target [a] ") Questo trova di nuovo entrambi gli elementi target, poiché entrambi hanno un elemento a
  • root.findall (" .// target [@ name = '1'] ") Trova solo il primo target. Si noti che le virgolette intorno a 1 sono necessarie; altrimenti viene generato un SyntaxError
  • root.findall (" .// target [a] [@ name = '1'] ") Anche valido; per trovare quell'obiettivo
  • root.findall (" .// target [@ name = '1'] / a ") Trova solo un elemento a; ...
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top