Если у вас есть только 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
Я предлагаю 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)
И похожие, обычно довольно простые, шаблоны кода.
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}
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
Вы можете использовать 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'
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
Я считаю, что Python xml.dom и xml.dom.minidom довольно прост. Имейте в виду, что DOM не подходит для больших объемов XML, но если ваш ввод довольно мал, это будет работать нормально.