2

一段时间以来,我一直在用头撞墙。根据文档,这应该很简单。我要做的就是读取 GPX 文件。然而,GPX 文件大量使用命名空间,这在理论上是有意义的。不过,我似乎无法让 ElementTree 阅读它们。这是我正在尝试使用的代码...

def loadGpx(self, sourceFile):
    ElementTree.register_namespace('gpx', 'http://www.topografix.com/GPX/1/1')
    eTree = ElementTree.ElementTree()
    eTree.parse(sourceFile)

    print eTree.findall('wpt')

要从这样的 GPX 文件中提取航点...

<?xml version="1.0" encoding="utf-8"?>
<gpx creator="Garmin Desktop App" version="1.1" 
    xsi:schemaLocation="http://www.topografix.com/GPX/1/1 
                    http://www.topografix.com/GPX/1/1/gpx.xsd 
                    http://www.garmin.com/xmlschemas/WaypointExtension/v1 
                    http://www8.garmin.com/xmlschemas/WaypointExtensionv1.xsd 
                    http://www.garmin.com/xmlschemas/TrackPointExtension/v1 
                    http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd 
                    http://www.garmin.com/xmlschemas/GpxExtensions/v3 
                    http://www8.garmin.com/xmlschemas/GpxExtensionsv3.xsd 
                    http://www.garmin.com/xmlschemas/ActivityExtension/v1 
                    http://www8.garmin.com/xmlschemas/ActivityExtensionv1.xsd 
                    http://www.garmin.com/xmlschemas/AdventuresExtensions/v1 
                    http://www8.garmin.com/xmlschemas/AdventuresExtensionv1.xsd" 
    xmlns="http://www.topografix.com/GPX/1/1" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:wptx1="http://www.garmin.com/xmlschemas/WaypointExtension/v1" 
    xmlns:gpxtrx="http://www.garmin.com/xmlschemas/GpxExtensions/v3" 
    xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" 
    xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3" 
    xmlns:abp="http://www.garmin.com/xmlschemas/ActivityExtension/v1" 
    xmlns:adv="http://www.garmin.com/xmlschemas/AdventuresExtensions/v1">

    <metadata>
        <link href="http://www.garmin.com">
          <text>Garmin International</text>
        </link>
        <time>2012-01-17T03:21:12Z</time>
        <bounds maxlat="45.708811283111572" maxlon="-121.3884991966188" 
                minlat="45.407062936574221" minlon="-121.54939779080451" />
    </metadata>

  <wpt lat="45.708682453259826" lon="-121.51224257424474">
    <time>2012-01-06T19:00:02Z</time>
    <name>1-State and First, start MHL</name>
    <sym>Bike Trail</sym>
    <extensions>
      <gpxx:WaypointExtension>
        <gpxx:DisplayMode>SymbolAndName</gpxx:DisplayMode>
      </gpxx:WaypointExtension>
    </extensions>
  </wpt>

  <wpt lat="45.615267734974623" lon="-121.43857721239328">
    <time>2012-01-07T15:38:14Z</time>
    <name>10-Right at fork staying on Huskey Rd</name>
    <sym>Bike Trail</sym>
    <extensions>
      <gpxx:WaypointExtension>
        <gpxx:DisplayMode>SymbolAndName</gpxx:DisplayMode>
      </gpxx:WaypointExtension>
    </extensions>
  </wpt>

诚然,它需要的不仅仅是print eTree.findall('wpt').,但如果我能做到这一点,我以前曾使用过 xml。那部分很容易。不过,这个命名空间的东西让我发疯了。

我提前谢谢你。这让我发疯了。

4

2 回答 2

3

register_namespace()控制序列化 XML 时使用的前缀,但不影响解析。

使用 ElementTree,可以这样做:

from xml.etree import ElementTree as ET

tree = ET.parse("gpx.xml")
for elem in tree.findall("{http://www.topografix.com/GPX/1/1}wpt"):
    print elem

结果输出:

<Element '{http://www.topografix.com/GPX/1/1}wpt' at 0x201c550>
<Element '{http://www.topografix.com/GPX/1/1}wpt' at 0x201c730>

使用lxml,您还可以使用它:

from lxml import etree

NSMAP = {"gpx": "http://www.topografix.com/GPX/1/1"}

tree = etree.parse("gpx.xml")
for elem in tree.findall("gpx:wpt", namespaces=NSMAP):
    print elem
于 2013-08-06T15:47:56.733 回答
2

为什么不直接使用现有的 GPX 库?

无耻的插件:使用 gpxpy https://github.com/tkrajina/gpxpy从您的文件中解析航点可以完美地工作:

import gpxpy

gpx_sample = """...your GPX sample here..."""

gpx = gpxpy.parse(gpx_sample)

for wpt in gpx.waypoints:
    print wpt.latitude, wpt.longitude

即使您不想使用该库,您也可以检查代码以了解它是如何解析 XML 文件的。

于 2013-08-06T06:21:54.160 回答