【发布时间】:2020-01-23 12:33:51
【问题描述】:
我想用以下结构解析 XML (~1GB):
<Publication creationDateTime="04-AUG-2019 05:22:07">
<holds>
<hold>
<recordType>Standard</recordType>
<isEnroute>true</isEnroute>
<holdName>NANLANG</holdName>
<holdTime>10</holdTime>
<inbound>
<courseValue>170</courseValue>
</inbound>
<min>
<altitude>7874</altitude>
</min>
</hold>
<hold>
<recordType>Standard</recordType>
<holdName>ZILINA LOM</holdName>
<holdTime>10</holdTime>
<inbound>
<courseValue>243</courseValue>
</inbound>
<max>
<isFlightLevel>true</isFlightLevel>
<altitude>85</altitude>
</max>
<min>
<altitude>4500</altitude>
</min>
</hold>
</holds>
</Publication>
我已经清楚最有效的方法是使用lxml.etree iterparse method。
我需要将每个标签解析为变量,然后插入数据库。 问题是我没有掌握迭代“head”标签(例如保持)并插入数据库的方式,我的代码示例如下:
class Avia:
def __init__(self, **kwargs):
for attr in kwargs.keys():
self.__dict__[attr] = kwargs[attr]
context = ET.iterparse('test.xml')
def xml_fast_iter(context):
for event, elem in context:
if elem.tag == 'holdName':
hold_name = elem.text
elif elem.tag == 'holdTime':
hold_time = elem.text
elif elem.tag == 'courseValue':
course = float(elem.text)
elif elem.tag == 'isEnroute':
hold_enr = elem.text
# ...
elem.clear()
for ancestor in elem.xpath('ancestor-or-self::*'):
if ancestor.tag == 'min':
bottom = alt
if ancestor.tag == 'max':
top = alt
while ancestor.getprevious() is not None:
del ancestor.getparent()[0]
if elem.tag == 'hold':
hold_type = 'TER'
if hold_enr:
hold_type = 'ENR'
outbound = course + 180 if course + 180 < 360 else course - 180
holdPattern = Avia(name=hold_name, time=hold_time, course=course, outbound=outbound, type=hold_type, bottom=bottom, top=top)
prop_dict = holdPattern.__dict__
print(prop_dict)
del context
当尝试打印时,我显然得到了第二个对象的hold_type = 'ENR',因为hold_enr 对第一个对象是正确的,并且当第二个对象没有这个键时它没有改变......当试图分配None对于for event, elem in context: 之后的所有变量,我将得到除最后一个之外的所有值=无,因为它们循环遍历每个元素。
解析所有键和初始化对象的正确方法是什么?也许我的方式完全错误?
初始化后给变量赋值None是否正确? (那么hold_type是正确的)
【问题讨论】:
标签: python-3.x for-loop xml-parsing lxml