1

我有一个 .gpx 文件,该文件在文件中间被截断。当我尝试使用gpxpy 库解析它时,我遇到了以下错误。

Parsing points in track.gpx
ERROR:root:expected '>', line 3125, column 29
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/gpxpy-0.8.7-py2.7.egg/gpxpy/parser.py", line 209, in parse
    self.xml_parser = LXMLParser(self.xml)
  File "/usr/local/lib/python2.7/dist-packages/gpxpy-0.8.7-py2.7.egg/gpxpy/parser.py", line 107, in __init__
    self.dom = mod_etree.XML(self.xml)
  File "lxml.etree.pyx", line 2734, in lxml.etree.XML (src/lxml/lxml.etree.c:54411)
  File "parser.pxi", line 1578, in lxml.etree._parseMemoryDocument (src/lxml/lxml.etree.c:82748)
  File "parser.pxi", line 1457, in lxml.etree._parseDoc (src/lxml/lxml.etree.c:81546)
  File "parser.pxi", line 965, in lxml.etree._BaseParser._parseDoc (src/lxml/lxml.etree.c:78216)
  File "parser.pxi", line 569, in lxml.etree._ParserContext._handleParseResultDoc (src/lxml/lxml.etree.c:74472)
  File "parser.pxi", line 650, in lxml.etree._handleParseResult (src/lxml/lxml.etree.c:75363)
  File "parser.pxi", line 590, in lxml.etree._raiseParseError (src/lxml/lxml.etree.c:74696)
XMLSyntaxError: expected '>', line 3125, column 29

File "gpxscript.py", line 370, in extractpoints gpx = gpxpy.parse(file)
File "/usr/local/lib/python2.7/dist-packages/gpxpy-0.8.7-py2.7.egg/gpxpy/__init__.py",
     line 28, in parse raise mod_gpx.GPXException('Error parsing {0}: {1}'
                       .format(xml_or_file[0 : 100], parser.get_error()))
TypeError: 'file' object has no attribute '__getitem__'

这些是产生错误的脚本的相关命令。

368  file = open(filepath)
369  try:
370      gpx = gpxpy.parse(file)
371  except gpxpy.gpx.GPXException:
372      print "GPXException for %s." % filepath
373      return 1

我按照建议为图书馆提交了一个错误。我在产生语法错误的错误报告中添加了一个示例文件。

4

1 回答 1

2

这似乎是gpxpy的错误处理中的错误。

查看源代码parse,当解析器失败但未引发异常时,它会尝试通过以下方式引发异常:

raise mod_gpx.GPXException('Error parsing {0}: {1}'.format(xml_or_file[0 : 100], parser.get_error()))

这假定它xml_or_file是一个 XML 字符串,但顾名思义,它既可以是字符串也可以是文件对象。所以,你正在做的事情(给它一个文件对象)是完全合法的,应该可以工作,但它没有,因此这是一个错误。

所以,你应该提出一个问题。正确的补丁应该是这样的:

if not parser.is_valid():
    try:
        fragment = xml_or_file[0 : 100]
    except TypeError:
        xml_or_file.seek(0)
        fragment = xml_or_file.read(100)
    raise mod_gpx.GPXException('Error parsing {0}: {1}'.format(fragment, parser.get_error()))

那么,你如何解决这个问题?几个选项:

  1. 由于无论如何它只会发生在无效文件上,因此您可以使用except Exceptionor except (gpxpy.gpx.GPXException, TypeError)

  2. 因为它只在你给它一个文件对象时发生,所以给它一个字符串:gpx = gpx.parse(file.read()). 当然,如果文件非常大,这是一个坏主意。

  3. 由于buggy函数只是封装了real函数的12行琐碎代码,所以直接使用real函数即可。或者,如果您喜欢包装器,请将其复制、修复,然后使用您自己的副本。


同时,鉴于我在这个库中看到的第一段代码有一些明显的危险信号(为什么xml_or_file[0 : 100]而不是仅仅xml_or_file[:100]?为什么要捕获异常,将它们丢弃并设置一个标志,然后使用该标志引发一个新的异常缺少所有信息?),如果您不能自己调试库,我认为这个库不适合您使用。

于 2013-04-24T20:33:48.357 回答