LXML, как получить несколько наборов атрибутов в списках - PullRequest
3 голосов
/ 30 декабря 2011

У меня похожая проблема, подобная этой:

Как выбрать несколько наборов атрибутов в документе XML с использованием XPath?

Мои XML-данные выглядят так:

<?xml version="1.0" encoding="utf-8"?>
<Basic>
    <Segment>
        <Sample value="12" data2="25" data3="23"/>
        <Sample value="13" data2="0" data3="323"/>
        <Sample value="14" data2="2" data3="3"/>
    </Segment>
</Basic>

Какой самый простой способ Python для получения этих datax значений в списках.

Например: data2 = ['25','0','2']

Ответы [ 3 ]

5 голосов
/ 30 декабря 2011

С xpath:

from lxml import etree
from collections import defaultdict
from pprint import pprint

doc="""<?xml version="1.0" encoding="utf-8"?>
<Basic>
    <Segment>
        <Sample value="12" data2="25" data3="23"/>
        <Sample value="13" data2="0" data3="323"/>
        <Sample value="14" data2="2" data3="3"/>
    </Segment>
</Basic>
"""
el = etree.fromstring(doc)
data2 = el.xpath('//@data2')
dataX = el.xpath('//@*[starts-with(name(), "data")]')
print data2
print dataX

# With iteration over Sample elements, like in J.F. Sebastian answer, but with XPath
d = defaultdict(list)
for sample in el.xpath('//Sample'):
    for attr_name, attr_value in sample.items():
        d[attr_name].append(attr_value)

pprint(dict(d))

Вывод:

['25', '0', '2']
['25', '23', '0', '323', '2', '3']
{'data2': ['25', '0', '2'],
 'data3': ['23', '323', '3'],
 'value': ['12', '13', '14']}
1 голос
/ 22 марта 2016

Самый простой способ получить значения атрибута - использовать etree.Element.get ('attr_name'):

from lxml import etree

s = '''<?xml version="1.0" encoding="utf-8"?>
<Basic>
    <Segment>
        <Sample value="12" data2="25" data3="23"/>
        <Sample value="13" data2="0" data3="323"/>
        <Sample value="14" data2="2" data3="3"/>
    </Segment>
</Basic>'''

# ❗️for python2
# tree = etree.fromstring(s)

# ❗️for python3
tree = etree.fromstring(s.encode("utf-8"))

samples = tree.xpath('//Sample')

print([sample.get('data2') for sample in samples])
>>> ['25', '0', '2']
0 голосов
/ 30 декабря 2011

Использование cElementTree из stdlib:

import sys
from collections import defaultdict
from xml.etree import cElementTree as etree

d = defaultdict(list)
for ev, el in etree.iterparse(sys.stdin):
    if el.tag == 'Sample':
       for name in "value data2 data3".split():
           d[name].append(el.get(name))
print(d)

Вывод

{'data2': ['25', '0', '2'],
 'data3': ['23', '323', '3'],
 'value': ['12', '13', '14']}

Если вы используете lxml.etree, тогда вы можете: etree.iterparse(file, tag='Sample') выбратьSample элементов в iterparse() т. Е. В этом случае вы можете сбросить условие if el.tag == 'Sample'.

...