2009-11-23 16 views
55

要素ツリーを使用してPythonで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> 

:ここでは私が働いているXMLのサンプルです。しかし、私はコードを少し動かす必要があります。ここで働いていたものです:ここでは

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タグを検索し、valueタグを繰り返し、dateTimeとタグ自体の値を返したいと思います。上の例でやっていることはすべてやっていますが、xmlのセクションをハードコーディングするのではなく、興味があります。誰かが私にいくつかの例を教えてもらえますか?


ありがとうございました。しかし、私が提供したサンプルファイルで作業した以下の両方の提案を使用しても、完全なファイルでは動作しませんでした。ここで私はエド・カレルの方法を使用する場合、私は本当のファイルから取得するエラーは次のとおりです。

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

私はそれが好きではなかった、実際のファイルに何かがあった考え出し、それが働いてまで、私はincremently物事を削除しました。ここに私が変更した行があります:

'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バージョンでは、インポートが次のように変更されました:ET xxx.etree.ElementTree as ET – Louis

+0

@Louis: '新しいPythonバージョン'とはどういう意味ですか? –

+0

@Monica Heddneck:このコメントは6歳以上だから、2.3以上のすべてのPythonを言いたいと思う。 – 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()は、最初に一致する要素のみを返します。最初の例は、見つかったすべての要素をループし、2番目のループはvalues要素の子要素をループします。結果。

timeSeriesが見つからない問題がどこから来るのかわかりません。たぶんあなたはgetroot()コールを忘れてしまったでしょうか? (パスの式を例えば/timeSeriesResponse/timeSeries/valuesまたは//timeSeries/valuesに変更すると、要素ツリー自体から作業することができるので、実際には必要ないことに注意してください)

+0

素晴らしい作品だ。私は 'from lxml import etree'モジュールと一緒に使っていました。 'doc = etree.parse( 'test.xml')' –