为什么 iterparse 会跳过此 OpenStreetMap 树的某些元素?
Why are some elements of this OpenStreetMap tree being skipped by iterparse?
我有一个捕获小社区的 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 .../>
元素都被正确读取,因为据我所知。
我在处理文件时注意到的另一件事是,当我在带有 'way'
标签的元素上使用 tostring()
时,如果读取 <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" />
这里发生了什么问题?
您似乎正在搜索响应 start
事件的子元素。但是子元素不一定已经被读取了。
考虑这个片段:
<a>foo<b/></a>
start
事件发生在解析器读取 <a>
之后,但在读取 foo
之前,更重要的是,在读取 <b/>
之前。正如 the documentation 所说:
Note iterparse() only guarantees that it has seen the “>” character of a starting tag when it emits a “start” event, so the attributes are defined, but the contents of the text and tail attributes are undefined at that point. The same applies to the element children; they may or may not be present.
If you need a fully populated element, look for “end” events instead.
因此,您可能会通过以下代码获得所需的行为:
for event, elem in CET.iterparse(osmfile,events = ('end',)):
我有一个捕获小社区的 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 .../>
元素都被正确读取,因为据我所知。
我在处理文件时注意到的另一件事是,当我在带有 'way'
标签的元素上使用 tostring()
时,如果读取 <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" />
这里发生了什么问题?
您似乎正在搜索响应 start
事件的子元素。但是子元素不一定已经被读取了。
考虑这个片段:
<a>foo<b/></a>
start
事件发生在解析器读取 <a>
之后,但在读取 foo
之前,更重要的是,在读取 <b/>
之前。正如 the documentation 所说:
Note iterparse() only guarantees that it has seen the “>” character of a starting tag when it emits a “start” event, so the attributes are defined, but the contents of the text and tail attributes are undefined at that point. The same applies to the element children; they may or may not be present.
If you need a fully populated element, look for “end” events instead.
因此,您可能会通过以下代码获得所需的行为:
for event, elem in CET.iterparse(osmfile,events = ('end',)):