使用 for 循环解析深度嵌套的 xml 文件

Parsing a deeply nested xml file using a for loop

如何有效地从嵌套 xml 中提取数据? 所谓高效,我的意思是例如使用 for 循环。 我需要使用新的数据结构吗?

解析函数:

import xml.etree.ElementTree as ET

it = ET.iterparse('OTA_AirSeatMapRS.xml')

# This for loop removes the namespaces
for _, el in it:
    _, _, el.tag = el.tag.rpartition('}')
root = it.root

# I am not able to select data with this loop
for x in element.find(Service):
    print(x)

这是 XML 文件的一部分:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <ns:OTA_AirSeatMapRS Version="1"
            xmlns:ns="http://www.opentravel.org/OTA/2003/05/common/">
            <ns:Success/>
            <ns:SeatMapResponses>
                <ns:SeatMapResponse>
                    <ns:FlightSegmentInfo DepartureDateTime="2020-11-22T15:30:00" FlightNumber="1179">
                        <ns:DepartureAirport LocationCode="LAS"/>
                        <ns:ArrivalAirport LocationCode="IAH"/>
                        <ns:Equipment AirEquipType="739"/>
                    </ns:FlightSegmentInfo>
                    <ns:SeatMapDetails>
                        <ns:CabinClass Layout="AB EF" UpperDeckInd="false">
                            <ns:RowInfo CabinType="First" OperableInd="true" RowNumber="1">
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="1" ExitRowInd="false" GalleyInd="false" GridNumber="1" PlaneSection="Left">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="1A"/>
                                    <ns:Features>Window</ns:Features>
                                </ns:SeatInfo>

我的最终目标是使用解析后的数据存储在JSON。

查看代码中的以下指令:

for x in element.find(Service):

您的代码示例中的第一个缺陷是:

  • 服务是一个变量(不是字符串文字),
  • 可能您将此变量初始化为某个字符串,但失败了 将此说明放入您的代码示例中。

另一个缺陷的来源是 find 找到了 first 元素 匹配给定的路径,所以你不应该在循环中使用它。 也许您还应该检查 find 是否返回了一些 not-None 内容,但这是另一个细节。

你得到空输出的第三个原因是 print(x) 实际上只打印相关元素的 text

所以举一个更一般的例子,运行:

Service = 'Summary'
x = root.find(f'.//{Service}')
print(f'{x.tag}, {x.text}, {x.attrib}')

第一条指令设置标签名称。

第二条指令调用find,但注意我添加了'.//' 到 XPath,查看源 XML 树的 任何深度

最后一条指令不仅打印找到的元素的文本, 还有标签名称和属性。

我得到的结果(对于你的输入XML)是:

Summary, None, {'AvailableInd': 'false', 'InoperativeInd': 'false', 'OccupiedInd': 'false', 'SeatNumber': '1A'}

(text 只是 None,所以您在原始文件中没有看到任何结果 输出)。