Holen Liste der XML-Attributwerte in Python
-
01-07-2019 - |
Frage
Ich brauche eine Liste von Attributwerten von untergeordneten Elementen in Python zu erhalten.
Es ist am einfachsten mit einem Beispiel zu erklären.
einige XML wie folgt gegeben:
<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>
Ich möchte in der Lage sein zu tun, so etwas wie:
>>> getValues("CategoryA")
['a1', 'a2', 'a3']
>>> getValues("CategoryB")
['b1', 'b2', 'b3']
Es sieht aus wie ein Job für XPath, aber ich bin auf alle Empfehlungen offen. Ich würde auch gerne über Ihre Lieblings-Python XML-Bibliotheken hören.
Lösung
Ich bin nicht wirklich ein alter Hase in Python, aber hier ist eine XPath-Lösung mit 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")
Mit Ergebnis ...
['a1', 'a2', 'a3']
Andere Tipps
ElementTree 1.3 (leider nicht die 1,2 ist die mit Python enthalten) unterstützt XPath wie folgt aus:
import elementtree.ElementTree as xml
def getValues(tree, category):
parent = tree.find(".//parent[@name='%s']" % category)
return [child.get('value') for child in parent]
Dann können Sie tun
>>> tree = xml.parse('data.xml')
>>> getValues(tree, 'CategoryA')
['a1', 'a2', 'a3']
>>> getValues(tree, 'CategoryB')
['b1', 'b2', 'b3']
lxml.etree
(die auch die ElementTree Schnittstelle zur Verfügung stellt) wird auch in der gleichen Art und Weise arbeiten.
einen Standard-W3 DOM wie die stdlib des minidom oder 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')
Ich muss zugeben, ich bin ein Fan von xmltramp aufgrund seiner Benutzerfreundlichkeit .
Zugriff auf die oben wird:
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" )
Sie können dies mit 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')]
Wenn Sie tun Arbeit mit HTML / XML würde ich empfehlen Ihnen einen Blick auf BeautifulSoup zu nehmen. Es ist ähnlich wie die DOM-Struktur enthält aber mehr Funktionalität.
Meine bevorzugte Python XML-Bibliothek ist lxml , die libxml2 einwickelt.
Xpath scheint den Weg hierher zu gehen, so würde ich dies als etwas schreiben wie:
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]
In Python 3.x, eine Liste der Attribute zu holen ist eine einfache Aufgabe, das Mitglied items()
der mit
Mit dem ElementTree
unter Schnipsel eine Art und Weise zeigt die Liste der Attribute zu erhalten.
Beachten, dass dieses Beispiel nicht berücksichtigt Namespaces, die falls vorhanden, werden muß, berücksichtigt.
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, "]" )
Referenz:
Element.items ()
Gibt das Element-Attribute als eine Folge von (Name, Wert) -Paare.
Die Attribute werden in beliebiger Reihenfolge zurückgegeben.