Pregunta

Tengo problemas para usar el atributo XPath Selector en ElementTree, que debería poder hacer de acuerdo con Documentación

Aquí hay un código de muestra

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

Recibo la siguiente excepción:

expected path separator ([)
¿Fue útil?

Solución

La sintaxis que está intentando usar es nueva en ElementTree 1.3 .

Dicha versión se envía con Python 2.7 o superior. Si tiene Python 2.6 o menos, todavía tiene ElementTree 1.2.6 o menos.

Otros consejos

Hay varios problemas en este código.

  1. El buildT ElementTree (ET para abreviar) de Python no tiene soporte XPATH real; solo un subconjunto limitado Por ejemplo, no admite expresiones find-from-root como // target .

    Aviso: la documentación menciona " // " ;, pero solo para niños: una expresión como .//target es válido; // ... no lo es

    Hay una implementación alternativa: lxml , que es más rica. Parece que se usa documentación para el código incorporado. Eso no coincide / funciona.

  2. La notación @name selecciona xml- atributos ; la expresión key = value dentro de una etiqueta xml.

    Entonces, ese nombre-valor debe ser 1 o 2 para seleccionar algo en el documento dado. O bien, uno puede buscar objetivos con un elemento secundario 'a' : target [a] (no @).

Para el documento dado, analizado con el ElementTree incorporado (v1.3) a la raíz, el siguiente código es correcto y funciona:

  • root.findall (" .// target ") Encuentra ambos objetivos
  • root.findall (" .// target / a ") Encuentra dos elementos a
  • root.findall (" .// target [a] ") Esto vuelve a encontrar ambos elementos de destino, ya que ambos tienen un elemento a
  • root.findall (" .// target [@ name = '1'] ") Encuentre solo el first target. Observe que se necesitan las comillas alrededor de 1; de lo contrario, se genera un SyntaxError
  • root.findall (" .// target [a] [@ name = '1'] ") También válido; para encontrar ese objetivo
  • root.findall (" .// target [@ name = '1'] / a ") Encuentra solo un elemento a; ...
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top