MiFID 2下解析GLEIF的LEI XML数据遇卡顿及AttributeError问题求助
我来帮你搞定这个LEI XML解析的问题,你遇到的卡顿和AttributeError,核心原因是XML命名空间没处理加上大文件一次性加载导致内存过载,咱们一步步解决:
1. 先搞懂命名空间的问题
你的XML里的lei:前缀不是随便加的,它对应一个固定的命名空间URI:http://www.gleif.org/data/schema/leidata/2016。lxml在解析时会把前缀转换成完整的URI,所以直接用root.LEIRecord这种方式根本找不到元素,必须明确指定命名空间。
2. 解决pyval的错误
pyval是lxml objectify给元素自动添加的属性,但如果元素内容为空或者解析时类型不匹配,就会抛出找不到这个属性的错误。更稳妥的方式是直接用elem.text来获取元素的文本内容,兼容性更好。
3. 优化大文件解析,避免卡顿
LEI的XML文件通常都很大,一次性把整个文件加载到内存里肯定会卡顿。咱们用iterparse来迭代解析,处理完一个LEIRecord就释放它的内存,这样内存占用会非常低。
完整修正后的代码
from lxml import etree import pandas as pd # 定义XML命名空间,对应lei:前缀 NS_MAP = {'lei': 'http://www.gleif.org/data/schema/leidata/2016'} file_path = '20180104-gleif-concatenated-file-lei2.xml' parsed_data = [] # 用iterparse迭代解析,只监听元素结束事件,减少内存占用 for event, element in etree.iterparse( file_path, events=('end',), tag='{http://www.gleif.org/data/schema/leidata/2016}LEIRecord' ): record = {} # 提取LEI编码 lei_element = element.find('lei:LEI', NS_MAP) if lei_element is not None: record['LEI'] = lei_element.text.strip() # 如果你需要解析其他字段,比如法人名称,可以这样扩展: # entity_section = element.find('lei:Entity', NS_MAP) # if entity_section is not None: # legal_name = entity_section.find('lei:LegalName/lei:Name', NS_MAP) # if legal_name is not None: # record['LegalName'] = legal_name.text.strip() parsed_data.append(record) # 关键:清理当前元素,释放内存 element.clear() # 清理父节点的引用,彻底释放内存 while element.getprevious() is not None: del element.getparent()[0] # 转换为DataFrame lei_df = pd.DataFrame(parsed_data) print(lei_df.head())
代码关键点说明
- 命名空间处理:用
NS_MAP字典配合find方法,精准定位带lei:前缀的元素。 - 内存优化:
iterparse只处理每个LEIRecord的结束事件,处理完就清理元素,避免大文件占用过多内存。 - 避免错误:用
elem.text代替pyval,不会因为元素内容问题抛出AttributeError。
原代码的问题复盘
- 错误地使用了
root.INDICATOR,你的XML里根本没有这个元素,应该定位LEIRecord。 - 没有处理XML命名空间,导致找不到目标元素。
- 一次性加载整个XML到内存,大文件直接导致系统卡顿。
内容的提问来源于stack exchange,提问作者Martien Lubberink
相关产品推荐
相关产品推荐

