2013-08-06 100 views
2

一段時間以來,我一直在撞牆。根據文件,這應該是簡單的。我想要做的就是讀一個GPX文件。但是,GPX文件寬泛地使用命名空間,理論上是有意義的。不過,我似乎無法讓ElementTree閱讀它們。這是我想使用的代碼...使用Python ElementTree.register_namespace讀取GPX?

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。這部分很容易。這個命名空間的東西,但是,讓我瘋狂。

我提前感謝你。這讓我瘋狂。

回答

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 
+0

這非常有用,明確了'register_namespace()'實際上做了什麼。序列化,如果我正確理解,只有在創建輸出時纔有用。對於我所做的,似乎gpxpy的解析器模塊實際上可能是一個很好的起點。不過,謝謝你幫忙澄清這一點。再次,Stackoverflow向我展示了我需要如何繼續! – knu2xs

1

爲什麼你不使用現有的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文件。

+0

是的,這是一個無恥插件和一個公平的問題。首先,我想了解如何使用它,因爲它適用於我正在開發的另一個項目。很多時候,這樣做是爲了學習。你使用了minidom,我想使用ElementTree,因爲我知道如何使用它,只要我能克服這個駝峯。其次,我不需要gpxpy中的所有東西。這最終會被ArcGIS插入,所以我擁有了我需要的用於分析的所有內容以及更多內容。結果,我需要的只是讀取這些標籤的能力。 – knu2xs

+0

順便說一句,我使用minidom只有lxml不可用(因爲lxml比minidom快得多)。 – puzz