繁体   English   中英

在python中解析大型xml

[英]parse large xml in python

我有一个非常大的 xml 文件(大约 100mb),其中包含多个类似于此示例中的元素

<adrmsg:hasMember>
    <aixm:DesignatedPoint gml:id="ID_197095_1650420151927_74256">
        <gml:identifier codeSpace="urn:uuid:">084e1bb6-94f7-450f-a88e-44eb465cd5a6</gml:identifier>
        <aixm:timeSlice>
            <aixm:DesignatedPointTimeSlice gml:id="ID_197095_1650420151927_74257">
                <gml:validTime>
                    <gml:TimePeriod gml:id="ID_197095_1650420151927_74258">
                        <gml:beginPosition>2020-12-31T00:00:00</gml:beginPosition>
                        <gml:endPosition indeterminatePosition="unknown"/>
                    </gml:TimePeriod>
                </gml:validTime>
                <aixm:interpretation>BASELINE</aixm:interpretation>
                <aixm:featureLifetime>
                    <gml:TimePeriod gml:id="ID_197095_1650420151927_74259">
                        <gml:beginPosition>2020-12-31T00:00:00</gml:beginPosition>
                        <gml:endPosition indeterminatePosition="unknown"/>
                    </gml:TimePeriod>
                </aixm:featureLifetime>
                <aixm:designator>BITLA</aixm:designator>
                <aixm:type>ICAO</aixm:type>
                <aixm:location>
                    <aixm:Point gml:id="ID_197095_1650420151927_74260">
                        <gml:pos srsName="urn:ogc:def:crs:EPSG::4326">40.87555555555556 21.358055555555556</gml:pos>
                    </aixm:Point>
                </aixm:location>
                <aixm:extension>
                    <adrext:DesignatedPointExtension gml:id="ID_197095_1650420151927_74261">
                        <adrext:pointUsage>
                            <adrext:PointUsage gml:id="ID_197095_1650420151927_74262">
                                <adrext:role>FRA_ENTRY</adrext:role>
                                <adrext:reference_border>
                                    <adrext:AirspaceBorderCrossingObject gml:id="ID_197095_1650420151927_74263">
                                        <adrext:exitedAirspace xlink:href="urn:uuid:78447f69-9671-41c5-a7b7-bdd82c60e978"/>
                                        <adrext:enteredAirspace xlink:href="urn:uuid:afb35b5b-6626-43ff-9d92-875bbd882c05"/>
                                    </adrext:AirspaceBorderCrossingObject>
                                </adrext:reference_border>
                            </adrext:PointUsage>
                        </adrext:pointUsage>
                        <adrext:pointUsage>
                            <adrext:PointUsage gml:id="ID_197095_1650420151927_74264">
                                <adrext:role>FRA_EXIT</adrext:role>
                                <adrext:reference_border>
                                    <adrext:AirspaceBorderCrossingObject gml:id="ID_197095_1650420151927_74265">
                                        <adrext:exitedAirspace xlink:href="urn:uuid:78447f69-9671-41c5-a7b7-bdd82c60e978"/>
                                        <adrext:enteredAirspace xlink:href="urn:uuid:afb35b5b-6626-43ff-9d92-875bbd882c05"/>
                                    </adrext:AirspaceBorderCrossingObject>
                                </adrext:reference_border>
                            </adrext:PointUsage>
                        </adrext:pointUsage>
                    </adrext:DesignatedPointExtension>
                </aixm:extension>
            </aixm:DesignatedPointTimeSlice>
        </aixm:timeSlice>
    </aixm:DesignatedPoint>
</adrmsg:hasMember>

最终目标是在 pandas DataFrame 中解析来自这个非常大的 xml 文件的数据。

到目前为止,我无法“捕获”我正在寻找的数据。 我只设法从那个大 xml 文件中的最后一个元素中“捕获”最后一个数据。

import xml.etree.ElementTree as ET

tree = ET.parse('file.xml')
root = tree.getroot()

ab = {'aixm':'http://www.aixm.aero/schema/5.1.1', 'adrext':'http://www.aixm.aero/schema/5.1.1/extensions/EUR/ADR', 'gml':'http://www.opengis.net/gml/3.2'}
for point in root.findall('.//aixm:DesignatedPointTimeSlice', ab):
    designator = point.find('.//aixm:designator', ab)
    d = point.find('.//{http://www.aixm.aero/schema/5.1.1}type', ab)
for pos in point.findall('.//gml:pos', ab):
    print(designator.text, pos.text, d.text)

print 语句返回我想要的数据,但如前所述,仅针对文件的最后一个元素,而我希望为所有这些元素返回结果

ZIFSA 54.02111111111111 27.823888888888888 ICAO

我可以就我应该遵循的路径提出建议吗? 我需要一些帮助,非常感谢

假设所有三个需要的节点( aixm:designator、aixm:typegml:pos )始终存在,请考虑解析父节点aixm:DesignatedPointTimeSliceaxim:Point ,然后join它们。 最后,选择所需的最后三个列。

import pandas as pd

ab = {
    'aixm':'http://www.aixm.aero/schema/5.1.1', 
    'adrext':'http://www.aixm.aero/schema/5.1.1/extensions/EUR/ADR',
    'gml':'http://www.opengis.net/gml/3.2'
}

time_slice_df = pd.read_xml(
    'file.xml', xpath=".//aixm:DesignatedPointTimeSlice", namespaces=ab
).add_prefix("time_slice_")

point_df  = pd.read_xml(
    'file.xml', xpath=".//aixm:Point", namespaces=ab
).add_prefix("point_")

time_slice_df = (
    time_slice_df.join(point_df)
    .reindex(
        ["time_slice_designator", "time_slice_type", "point_pos"], 
        axis="columns"
    )
)

在即将发布的 pandas 1.5 中, read_xml将支持iterparse ,允许检索不限于 XPath 表达式的后代节点:

time_slice_df = pd.read_xml(
    'file.xml', 
    namespaces = ab, 
    iterparse = {"aixm:DesignatedPointTimeSlice": 
        ["aixm:designator", "axim:type", "aixm:Point"]
    }
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM