Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get list of XML attribute values in Python

I need to get a list of attribute values from child elements in Python.

It's easiest to explain with an example.

Given some XML like this:

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

I want to be able to do something like:

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

It looks like a job for XPath but I'm open to all recommendations. I'd also like to hear about your favourite Python XML libraries.

like image 740
roomaroo Avatar asked Sep 17 '08 20:09

roomaroo


3 Answers

I'm not really an old hand at Python, but here's an XPath solution using 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")

With result...

['a1', 'a2', 'a3']
like image 177
3 revs Avatar answered Oct 12 '22 17:10

3 revs


ElementTree 1.3 (unfortunately not 1.2 which is the one included with Python) supports XPath like this:

import elementtree.ElementTree as xml

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

Then you can do

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

lxml.etree (which also provides the ElementTree interface) will also work in the same way.

like image 38
dF. Avatar answered Oct 12 '22 17:10

dF.


You can do this with 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')]

If you're doing work with HTML/XML I would recommend you take a look at BeautifulSoup. It's similar to the DOM tree but contains more functionality.

like image 34
Cristian Avatar answered Oct 12 '22 19:10

Cristian