2008-09-17 11 views
12

J'ai besoin d'obtenir une liste de valeurs d'attributs à partir d'éléments enfants dans Python.Obtenir la liste des valeurs d'attributs XML en Python

Il est plus facile d'expliquer avec un exemple.

donné quelques XML comme ceci:

<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> 

Je veux être capable de faire quelque chose comme:

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

Il ressemble à un emploi pour XPath mais je suis ouvert à tous recommandations. J'aimerais aussi entendre parler de vos bibliothèques Python XML préférées.

Répondre

7

Je ne suis pas vraiment un vétéran de Python, mais voici une solution XPath utilisant 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") 

avec un résultat ...

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

accepté parce que ce que je fini par utiliser. C'est un simple interligne et je n'ai pas besoin d'installer de modules supplémentaires. Regardez les autres réponses aussi - il y a du bon. – roomaroo

+0

python test.py retraçage (appel le plus récent en dernier): Fichier "test.py", ligne 1, dans importation libxml2 ImportError: Aucun module nommé libxml2 –

+0

requête @SR: Vous aurez probablement besoin d'utiliser libxml2 cet exemple libxml2. –

2

Je dois admettre que je suis un fan de xmltramp en raison de sa facilité d'utilisation.

Accès au-dessus devient:

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

Vous pouvez le faire avec 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 vous faites travailler avec HTML/XML, je vous recommande de jeter un oeil à BeautifulSoup. Il est similaire à l'arborescence DOM mais contient plus de fonctionnalités.

3

En utilisant une norme W3 DOM comme le minidom du stdlib ou 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 (malheureusement pas 1.2 qui est celui inclus avec Python) supports XPath comme ceci:

import elementtree.ElementTree as xml 

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

Ensuite, vous pouvez faire

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

lxml.etree (qui fournit également l'interface ElementTree) travaillera également de la même manière.

2

Ma bibliothèque python xml préférée est lxml, ce qui enveloppe libxml2.
Xpath ne semble le chemin à parcourir ici, donc j'écrire cela comme quelque chose comme:

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

3.x Python, la lecture d'une liste d'attributs est une tâche simple d'utiliser le membre items()

En utilisant le ElementTree, l'extrait ci-dessous montre un moyen d'obtenir la liste des attributs. REMARQUE: cet exemple ne prend pas en compte les espaces de noms qui, s'ils sont présents, devront être pris en compte.

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, "]") 

RÉFÉRENCE:

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

Python manual

Questions connexes