0

我有一个捕获一个小社区的 OSM 文件。 http://pastebin.com/xeWJsPeY

我有 Python 代码,它做了很多额外的解析,但这里可以看到一个主要问题的例子:

import xml.etree.cElementTree as CET
osmfile = open('osm_example.osm','r')
for event, elem in CET.iterparse(osmfile,events = ('start',)):
    if elem.tag == 'way':
        if elem.get('id') == "21850789":
            for child in elem:
                print CET.tostring(child,encoding='utf-8')
    elem.clear()

在这里和其他地方,我注意到缺少特定条目的标签(其中标签是一个看起来像的元素。据我所知, <tag k="highway" v="residential" />所有元素都被正确读取。<nd .../>

处理文件时我注意到的另一件事是,当我tostring()在带有'way'标签的元素上使用时,如果正在读取的元素有错误<tag .../>,它不会在其末尾附加换行符。例如,运行时

for event, elem in CET.iterparse(osmfile,events = ('start',)):
    if elem.tag == 'way':
        print CET.tostring(elem,encoding='utf-8')
    elem.clear()

<tag .../>缺少元素的条目的输出是

<nd ref="235476200" />
  <nd ref="1865868598" /></way><way changeset="12727901" id="21853023" timestamp="2012-08-14T15:23:13Z" uid="451048" user="bbmiller" version="8" visible="true">
  <nd ref="1865868557" />

与形成得很好的相比,

 <tag k="tiger:zip_left" v="60061" />
  <tag k="tiger:zip_right" v="60061" />
 </way>
 <way changeset="15851022" id="21874389" timestamp="2013-04-24T16:33:28Z" uid="451693" user="bot-mode" version="3" visible="true">
  <nd ref="235666887" />
  <nd ref="235666891" />

这里发生了什么问题?

4

1 回答 1

1

您似乎正在搜索子元素以响应该start事件。但是子元素还不一定被读取。

考虑这个片段:

<a>foo<b/></a>

start事件发生在解析器读取之后<a>,但在它读取之前foo,更重要的是,在它读取之前<b/>。正如文档所说:

请注意,iterparse() 仅保证它在发出“start”事件时看到了起始标记的“>”字符,因此定义了属性,但此时 text 和 tail 属性的内容未定义。这同样适用于子元素;它们可能存在也可能不存在。

如果您需要一个完全填充的元素,请寻找“结束”事件。

因此,您可能会使用此代码获得所需的行为:

for event, elem in CET.iterparse(osmfile,events = ('end',)):
于 2015-04-18T06:10:39.797 回答