Как использовать 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.