1086 votes

Comment pour analyser XML en python ?

J’ai plusieurs lignes d’une base de données contenant le xml et j’essaie d’écrire un python script qui va traverser les lignes et compter le nombre d’instances d’un attribut du nœud particulier apparaît. Par exemple, mon arbre ressemble à :

Comment puis-je accéder aux attributs de 1 et 2 dans le fichier XML à l’aide de Python ?

859voto

Alex Martelli Points 330805

Je suggère ElementTree (il y a d'autres compatible implémentations, comme lxml, mais ce qu'ils ont ajouter, c'est "juste" encore plus de rapidité, la facilité de programmation de la partie dépend de l'API, qui ElementTree définit.

Après la construction d'un Élément de l'instance e du XML, par exemple avec le XML en fonction de:

for atype in e.findall('type')
  print(atype.get('foobar'))

et la comme.

454voto

Ryan Christensen Points 4064

minidom est le plus rapide et plutôt simple:

XML:

 <data>
    <items>
        <item name="item1"></item>
        <item name="item2"></item>
        <item name="item3"></item>
        <item name="item4"></item>
    </items>
</data>
 

PYTHON:

 from xml.dom import minidom
xmldoc = minidom.parse('items.xml')
itemlist = xmldoc.getElementsByTagName('item') 
print len(itemlist)
print itemlist[0].attributes['name'].value
for s in itemlist :
    print s.attributes['name'].value
 

SORTIE

 4
item1
item1
item2
item3
item4
 

251voto

YOU Points 44812

Vous pouvez utiliser BeautifulSoup

 from BeautifulSoup import BeautifulSoup

x="""<foo>
   <bar>
      <type foobar="1"/>
      <type foobar="2"/>
   </bar>
</foo>"""

y=BeautifulSoup(x)
>>> y.foo.bar.type["foobar"]
u'1'

>>> y.foo.bar.findAll("type")
[<type foobar="1"></type>, <type foobar="2"></type>]

>>> y.foo.bar.findAll("type")[0]["foobar"]
u'1'
>>> y.foo.bar.findAll("type")[1]["foobar"]
u'2'
 

105voto

Cyrus Points 179

Il y a beaucoup d'options là-bas. cElementTree semble plutôt idéal si la vitesse et l'utilisation de la mémoire sont un problème. Les repères par rapport à plusieurs autres méthodes sont disponibles sur le site Web. J'ai copié le tableau pertinent ci-dessous:

 library                         time    space
xml.dom.minidom (Python 2.1)    6.3 s   80000K
gnosis.objectify                2.0 s   22000k
xml.dom.minidom (Python 2.4)    1.4 s   53000k
ElementTree 1.2                 1.6 s   14500k  
ElementTree 1.2.4/1.3           1.1 s   14500k  
cDomlette (C extension)         0.540 s 20500k
PyRXPU (C extension)            0.175 s 10850k
libxml2 (C extension)           0.098 s 16000k
readlines (read as utf-8)       0.093 s 8850k   
cElementTree (C extension)      0.047 s 4900k   
readlines (read as ascii)       0.032 s 5050k   
 

39voto

Ryan Ginstrom Points 8354

lxml.objectify est vraiment simple.

Prenant votre exemple de texte:

 from lxml import objectify
from collections import defaultdict

count = defaultdict(int)

root = objectify.fromstring(text)

for item in root.bar.type:
    count[item.attrib.get("foobar")] += 1

print dict(count)
 

Sortie:

 {'1': 1, '2': 1}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X