Как использовать xmltodict, чтобы получить элементы из файла XML

Я пытаюсь легко получить доступ к значениям из XML-файла.

<artikelen>
    <artikel nummer="121">
        <code>ABC123</code>
        <naam>Highlight pen</naam>
        <voorraad>231</voorraad>
        <prijs>0.56</prijs>
    </artikel>
    <artikel nummer="123">
        <code>PQR678</code>
        <naam>Nietmachine</naam>
        <voorraad>587</voorraad>
        <prijs>9.99</prijs>
    </artikel>
..... etc

Если я хочу получить доступ к значению ABC123, как мне его получить?

import xmltodict

with open('8_1.html') as fd:
    doc = xmltodict.parse(fd.read())
    print(doc[fd]['code'])

4 ответа

Используя ваш пример:

import xmltodict

with open('artikelen.xml') as fd:
    doc = xmltodict.parse(fd.read())

Если вы изучите docвы увидите, что это OrderedDict, упорядочено по тегу:

>>> doc
OrderedDict([('artikelen',
              OrderedDict([('artikel',
                            [OrderedDict([('@nummer', '121'),
                                          ('code', 'ABC123'),
                                          ('naam', 'Highlight pen'),
                                          ('voorraad', '231'),
                                          ('prijs', '0.56')]),
                             OrderedDict([('@nummer', '123'),
                                          ('code', 'PQR678'),
                                          ('naam', 'Nietmachine'),
                                          ('voorraad', '587'),
                                          ('prijs', '9.99')])])]))])

Корневой узел называется artikelenи есть подузел artikel который является списком OrderedDict объекты, так что если вы хотите code для каждой статьи вы должны сделать:

codes = []
for artikel in doc['artikelen']['artikel']:
    codes.append(artikel['code'])

# >>> codes
# ['ABC123', 'PQR678']

Если вы специально хотите code только когда nummer является 121Вы могли бы сделать это:

code = None
for artikel in doc['artikelen']['artikel']:
    if artikel['@nummer'] == '121':
        code = artikel['code']
        break

Тем не менее, если вы анализируете XML-документы и хотите найти определенное значение, подобное этому, я бы рассмотрел использование выражений XPath, которые поддерживаются ElementTree,

Чтобы прочитать.xml файлы:

import lxml.etree as ET
root = ET.parse(filename).getroot()
value = root.node1.node2.variable_name.text

Это использует xml.etree. Вы можете попробовать это:

for artikelobj in root.findall('artikel'):
    print artikelobj.find('code')

если вы хотите извлечь конкретный код на основе атрибута 'nummer' из artikel, вы можете попробовать это:

for artikelobj in root.findall('artikel'):
    if artikel.get('nummer') == 121:
        print artikelobj.find('code')

это напечатает только код, который вы хотите.

Вы можете использовать пакет lxml, используя XPath Expression.

from lxml import etree
f = open("8_1.html", "r")
tree = etree.parse(f)
expression = "/artikelen/artikel[1]/code"
l = tree.xpath(expression)
code = next(i.text for i in l)
print code

# ABC123

Здесь стоит обратить внимание на выражение. /artikelen является корневым элементом. /artikel[1] выбирает первый artikel элемент под root (Обратите внимание, что первый элемент не имеет индекс 0). /code дочерний элемент под artikel[1], Вы можете прочитать больше о синтаксисе lxml и xpath.

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