Мне нужно получить список значений атрибутов из дочерних элементов в 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, но вот решение XPath с использованием 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")
С результатом ...
['a1', 'a2', 'a3']
python test.py Traceback (последний вызов последним): файл "test.py", строка 1, в <module> import libxml2 ImportError: нет модуля с именем libxml2
Запрос @SR: вам, вероятно, понадобится libxml2 для использования этого примера libxml2.
Используя стандартный W3 DOM, такой как minidom stdlib или 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 (к сожалению, не 1.2, который включен в Python) поддерживает 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]
В Python 3.x выборка списка атрибутов - это простая задача использования члена items().
Нижеприведенный фрагмент кода показывает способ получения списка атрибутов с помощью ElementTree.
ОБРАТИТЕ ВНИМАНИЕ, что в этом примере не рассматриваются пространства имен, которые, если они есть, необходимо учитывать.
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, "]" )
ССЫЛКА:
Element.items()
Returns the element attributes as a sequence of (name, value) pairs.
The attributes are returned in an arbitrary order.
Принято, потому что это то, что я в конечном итоге использовал. Это простой однострочник, и мне не нужно было устанавливать никаких дополнительных модулей. Посмотрите и другие ответы - там есть кое-что хорошее.