2008-09-17 20 views
12

Necesito obtener una lista de valores de atributos de elementos secundarios en Python.Obtener una lista de valores de atributos XML en Python

Es más fácil de explicar con un ejemplo.

dado un poco de XML como esto:

<elements> 
    <parent name="CategoryA"> 
     <child value="a1"/> 
     <child value="a2"/> 
     <child value="a3"/> 
    </parent> 
    <parent name="CategoryB"> 
     <child value="b1"/> 
     <child value="b2"/> 
     <child value="b3"/> 
    </parent> 
</elements> 

Quiero ser capaz de hacer algo como:

>>> getValues("CategoryA") 
['a1', 'a2', 'a3'] 
>>> getValues("CategoryB") 
['b1', 'b2', 'b3'] 

Se ve como un trabajo para XPath, pero estoy abierto a todos recomendaciones. También me gustaría escuchar acerca de sus bibliotecas favoritas de Python XML.

Respuesta

7

No soy realmente un experto en Python, pero aquí hay una solución XPath que usa libxml2.

import libxml2 

DOC = """<elements> 
    <parent name="CategoryA"> 
     <child value="a1"/> 
     <child value="a2"/> 
     <child value="a3"/> 
    </parent> 
    <parent name="CategoryB"> 
     <child value="b1"/> 
     <child value="b2"/> 
     <child value="b3"/> 
    </parent> 
</elements>""" 

doc = libxml2.parseDoc(DOC) 

def getValues(cat): 
    return [attr.content for attr in doc.xpathEval("/elements/parent[@name='%s']/child/@value" % (cat))] 

print getValues("CategoryA") 

Con el resultado ...

['a1', 'a2', 'a3'] 
+0

aceptada porque esto es lo que terminé usando. Es un simple trazador de líneas y no tuve que instalar ningún módulo adicional. Echa un vistazo a las otras respuestas también, hay algunas cosas buenas allí. – roomaroo

+0

pitón test.py Rastreo (llamada más reciente pasado): Archivo "test.py", línea 1, en importación libxml2 ImportError: Sin módulo denominado libxml2 –

+0

consulta @SR: Usted va a necesitar utilizar libxml2 este ejemplo libxml2. –

2

Debo admitir que soy fan de xmltramp debido a su facilidad de uso.

Acceso a la anterior se convierte en:

import xmltramp 

    values = xmltramp.parse('''...''') 

    def getValues(values, category): 
    cat = [ parent for parent in values['parent':] if parent(name) == category ] 
    cat_values = [ child(value) for child in parent['child':] for parent in cat ] 
    return cat_values 

    getValues(values, "CategoryA") 
    getValues(values, "CategoryB") 
2

Usted puede hacer esto con BeautifulSoup

>>> from BeautifulSoup import BeautifulStoneSoup 
>>> soup = BeautifulStoneSoup(xml) 
>>> def getValues(name): 
. . .  return [child['value'] for child in soup.find('parent', attrs={'name': name}).findAll('child')] 

Si estás haciendo un trabajo con HTML/XML le recomiendo que eche un vistazo a BeautifulSoup. Es similar al árbol DOM pero contiene más funcionalidad.

3

El uso de un estándar W3 DOM como minidom del stdlib o pxdom:

def getValues(category): 
    for parent in document.getElementsByTagName('parent'): 
     if parent.getAttribute('name')==category: 
      return [ 
       el.getAttribute('value') 
       for el in parent.getElementsByTagName('child') 
      ] 
    raise ValueError('parent not found') 
6

ElementTree 1.3 (por desgracia, no es 1.2, que el incluido con Python) supports XPath como este:

import elementtree.ElementTree as xml 

def getValues(tree, category): 
    parent = tree.find(".//parent[@name='%s']" % category) 
    return [child.get('value') for child in parent] 

A continuación, puede hacer

>>> tree = xml.parse('data.xml') 
>>> getValues(tree, 'CategoryA') 
['a1', 'a2', 'a3'] 
>>> getValues(tree, 'CategoryB') 
['b1', 'b2', 'b3'] 

lxml.etree (que también proporciona la interfaz elementtree) también funcionará de la misma manera.

2

Mi biblioteca preferida de python xml es lxml, que envuelve libxml2.
Xpath hace parecer el camino a seguir aquí, así que me gustaría escribir esto como algo así como:

from lxml import etree 

def getValues(xml, category): 
    return [x.attrib['value'] for x in 
      xml.findall('/parent[@name="%s"]/*' % category)] 

xml = etree.parse(open('filename.xml')) 

>>> print getValues(xml, 'CategoryA') 
['a1', 'a2', 'a3'] 
>>> print getValues(xml, 'CategoryB') 
['b1', 'b2', 'b3] 
0

En Python 3.x, ir a buscar una lista de atributos es una tarea simple de usar el miembro de items()

Al usar el ElementTree, debajo del fragmento se muestra una forma de obtener la lista de atributos. TEN EN CUENTA que este ejemplo no considera los espacios de nombres, que si están presentes, deberán tenerse en cuenta.

import xml.etree.ElementTree as ET 

    flName = 'test.xml' 
    tree = ET.parse(flName) 
    root = tree.getroot() 
    for element in root.findall('<child-node-of-root>'): 
     attrList = element.items() 
     print(len(attrList), " : [", attrList, "]") 

REFERENCIA:

Element.items()
Returns the element attributes as a sequence of (name, value) pairs.
The attributes are returned in an arbitrary order.

Python manual

Cuestiones relacionadas