我正在尝试使用Python解析从OCTranspo(渥太华城市公交公司)检索到的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中的错误。
任何帮助都将不胜感激。
更新:2013年9月21日
我将搜索Lat和Lon的代码更改为:
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分钟,则返回为空。代码返回总线的Lat和Lon - 然后我可以使用Google Maps绘制位置。
凯利
答案 0 :(得分:2)
Element.findall()仅查找带有当前元素的直接子项标记的元素。 (强调添加)
幸运的是,ElementTree有XPath support
将doc.findall('Trip')
(搜索doc的直接子级)更改为doc.findall('.//Trip')
(以递归方式搜索doc的子级),它应该按预期工作。
答案 1 :(得分: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