【发布时间】:2021-03-09 01:02:56
【问题描述】:
我正在尝试使用 python 库 lxml 解析 XML,并希望结果输出位于数据框中。我对 python 和解析比较陌生,所以在我概述问题时请多多包涵。我尝试解析的原始 xml 可用 here
我有兴趣在“invstOrSec”中找到一些相关标签。下面是“invstOrSec”的一个实例的快照,其中“curCd”标签附带的文本是美元。
<?xml version="1.0" encoding="UTF-8"?>
<invstOrSec>
<name>NIPPON LIFE INSURANCE</name>
<lei>549300Y0HHMFW3EVWY08</lei>
<curCd>USD</curCd>
<invstOrSec>
这个比较简单,我目前的做法是先在字典中定义相关标签,然后在循环中粗化成数据框。
import pandas as pd
from lxml import etree
# Declare directory
os.chdir('C:/Users/A1610222/Desktop/Form NPORT/pkg/sec-edgar-filings/0001548717/NPORT-P/0001752724-
20-040624')
# Set root
xmlfile = "filing-details.xml"
tree = etree.parse(xmlfile)
root = tree.getroot()
# Remove namespace prefixes
for elem in root.getiterator():
elem.tag = etree.QName(elem).localname
# Remove unused namespace declarations
etree.cleanup_namespaces(root)
# Set path
invstOrSec = root.xpath('//invstOrSec')
# Define tags to extract
vars = {'invstOrSec' : {'name', 'lei', 'curCd'}
# Extract holdings data
sec_info = pd.DataFrame()
temp = pd.DataFrame()
for one in invstOrSec:
for two in one:
if two.tag in vars['invstOrSec']:
temp[two.tag] = [two.text]
sec_info = sec_info.append(temp)
这是 sec_info
的前三行| name | lei | curCd |
|---|---|---|
| NIPPON LIFE INSURANCE | 549300Y0HHMFW3EVWY08 | USD |
| Lloyds Banking Group PLC | 549300PPXHEU2JF0AM85 | USD |
| Enbridge Inc | 98TPTUM4IVMFCZBCUR27 | USD |
但是,当货币不是美元时,xml 的结构略有不同。请参见下面的示例。
<?xml version="1.0" encoding="UTF-8"?>
<invstOrSec>
<name>ACHMEA BV</name>
<lei>7245007QUMI1FHIQV531</lei>
<currencyConditional curCd="EUR" exchangeRt="0.89150400"/>
<invstOrSec>
这一次 curCd 被替换为不同的标签 currencyConditional 并且它包含与文本相反的属性。我很难解释这些情况,同时保持我的代码尽可能通用。我希望我已经设法说明了这个问题。再次,如果这太初级,请原谅我。任何帮助将不胜感激。
【问题讨论】:
标签: python xml parsing lxml edgar