Получить список значений атрибутов XML в Python

Мне нужно получить список значений атрибутов из дочерних элементов в 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.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
14
0
32 541
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Должен признать, что я поклонник 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']

Принято, потому что это то, что я в конечном итоге использовал. Это простой однострочник, и мне не нужно было устанавливать никаких дополнительных модулей. Посмотрите и другие ответы - там есть кое-что хорошее.

roomaroo 18.09.2008 11:53

python test.py Traceback (последний вызов последним): файл "test.py", строка 1, в <module> import libxml2 ImportError: нет модуля с именем libxml2

Sreeni Puthiyillam 21.10.2012 16:41

Запрос @SR: вам, вероятно, понадобится libxml2 для использования этого примера libxml2.

Jesse Millikan 22.10.2012 08:59

Используя стандартный 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.

Руководство по Python

Другие вопросы по теме