2

我有一个带有如下节点的 XML 文件:

<trkpt lat="-37.7944415" lon="144.9616159">
  <ele>41.3681107</ele>
  <time>2015-04-11T03:52:33.000Z</time>
  <speed>3.9598</speed>
</trkpt>

我正在使用 lxml.etree.iterparse() 迭代解析树。我循环遍历每个 trkpt 元素的子节点,并希望打印子节点的文本值。例如

for event, element in etree.iterparse(infile, events=("start", "end")):
    if element.tag == NAMESPACE + 'trkpt':
        for child in list(element):
            print child.text

问题是在这个阶段节点没有文本,所以打印的输出是'None'。

我已经通过用'print etree.tostring(child)'替换'print child.text'语句来验证这一点,输出看起来像这样

<ele/>
<time/>
<speed/>    

根据文档,“请注意,在收到开始事件时,元素的文本、尾部和子项不一定存在。只有结束事件才能保证元素已被完全解析。”

所以我把我的for循环改成了这个,注意'if event == "end":'语句

for event, element in etree.iterparse(infile, events=("start", "end")):
    if element.tag == NAMESPACE + 'trkpt':
        if event == "end":
            for child in list(element):
                print child.text

但我仍然得到相同的结果。任何帮助将不胜感激。

4

2 回答 2

1

你确定你不会element.clear()像这样在你的条件语句之后调用 eg 吗?

for event, element in etree.iterparse(infile, events=("start", "end")):
  if element.tag == NAMESPACE + 'trkpt' and event == 'end':
    for child in list(element):
        print child.text
  element.clear()

问题是解析器在发送事件之前为子元素发出end事件trkpt(因为它首先遇到嵌套元素的结束标记)。如果在end为外部元素调用事件之前对已解析的元素进行任何修改,则可能会发生您描述的行为。

考虑以下替代方案:

for event, element in etree.iterparse(infile, events=('end',),
    tag=NAMESPACE + 'trkpt'):
  for child in element:
     print child.text
  element.clear()
于 2015-11-22T16:11:42.180 回答
0

您是尝试显式使用 iterparse 还是可以使用其他方法。

e.g.

from lxml import etree

tree = etree.parse('/path/to/file')
root = tree.getroot()
for elements in root.findall('trkpt'):
    for child in elements:
        print child.text

lxml 非常擅长解析并且不会占用太多内存......不确定这是否解决了您的问题,或者您是否正在尝试使用上述特定方法。

于 2015-05-13T17:04:00.583 回答