2016-09-27 3 views
0

Мне очень нужна помощь в разборе XML-файла. Я пару часов двигаю колесами и не добился большого прогресса. У меня есть фрагмент ниже XML и я пытаюсь создать столбец с именами и значениями. Проблема в том, что некоторые имена индексируются и вызывают проблемы с выравниванием, когда я печатаю их рядом.Python XML Parsing - выравнивание индексированных элементов

Можете ли вы мне помочь или направить меня на разбор этого XML и получить желаемый отпечаток? В идеале я хотел бы сделать это, не используя lxml, поскольку система не имеет этого модуля, но не против предложений, использующих lxml.

Пример XML файла:

<root> 
    <elments> 
    <mgmtid> 
     <date>20160926</date> 
     <gp>3600</gp> 
     <name p="">watermelons</name> 
     <name p="">bananas</name> 
     <name p="">oranges</name> 
     <valuegroup> 
     <objid>None</objid> 
     <value p="">10</value> 
     <value p="">15</value> 
     <value p="">20</value> 
     </valuegroup> 
    </mgmtid> 
    <mgmtid> 
     <date>20160926</date> 
     <gp>3600</gp> 
     <name p="">apples</name> 
     <valuegroup> 
     <objid>red</objid> 
     <value p="">100</value> 
     </valuegroup> 
     <valuegroup> 
     <objid>blue</objid> 
     <value p="">200</value> 
     </valuegroup> 
     <valuegroup> 
     <objid>yellow</objid> 
     <value p="">300</value> 
     </valuegroup> 
     <valuegroup> 
     <objid>white</objid> 
     <value p="">400</value> 
     </valuegroup> 
     <valuegroup> 
     <objid>green</objid> 
     <value p="">500</value> 
     </valuegroup> 
    </mgmtid> 
    <mgmtid> 
     <date>20160926</date> 
     <gp>3600</gp> 
     <name p="">strawberry</name> 
     <name p="">guava</name> 
     <valuegroup> 
     <objid>None</objid> 
     <value p="">650</value> 
     <value p="">750</value> 
     </valuegroup> 
    </mgmtid> 
    </elments> 
</root> 

Моя попытка (несчастно не удалось) при получении имен и значений. Поскольку вы можете видеть, что значения не совпадают с их именами.

import xml.etree.ElementTree as ET 
import itertools 
import collections 

tree = ET.parse('test_xml_file.xml') 
root = tree.getroot() 

names = [] 
values = [] 

for i in (tree.findall('.//')): 
    if i.tag == 'name': 
     n = (i.tag, i.text) 
     names.append(n[0] + ' ' + str(n[1])) 

for i in (tree.findall('.//')): 
    if i.tag == 'value' or i.tag == 'objid': 
     v = (i.tag, i.text) 
     values.append(v[0] + ' ' + str(v[1])) 

print('=' * 45) 
for n, v in itertools.zip_longest(names, values): 
    print(str(n).ljust(20, ' ') + str(v)) 

Выходной ток:

name watermelons objid None 
name bananas  value 10 
name oranges  value 15 
name apples   value 20 
name strawberry  objid red 
name guava   value 100 
None    objid blue 
None    value 200 
None    objid yellow 
None    value 300 
None    objid white 
None    value 400 
None    objid green 
None    value 500 
None    objid None 
None    value 650 
None    value 750 

Желаемая Выход:

============================= 
name  Index value 
============================= 
watermelons None 10 
bananas  None 15 
oranges  None 20 
apples  red  100 
apples  blue 200 
apples  yellow 300 
apples  white 400 
apples  green 500 
strawberry None 650 
guava  None 750 

ответ

0

Я не вижу быстрый и необычный способ ее решения, этот код работает:

import xml.etree.ElementTree as ET 
tree = ET.parse('test_xml_file.xml') 
elements = [] 
mgmtids = tree.getroot().findall(".//mgmtid") 
for mgmtid in mgmtids: 
    names = mgmtid.findall(".//name") 
    objids = mgmtid.findall(".//valuegroup/objid") 
    values = mgmtid.findall(".//valuegroup/value") 
    if len(names) == len(values): 
     for i in range(len(names)): 
      elements.append([names[i].text,objids[0].text,values[i].text]) 
    elif len(objids)==len(values): 
     for i in range(len(values)): 
      elements.append([names[0].text,objids[i].text,values[i].text]) 
    elif len(names) == len(objids): 
     for i in range(len(names)): 
      elements.append([names[i].text,objids[i].text,values[0].text]) 
     #elements.append([names[i].text,objids[i].text,values[i].text for i in len(names)]) 
print "\n".join([" - ".join([text for text in el]) for el in elements]) 

Надеюсь, это поможет!

+0

Спасибо, что посмотрели на это. Несмотря на то, что это не выполняло именно то, что я искал, это помогло/направить меня на выравнивание имен и значений для неиндексированных значений. Я продолжу искать решение для индексированных значений. Благодарю. – MBasith