Как мне разобрать XML в Python?

Если у вас есть только 1 разделитель, вы можете использовать списки:

text = 'foo,bar,baz,qux'  
sep = ','

Добавление / добавочный разделитель:

result = [x+sep for x in text.split(sep)]
#['foo,', 'bar,', 'baz,', 'qux,']
# to get rid of trailing
result[-1] = result[-1].strip(sep)
#['foo,', 'bar,', 'baz,', 'qux']

result = [sep+x for x in text.split(sep)]
#[',foo', ',bar', ',baz', ',qux']
# to get rid of trailing
result[0] = result[0].strip(sep)
#['foo', ',bar', ',baz', ',qux']

Сепаратор как собственный элемент:

result = [u for x in text.split(sep) for u in (x, sep)]
#['foo', ',', 'bar', ',', 'baz', ',', 'qux', ',']
results = result[:-1]   # to get rid of trailing
889
задан Martin Thoma 9 April 2015 в 11:47
поделиться

6 ответов

Я предлагаю ElementTree . Существуют и другие совместимые реализации того же API, такие как lxml и cElementTree в самой стандартной библиотеке Python; но в этом контексте они в основном добавляют еще большую скорость - простота программирования зависит от API, который определяет ElementTree .

Сначала создайте экземпляр Element root ] из XML, например, с помощью функции XML , или путем синтаксического анализа файла, например:

import xml.etree.ElementTree as ET
root = ET.parse('thefile.xml').getroot()

Или любым другим способом, показанным в ElementTree . Затем сделайте что-нибудь вроде:

for type_tag in root.findall('bar/type'):
    value = type_tag.get('foobar')
    print(value)

И похожие, обычно довольно простые, шаблоны кода.

726
ответ дан 19 December 2019 в 20:22
поделиться

lxml.objectify действительно прост.

Взять образец текста:

from lxml import objectify
from collections import defaultdict

count = defaultdict(int)

root = objectify.fromstring(text)

for item in root.bar.type:
    count[item.attrib.get("foobar")] += 1

print dict(count)

Вывод:

{'1': 1, '2': 1}
37
ответ дан 19 December 2019 в 20:22
поделиться

minidom - самый быстрый и довольно простой.

XML:

<data>
    <items>
        <item name="item1"></item>
        <item name="item2"></item>
        <item name="item3"></item>
        <item name="item4"></item>
    </items>
</data>

Python:

from xml.dom import minidom
xmldoc = minidom.parse('items.xml')
itemlist = xmldoc.getElementsByTagName('item')
print(len(itemlist))
print(itemlist[0].attributes['name'].value)
for s in itemlist:
    print(s.attributes['name'].value)

Вывод:

4
item1
item1
item2
item3
item4
416
ответ дан 19 December 2019 в 20:22
поделиться

Вы можете использовать BeautifulSoup :

from bs4 import BeautifulSoup

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

y=BeautifulSoup(x)
>>> y.foo.bar.type["foobar"]
u'1'

>>> y.foo.bar.findAll("type")
[<type foobar="1"></type>, <type foobar="2"></type>]

>>> y.foo.bar.findAll("type")[0]["foobar"]
u'1'
>>> y.foo.bar.findAll("type")[1]["foobar"]
u'2'
229
ответ дан 19 December 2019 в 20:22
поделиться

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 # prints 4
20
ответ дан 19 December 2019 в 20:22
поделиться

Я считаю, что Python xml.dom и xml.dom.minidom довольно прост. Имейте в виду, что DOM не подходит для больших объемов XML, но если ваш ввод довольно мал, это будет работать нормально.

5
ответ дан 19 December 2019 в 20:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: