2013-09-21 176 views
2

我想解析從OCTranspo(渥太華市巴士公司)檢索使用Python的XML文件。我的問題是,我似乎無法訪問子域,如經度和緯度。Python的XML解析

下面是一個示例XML文件的嚴重縮短的版本,仍然導致問題:

<?xml version="1.0" encoding="utf-8"?> 
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<soap:Body> 

<Route xmlns="http://tempuri.org/"> 

<Trips> 
<Trip><TripDestination>Barrhaven Centre</TripDestination 
<TripStartTime>19:32</TripStartTime><Latitude>45.285458</Latitude 
<Longitude>-75.746786</Longitude></Trip> 
</Trips> 

</Route> 

</soap:Body> 
</soap:Envelope> 

這裏是我的代碼:

import xml.etree.ElementTree as ET 
import urllib 

u = urllib.urlopen('https://api.octranspo1.com/v1.1/GetNextTripsForStop', 'appID=7a51d100&apiKey=5c5a8438efc643286006d82071852789&routeNo=95&stopNo=3044') 
data = u.read() 

f = open('route3044.xml', 'wb') 
f.write(data) 
f.close() 

doc = ET.parse('route3044.xml') 

for bus in doc.findall('Trip'): 
    lat = bus.findtext('Latitude') 
    #NEVER EXECUTES 
    print trip 

如果我對一個執行相同的代碼非常簡單的xml文件(一個沒有soap:Envelope ...),那麼代碼完美無瑕。但是,由於我需要的xml是由OCTranspo生成的,我無法控制格式。

我不確定問題是Python中的'命名空間'問題還是bug。

任何援助將不勝感激。

更新:21九月,2013

我改變了搜索的緯度和經度此代碼:

doc = ET.parse('Stop1A.xml') 

for a in doc.findall('{http://schemas.xmlsoap.org/soap/envelope/}Body'): 
    for b in a.findall('{http://octranspo.com}GetNextTripsForStopResponse'): 
     for c in b.findall('{http://octranspo.com}GetNextTripsForStopResult'): 
      for d in c.findall('{http://tempuri.org/}Route'): 
       for e in d.findall('{http://tempuri.org/}RouteDirection'): 
        direction = e.findtext('{http://tempuri.org/}Direction') 
        if direction == 'Eastbound': 
         for f in e.findall('{http://tempuri.org/}Trips'): 
          for g in f.findall('{http://tempuri.org/}Trip'): 
           lat = g.findtext('{http://tempuri.org/}Latitude') 
           lon = g.findtext('{http://tempuri.org/}Longitude') 
           print lat + ',' + lon 
           print 'Done' 

最終的結果是,我現在可以看到「東向」公交車路線95.我知道這段代碼並不漂亮,但是它可以工作。我的下一個目標將是使用命名空間技巧進行優化。

如果有人在意嘗試訪問該網址,請注意,通常在5-7分鐘內看到「無巴士」,因爲該網址只是將最近的6條巴士返回到該站點。三條公共汽車東行,三條公共汽車西行。如果距離最近的巴士超過7分鐘,則返回爲空。該代碼返回公交車的緯度和經度 - 然後我可以使用Google地圖來繪製位置。

凱利

回答

2

按照ElementTree documentation

Element.findall()發現僅與一標籤,它是直接子當前元素的元件。 (強調)

幸運的是,ElementTree的具有XPath support

變化doc.findall('Trip')(通過文檔的直接子搜索)以doc.findall('.//Trip')(遞歸文檔的子搜索),如你預期它應該工作。

+0

感謝您的響應。不幸的是,這種改變沒有奏效。 – user2801100

+0

我站好了。我沒有追加名稱空間到搜索,所以這確實起作用。謝謝! – user2801100

1

以下是獲取每次旅行的緯度和經度的簡單方法。你不需要遍歷每個元素。請注意使用.//來查找全部{http://tempuri.org/}Trip元素。

import xml.etree.ElementTree as ET 

doc = ET.parse("temp.xml")  # Your shortened XML document 

for bus in doc.findall('.//{http://tempuri.org/}Trip'): 
    lat = bus.findtext('{http://tempuri.org/}Latitude') 
    lon = bus.findtext('{http://tempuri.org/}Longitude') 
    print lat, lon 

輸出:

45.285458 -75.746786 
+0

更加優雅。謝謝。我最近剛剛切換到Python,並發現它很好用。 – user2801100