【问题标题】:How to fetch data dynamically from xml file by tag and nested tag using python?如何使用python通过标签和嵌套标签从xml文件中动态获取数据?
【发布时间】:2019-12-11 17:05:54
【问题描述】:

我有一个 xml 文件 details.xml,xml 文件看起来像这样,

<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="Overpass API 0.7.55.7 8b86ff77">
<meta osm_base="2019-08-02T12:21:02Z"/>

<bounds minlat="19.0983000" minlon="72.8890000" maxlat="19.1184000" maxlon="72.9206000"/>

<node id="245670274" lat="19.1000660" lon="72.8961407" version="5" timestamp="2015-10-27T04:31:16Z" changeset="34895909" uid="3339404" user="Anushka&amp;saroj">
<tag k="AND_a_nosr_p" v="10004762"/>
<tag k="name" v="Kulkarni Wadi"/>
<tag k="place" v="locality"/>
<tag k="source" v="AND"/>
</node>

<node id="245670576" lat="19.1030072" lon="72.8885419" version="4" timestamp="2017-11-22T06:20:01Z" changeset="53992152" uid="1306" user="PlaneMad">
<tag k="source" v="AND"/>
</node>

<node id="619199656" lat="19.1023916" lon="72.9200375" version="3" timestamp="2015-07-03T06:26:42Z" changeset="32379895" uid="2897305" user="Ashok09"/>

<way id="353138857" version="2" timestamp="2015-06-12T10:57:15Z" changeset="31917729" uid="2900596" user="harisha">
<nd ref="3589055782"/>
<nd ref="3589055908"/>
<nd ref="3589055924"/>
<nd ref="3589055914"/>
<nd ref="3589055921"/>
<nd ref="3589055916"/>
<nd ref="3589055922"/>
<nd ref="3589055909"/>
<nd ref="3589055913"/>
<nd ref="3589055904"/>
<nd ref="3589055782"/>
<tag k="building" v="yes"/>
</way>
</osm>

我想获取'node'标签内的所有信息并忽略所有其他内容,

对于上述 xml 中的示例,我们有 3 个“节点”标签,我想要每个标签中的所有嵌套(如果可用,否则可用)信息。

如果我将这些信息存储在列表中,结果应该是这样的,

ids=['245670576','245670576','619199656'] 
lat=['19.1000660','19.1030072','19.1023916']
lon=['72.8961407','72.8885419','72.9200375']
k=[['AND_a_nosr_p','name','place','source'],['source'],[]]
v=[['10004762','Kulkarni Wadi','locality','AND'],['AND'],[]]

如何使用 python 以最有效的方式做到这一点?

【问题讨论】:

  • 将所有后续数据关联到每个单独的节点 - 最好将其存储在字典中,你不觉得吗?
  • @RomanPerekhrest 我也可以将它存储在字典中,我需要先获取数据,怎么做?
  • 您的 xml 缺少 &lt;osm&gt; 的结束标记。

标签: python xml python-3.x xml-parsing


【解决方案1】:

扩展解决方案:

import pprint
from xml.etree.ElementTree import ElementTree as ET

tree = ET().parse(source='input.xml')
nodes_data = {}
for node in tree.findall('./node'):
    k = 'node_' + node.attrib['id']   # custom node key
    nodes_data[k] = node.attrib
    tag_attribs = list(zip(*[tag.attrib.items() for tag in list(node)]))
    if not tag_attribs:
        nodes_data[k].update({'k': [], 'v': []})
    else:
        k_items, v_items = zip(*[tag.attrib.items() for tag in list(node)])
        nodes_data[k].update({'k': [t[1] for t in k_items], 'v': [t[1] for t in v_items]})

pprint.pprint(nodes_data)

实际输出:

{'node_245670274': {'changeset': '34895909',
                    'id': '245670274',
                    'k': ['AND_a_nosr_p', 'name', 'place', 'source'],
                    'lat': '19.1000660',
                    'lon': '72.8961407',
                    'timestamp': '2015-10-27T04:31:16Z',
                    'uid': '3339404',
                    'user': 'Anushka&saroj',
                    'v': ['10004762', 'Kulkarni Wadi', 'locality', 'AND'],
                    'version': '5'},
 'node_245670576': {'changeset': '53992152',
                    'id': '245670576',
                    'k': ['source'],
                    'lat': '19.1030072',
                    'lon': '72.8885419',
                    'timestamp': '2017-11-22T06:20:01Z',
                    'uid': '1306',
                    'user': 'PlaneMad',
                    'v': ['AND'],
                    'version': '4'},
 'node_619199656': {'changeset': '32379895',
                    'id': '619199656',
                    'k': [],
                    'lat': '19.1023916',
                    'lon': '72.9200375',
                    'timestamp': '2015-07-03T06:26:42Z',
                    'uid': '2897305',
                    'user': 'Ashok09',
                    'v': [],
                    'version': '3'}}

【讨论】:

    【解决方案2】:

    您可以使用lxml 来完成这项工作。
    它有一个您可以使用的findall() 方法。
    然后你可以遍历它的attrib 并将它们解析成list

    【讨论】:

    • 我试过了,但是有问题,你能写一个模板吗?
    【解决方案3】:

    我建议使用

    xml.etree.ElementTree

    我无法解析您的 xml 代码副本。我认为这个副本有一个标签关闭问题。 但总的来说,我会使用类似的东西:

    import xml.etree.ElementTree as et
    
    tree = et.parse('PATH TO XML FILE')
    root = tree.getroot()
    
    ids = []
    lat = []
    
    for element in root.findall('node'):
        id = element.attrib['id']
        ids.append(id)
        lat = element.attrib['lat']
        ids.append(lat)
    

    请注意,此代码未经测试。如有错误,我深表歉意。

    【讨论】:

      【解决方案4】:

      试试这个:

      import lxml.html
      
      xml  = [your xml above]
      
      tree = lxml.html.fromstring(xml)
      
      ids= tree.xpath('//node/@id')
      lat = tree.xpath('//node/@lat')
      lon = tree.xpath('//node/@lon')
      k = tree.xpath('//node/tag/@k')
      v = tree.xpath('//node/tag/@v')
      
      print(ids)
      print(lat)
      print(lon)
      print(k)
      print(v)
      

      输出:

      ['245670274', '245670576', '619199656']
      ['19.1000660', '19.1030072', '19.1023916']
      ['72.8961407', '72.8885419', '72.9200375']
      ['AND_a_nosr_p', 'name', 'place', 'source', 'source']
      ['10004762', 'Kulkarni Wadi', 'locality', 'AND', 'AND']
      

      【讨论】:

      • 第三个和第四个列表也应该有3个元素,列表列表
      猜你喜欢
      • 2014-05-09
      • 2022-11-25
      • 1970-01-01
      • 1970-01-01
      • 2011-09-05
      • 1970-01-01
      • 2020-05-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多