使用 xmltodict 解析无效 xml

parsing invalid xml using xmltodict

我正在读取 xml 文件并使用 xmltodict 和 pandas.

转换为 df

这是文件中的一个元素的样子

<net>
    <ref>https://whois.arin.net/rest/v1/net/NET-66-125-37-120-1</ref>
    <endAddress>66.125.37.127</endAddress>
    <handle>NET-66-125-37-120-1</handle>
    <name>SBC066125037120020307</name>
    <netBlocks>
        <netBlock>
            <cidrLenth>29</cidrLenth>
            <endAddress>066.125.037.127</endAddress>
            <type>S</type>
            <startAddress>066.125.037.120</startAddress>
        </netBlock>
    </netBlocks>
    <pocLinks/>
    <orgHandle>C00285134</orgHandle>
    <parentNetHandle>NET-66-120-0-0-1</parentNetHandle>
    <registrationDate>2002-03-08T00:00:00-05:00</registrationDate>
    <startAddress>66.125.37.120</startAddress>
    <updateDate>2002-03-08T07:56:59-05:00</updateDate>
    <version>4</version>
</net>

由于 API 正在拉入大量这样的记录,有时可以部分下载文件末尾的一些 <net> 对象。 例如:一个标签没有结束标签。

这是我为解析 xml

而写的
xml_data = open('/Users/dgoswami/Downloads/net.xml', 'r').read()  # Read data
xml_data = xmltodict.parse(xml_data,
                      process_namespaces=True,
                      namespaces={'http://www.arin.net/bulkwhois/core/v1':None})

发生这种情况时,我会收到类似这样的错误

no element found: line 30574438, column 37

我希望能够解析到最后一个有效的 <net> 元素。 怎么办?

您可能需要事先修复 xml - xmltodict 无法为您完成。

您可以按照 中所述利用 lxml 来修复您的 xml:

from lxml import etree

def fixme(x):
    p = etree.fromstring(x, parser = etree.XMLParser(recover=True))
    return etree.tostring(p).decode("utf8")


fixed = fixme("""<start><net>
<endAddress>66.125.37.127</endAddress>
<handle>NET-66-125-37-120-1</handle>
</net><net>
<endAddress>66.125.37.227</endAddress>
<handle>NET-66-125-37-220-1</handle>
""")

然后使用固定的xml:

import xmltodict

print(xmltodict.parse(fixed))

获得

OrderedDict([('start', 
    OrderedDict([('net', [
        OrderedDict([('endAddress', '66.125.37.127'), ('handle', 'NET-66-125-37-120-1')]), 
        OrderedDict([('endAddress', '66.125.37.227'), ('handle', 'NET-66-125-37-220-1')])
        ])
    ]))
])