Python XML解析 - 对齐索引元素

时间:2016-09-27 00:21:33

标签: python xml parsing xml-parsing lxml

我迫切需要一些解析xml文件的帮助。我一直在转动轮子几周,并没有取得多大进展。我有下面的XML片段,我正在尝试创建一个包含名称和值的列。问题是,当我并排打印时,某些名称会被编入索引并导致对齐问题。

您能帮助或指导我解析此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

1 个答案:

答案 0 :(得分: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])

希望它有所帮助!