11

Как разобрать XML и получить значения определенного атрибута узла?

9

У меня есть много строк в XML, и я пытаюсь получить значения конкретного атрибута узла. Вот пример XML:

<foo>
   <bar>
      <type foobar="1"/>
      <type foobar="2"/>
   </bar>
</foo>

Как мне получить доступ к значениям атрибута foobar? В этом примере я хочу получить "1" и "2".

5 ответ(ов)

0

xml.etree.ElementTree vs. lxml

Вот некоторые преимущества двух самых популярных библиотек, которые было бы полезно знать перед выбором между ними.

xml.etree.ElementTree:

  1. Из стандартной библиотеки: не требуется установка дополнительных модулей.

lxml:

  1. Легко писать XML-декларации: например, нужно ли добавить standalone="no"?
  2. Красивый вывод: вы можете получить хорошо отформатированный XML без лишнего кода.
  3. Функциональность Objectify: позволяет работать с XML так, как если бы это была обычная иерархия объектов Python.
  4. sourceline позволяет легко получить номер строки элемента XML, который вы используете.
  5. Также доступен встроенный проверщик схем XSD.
0

В приведенном вами коде происходит парсинг XML-строки с использованием модуля xml.etree.ElementTree. В этом коде создается XML-дерево, после чего выполняется поиск всех элементов <type> внутри тега <bar>. Далее, для каждого найденного элемента выводится значение атрибута foobar.

Вот код с небольшими исправлениями для корректного вывода (с использованием функции print в Python 3):

import xml.etree.ElementTree as ET

data = '''<foo>
           <bar>
               <type foobar="1"/>
               <type foobar="2"/>
          </bar>
       </foo>'''

tree = ET.fromstring(data)
lst = tree.findall('bar/type')

for item in lst:
    print(item.get('foobar'))

Этот код напечатает значения атрибута foobar для каждого элемента <type>, что в данном случае будет:

1
2

Таким образом, скрипт успешно извлекает и выводит значения атрибута foobar из XML-структуры.

0

Используйте библиотеку pandas. В pandas есть функция read_xml(), которая отлично подходит для работы с такими плоскими структурами XML.

Вот пример кода:

import pandas as pd

xml = """<foo>
   <bar>
      <type foobar="1"/>
      <type foobar="2"/>
   </bar>
</foo>"""

df = pd.read_xml(xml, xpath=".//type")
print(df)

Вывод будет следующим:

   foobar
0       1
1       2

Таким образом, вы сможете легко извлечь данные из вашего XML в удобный формат DataFrame для дальнейшей работы.

0

В Python есть интерфейс к парсеру XML expat:

xml.parsers.expat

Это парсер, не проводящий валидацию, поэтому ошибки в XML не будут выявлены. Но если вы уверены, что ваш файл корректен, то это вполне приемлемо, и вы, вероятно, сможете получить нужную информацию, отбрасывая лишнее на лету.

В качестве примера, вот как можно использовать этот парсер:

stringofxml = """<foo>
    <bar>
        <type arg="value" />
        <type arg="value" />
        <type arg="value" />
    </bar>
    <bar>
        <type arg="value" />
    </bar>
</foo>"""
count = 0

def start(name, attr):
    global count
    if name == 'type':
        count += 1

p = expat.ParserCreate()
p.StartElementHandler = start
p.Parse(stringofxml)

print(count)  # выводит 4

В этом примере мы создаем строку с XML, устанавливаем обработчик для начала элемента и подсчитываем, сколько раз встречается элемент <type>. В результате мы получаем количество этих элементов в XML, которое равно 4.

0

Ваш код на Python правильно разбирает XML-файл и выводит ожидаемые результаты. Давайте разберем его по частям.

Первоначально вы импортируете модуль xml.etree.cElementTree и загружаете XML-дерево из файла foo.xml. После этого вы получаете корневой элемент и выводите его тег.

import xml.etree.cElementTree as ET

tree = ET.parse("foo.xml")
root = tree.getroot() 
root_tag = root.tag
print(root_tag)  # Выводит 'foo'

Следующий блок кода находит все дочерние элементы <type>, которые находятся внутри <bar>. Используя метод findall, вы получаете список этих элементов и перебираете их.

for form in root.findall("./bar/type"):
    x = (form.attrib)  # Получаем атрибуты элемента <type>
    z = list(x)        # Преобразуем словарь атрибутов в список
    for i in z:
        print(x[i])    # Выводим значение каждого атрибута

В этом блоке x представляет собой словарь атрибутов, который содержит foobar как ключ. Поскольку в вашем XML два элемента <type> с разными значениями атрибута foobar, ваш код корректно выводит их значения в порядке их появления.

Таким образом, вывод программы будет:

foo
1
2

Если у вас есть какие-либо конкретные вопросы по коду или XML, пожалуйста, уточните, и я с радостью помогу!

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь