2009-11-23 42 views
55

我很難找到一個很好的基本示例,說明如何使用Element Tree解析python中的XML。從我所能找到的,這似乎是用於解析XML的最簡單的庫。這裏是我正在使用的XML的示例:使用ElementTree在Python中解析XML示例

<timeSeriesResponse> 
    <queryInfo> 
     <locationParam>01474500</locationParam> 
     <variableParam>99988</variableParam> 
     <timeParam> 
      <beginDateTime>2009-09-24T15:15:55.271</beginDateTime> 
      <endDateTime>2009-11-23T15:15:55.271</endDateTime> 
     </timeParam> 
    </queryInfo> 
    <timeSeries name="NWIS Time Series Instantaneous Values"> 
     <values count="2876"> 
      <value dateTime="2009-09-24T15:30:00.000-04:00" qualifiers="P">550</value> 
      <value dateTime="2009-09-24T16:00:00.000-04:00" qualifiers="P">419</value> 
      <value dateTime="2009-09-24T16:30:00.000-04:00" qualifiers="P">370</value> 
      ..... 
     </values> 
    </timeSeries> 
</timeSeriesResponse> 

我能夠使用硬編碼方法來做我所需要的。但我需要我的代碼更具活力。這裏是什麼工作:

tree = ET.parse(sample.xml) 
doc = tree.getroot() 

timeseries = doc[1] 
values = timeseries[2] 

print child.attrib['dateTime'], child.text 
#prints 2009-09-24T15:30:00.000-04:00, 550 

這裏有幾件事情我已經試過,沒有他們的努力,報告說,他們找不到時間序列(或其他任何東西我試過):

tree = ET.parse(sample.xml) 
tree.find('timeSeries') 

tree = ET.parse(sample.xml) 
doc = tree.getroot() 
doc.find('timeSeries') 

基本上,我想加載XML文件,搜索timeSeries標籤,並遍歷值標籤,返回dateTime和標籤本身的值;在上面的例子中,我正在做的所有事情,但沒有硬編碼XML我感興趣的部分。任何人都可以指向我的一些例子,或者給我一些關於如何解決這個問題的建議?


感謝您的所有幫助。但是,對我提供的示例文件使用了以下兩個建議,但它們不能在完整文件上工作。下面是我從真實文件得到的,當我用埃德卡雷爾氏法的錯誤:

(<type 'exceptions.AttributeError'>, AttributeError("'NoneType' object has no attribute 'attrib'",), <traceback object at 0x011EFB70>) 

我想有什麼東西在裏面並沒有像真正的文件,所以我incremently去掉的東西,直到它的工作。以下是我更改的行:

originally: <timeSeriesResponse xsi:schemaLocation="a URL I removed" xmlns="a URL I removed" xmlns:xsi="a URL I removed"> 
changed to: <timeSeriesResponse> 

originally: <sourceInfo xsi:type="SiteInfoType"> 
changed to: <sourceInfo> 

originally: <geogLocation xsi:type="LatLonPointType" srs="EPSG:4326"> 
changed to: <geogLocation> 

刪除具有'xsi:...'的屬性已修復該問題。 'xsi:...'是不是有效的XML?我很難以編程方式刪除這些內容。任何建議的解決方法?

以下是完整的XML文件:http://www.sendspace.com/file/lofcpt


當我最初問這個問題,我不知道在XML命名空間。現在我知道發生了什麼,我不必刪除「xsi」屬性,這是名稱空間聲明。我只是將它們包含在我的xpath搜索中。有關lxml中命名空間的更多信息,請參閱this page

+0

可能我建議您查看'提供的'etree'模塊, lxml'?我最近發現它,發現它遠遠優於ElementTree。它被寫爲一個完全模擬ElementTree的替代品。 – jathanism

+0

我最終與lxml一起工作,因爲使用起來有點容易,但我仍然遇到上述問題。對於解決方法,我事先掃描xml文件並刪除所有「xsi:type」實例。以下答案中列出的方法可以正常工作。 – Casey

回答

40

所以我有ElementTree的1.2.6對我的盒子,現在,跑了反對您發佈的XML塊下面的代碼:

import elementtree.ElementTree as ET 

tree = ET.parse("test.xml") 
doc = tree.getroot() 
thingy = doc.find('timeSeries') 

print thingy.attrib 

,並得到了以下回:

{'name': 'NWIS Time Series Instantaneous Values'} 

看樣子找到timeSeries元素而不需要使用數字索引。

現在有用的是知道你的意思,當你說「它不工作」。由於在給定相同輸入的情況下它適用於我,ElementTree不太可能以某種明顯的方式被破壞。用任何錯誤消息,回溯或您可以提供的任何幫助我們幫助您的問題更新您的問題。

+28

對於新的Python版本,導入已更改爲:導入xml.etree.ElementTree作爲ET – Louis

+0

@Louis:「新版本的Python版本」是什麼意思? –

+0

@Monica Heddneck:因爲這個評論已經超過六年了,我應該說每個Python都超過2.3 ... – Louis

18

如果我理解正確你的問題:

for elem in doc.findall('timeSeries/values/value'): 
    print elem.get('dateTime'), elem.text 

或者如果你喜歡(如果存在的timeSeries/values只出現一次:

values = doc.find('timeSeries/values') 
for value in values: 
    print value.get('dateTime'), elem.text 

findall()方法返回所有匹配的元素列表,而find()只返回第一個匹配元素,第一個例子遍歷所有找到的元素,第二個遍歷values元素的子元素,在這種情況下導致相同結果。

但是,我沒有看到沒有找到timeSeries的問題來自哪裏。也許你只是忘記了getroot()電話? (請注意,您並不需要它,因爲如果將路徑表達式更改爲/timeSeriesResponse/timeSeries/values//timeSeries/values

+0

它很棒。我使用了'來自lxml import etree'模塊。 'doc = etree.parse('test.xml')' – 2015-04-11 06:51:31