获取Python中XML属性值的列表
时间:2020-03-05 18:59:57 来源:igfitidea点击:
我需要从Python的子元素中获取属性值的列表。
举个例子最容易解释。
给定一些这样的XML:
<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>
我希望能够执行以下操作:
>>> getValues("CategoryA") ['a1', 'a2', 'a3'] >>> getValues("CategoryB") ['b1', 'b2', 'b3']
它看起来像XPath的工作,但我愿意接受所有建议。我也想听听我们最喜欢的Python XML库。
解决方案
回答
我必须承认我很喜欢xmltramp,因为它易于使用。
访问以上内容将成为:
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" )
回答
我们可以使用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')]
如果我们正在使用HTML / XML进行工作,我建议我们看一看BeautifulSoup。它类似于DOM树,但包含更多功能。
回答
我对Python并不是真正的老手,但是这是一个使用libxml2的XPath解决方案。
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")
结果...
['a1', 'a2', 'a3']
回答
使用标准W3 DOM,例如stdlib的minidom或者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')
回答
ElementTree 1.3(不幸的是不是Python附带的1.2)支持XPath,如下所示:
import elementtree.ElementTree as xml def getValues(tree, category): parent = tree.find(".//parent[@name='%s']" % category) return [child.get('value') for child in parent]
那你可以做
>>> tree = xml.parse('data.xml') >>> getValues(tree, 'CategoryA') ['a1', 'a2', 'a3'] >>> getValues(tree, 'CategoryB') ['b1', 'b2', 'b3']
lxml.etree(也提供ElementTree接口)也将以相同的方式工作。
回答
我首选的python xml库是lxml,它包装了libxml2.
Xpath似乎是解决问题的方法,因此我将其编写为:
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]