Element Treeを使用してpythonでXMLを解析する方法の基本的な例を見つけるのに苦労しています。見つけることができるものから、これは解析に使用する最も簡単なライブラリのようですXML:私が使用している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
ここに私が試したことがいくつかありますが、どれも機能せず、timeSeries(または私が試した他の何か)が見つからなかったと報告しています:
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>)
実際のファイルには、気に入らないものがあると考えたため、機能するまで徐々に削除しました。変更した行は次のとおりです。
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の名前空間の詳細については、 このページ を参照してください。
だから私は今私のボックスに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が何らかの明らかな方法で壊れることはまずありません。エラーメッセージ、バックトレース、またはサポートに役立つ情報を入力して質問を更新してください。
あなたの質問を正しく理解できたら:
_for elem in doc.findall('timeSeries/values/value'):
print elem.get('dateTime'), elem.text
_
または、必要な場合(および_timeSeries/values
_が1つしか存在しない場合):
_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
_に変更すると、要素ツリー自体からも作業できるため、実際には必要ないことに注意してください)