Python:解析ESMA(欧洲金融管理局)XML文件

2024-09-30 01:18:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图解析此处找到的XML文件:

https://registers.esma.europa.eu/publication/searchRegister?core=esma_registers_fitrs_files

使用xml.etree.ElementTree.parse()

这些文件包含安全isin和MiFIR报告规则强制执行的交易量数据。你知道吗

我用findall()或find()找不到任何东西。在孩子和孙子孙女身上打圈似乎是可行的,但树的深度是疯狂的。你知道吗

我想提取每个“NonEqtyTrnsprncyData”节点的isin和数据。我试过了

from xml.etree.ElementTree import parse
tree = parse("FULNCR_20191005_D_1of10.xml")
root = tree.getroot()
elems = root.findall('NonEqtyTrnsprncyData')

只给我[]个元素。你知道吗

在我的第一次尝试中,对示例数据库使用相同的逻辑mondial-3.0.xml工作得非常完美。你知道吗

这里有没有人成功解析过ESMA xml文件,可以提高我的学习效率?你知道吗

xml文件的简短版本为:

<?xml version="1.0" encoding="UTF-8"?>
<BizData
    xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:head.003.001.01 head.003.001.01.xsd"
    xmlns="urn:iso:std:iso:20022:tech:xsd:head.003.001.01" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Hdr>
        <AppHdr
            xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:head.001.001.01 head.001.001.01_ESMAUG_1.0.0.xsd"
            xmlns="urn:iso:std:iso:20022:tech:xsd:head.001.001.01" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <Fr>
                <OrgId>
                    <Id>
                        <OrgId>
                            <Othr>
                                <Id>EU</Id>
                            </Othr>
                        </OrgId>
                    </Id>
                </OrgId>
            </Fr>
            <To>
                <OrgId>
                    <Id>
                        <OrgId>
                            <Othr>
                                <Id>Public</Id>
                            </Othr>
                        </OrgId>
                    </Id>
                </OrgId>
            </To>
            <BizMsgIdr>FULNCR_20191005_D_3of10</BizMsgIdr>
            <MsgDefIdr>auth.045.001.02</MsgDefIdr>
            <CreDt>2019-10-05T13:00:01Z</CreDt>
        </AppHdr>
    </Hdr>
    <Pyld>
        <Document
            xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:auth.045.001.02 auth.045.001.02_ESMAUG_DATNCR_1.1.0.xsd"
            xmlns="urn:iso:std:iso:20022:tech:xsd:auth.045.001.02" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <FinInstrmRptgNonEqtyTradgActvtyRslt>
                <RptHdr>
                    <RptgNtty>
                        <NtlCmptntAuthrty>EU</NtlCmptntAuthrty>
                    </RptgNtty>
                    <RptgPrd>
                        <FrDtToDt>
                            <FrDt>2019-10-05</FrDt>
                            <ToDt>2019-10-11</ToDt>
                        </FrDtToDt>
                    </RptgPrd>
                </RptHdr>
                <NonEqtyTrnsprncyData>
                    <TechRcrdId>1</TechRcrdId>
                    <Id>CH0110680714</Id>
                    <FinInstrmClssfctn>BOND</FinInstrmClssfctn>
                    <RptgPrd>
                        <FrDtToDt>
                            <FrDt>2018-01-01</FrDt>
                            <ToDt>2018-03-31</ToDt>
                        </FrDtToDt>
                    </RptgPrd>
                    <Lqdty>false</Lqdty>
                </NonEqtyTrnsprncyData>
            </FinInstrmRptgNonEqtyTradgActvtyRslt>
        </Document>
    </Pyld>
</BizData>

我删除了所有非qtytrnspncydata元素,只有一个。你知道吗


Tags: 文件idisoxmltechxsdstdxmlns
1条回答
网友
1楼 · 发布于 2024-09-30 01:18:39

这里有两个问题:

  • 只有标记名的Element.findall()只能从relevant documentation中找到直接子级

    Element.findall() finds only elements with a tag which are direct children of the current element.

    您希望在这里使用XPath expression;在标记名前面加上.//会告诉API在当前元素下的所有级别上搜索子元素

  • XML文档使用XML namespaces;您要查找的元素是urn:iso:std:iso:20022:tech:xsd:auth.045.001.02命名空间的一部分;这是在Document父元素上用xmlns="..."属性设置的,如下所示(忽略其他属性):

    <Document
        xmlns="urn:iso:std:iso:20022:tech:xsd:auth.045.001.02"
        >
    

    xmlns属性,带或不带前缀(例如xmlns:prefix)应用于定义它们的元素和整个子树,直到另一个这样的属性覆盖设置。你知道吗

    注意,像xsi这样的前缀通常是文档本地的,所以前缀是什么并不重要;名称空间是由URI命名的。

所以您需要使用名称空间,并且需要使用XPath表达式。使用(您自己的)前缀使编写XPath表达式更容易。这将找到您的元素:

namespace = 'urn:iso:std:iso:20022:tech:xsd:auth.045.001.02'
elems = tree.findall('.//ns:NonEqtyTrnsprncyData', {'ns': namespace})

您也可以使用.//{urn:iso:std:iso:20022:tech:xsd:auth.045.001.02}NonEqtyTrnsprncyData作为表达式,而不使用名称空间前缀和映射,但如果多次使用,就会变得非常冗长。你知道吗

您也不需要调用tree.getroot();您可以直接使用tree.findall(),因为我们使用的XPath表达式设计用于搜索整个树。你知道吗

演示:

>>> from xml.etree.ElementTree import parse
>>> tree = parse("FULNCR_20191005_D_1of10.xml")
>>> namespace = 'urn:iso:std:iso:20022:tech:xsd:auth.045.001.02'
>>> elems = tree.findall('.//ns:NonEqtyTrnsprncyData', {'ns': namespace})
>>> len(elems)
1
>>> elems[0]
<Element '{urn:iso:std:iso:20022:tech:xsd:auth.045.001.02}NonEqtyTrnsprncyData' at 0x109a84400>
>>> list(elems[0])
[<Element '{urn:iso:std:iso:20022:tech:xsd:auth.045.001.02}TechRcrdId' at 0x109a844a0>, <Element '{urn:iso:std:iso:20022:tech:xsd:auth.045.001.02}Id' at 0x109a84540>, <Element '{urn:iso:std:iso:20022:tech:xsd:auth.045.001.02}FinInstrmClssfctn' at 0x109a845e0>, <Element '{urn:iso:std:iso:20022:tech:xsd:auth.045.001.02}RptgPrd' at 0x109a84680>, <Element '{urn:iso:std:iso:20022:tech:xsd:auth.045.001.02}Lqdty' at 0x109a849a0>]

请注意,API返回的所有元素都有完全限定名;如果您有一个带有一组可变名称空间的文档,您可以从标记名中解析名称空间:

>>> prefix, has_namespace, remainder = elems[0].tag.partition("}")
>>> if has_namespace:
...     namespace, tag = prefix[1:], remainder
... else:
...     namespace, tag = None, prefix
...
>>> namespace, tag
('urn:iso:std:iso:20022:tech:xsd:auth.045.001.02', 'NonEqtyTrnsprncyData')

您可能还想看看^{} project,它构建在相同的elementtreeapi之上,但是速度更快,并且提供了更多的特性,例如更好的名称空间处理和完整的XPath 1.0支持(Python标准库ElementTree实现的限制更大)。你知道吗

相关问题 更多 >

    热门问题