ElementTreeはpythonでXMLを扱うためのライブラリです。バージョン2.5からはpythonに標準で内蔵されています。
このライブラリを使うと、XMLをパースしてプログラム内で利用しやすい形に変換したり、XMLファイルを生成したりすることが出来ます。そこで今回は、XMLをパースして利用する方法についてまとめたいと思います。
Python2.5以降にはElementTreeが標準で内蔵されているため、パッケージを個別で入手する必要はありません。
以下のようにインポートするだけで利用できます。
from xml.etree.ElementTree import *
Python2.5より古いバージョンを利用している場合は、
からパッケージを入手し、以下のようにインポートして下さい。
from elementtree.ElementTree import *
今回の説明では、以下の内容のXMLファイルをサンプルとして扱います。
<window width="1920"> <title font="large" color="red">sample</title> <buttonbox> <button>OK</button> <button>Cancel</button> </buttonbox> </window>
ElementTreeを使う上でメインとなるのがElementというオブジェクトです。まずは、このElementの作成方法について以下に例を示します。
xmlString = '<window width="1920"><title font="large" color="red">sample</title><buttonbox><button>OK</button><button>Cancel</button></buttonbox></window>' elem = fromstring(xmlString) #ファイルから作成 tree = parse("sample.xml") elem = tree.getroot() # ルート要素を取得(Element型)
XMLを表す文字列からElementを作成するには、fromstringメソッドを呼び出します。WebAPIなどから取得したデータをパースしたい場合はこの方法を利用することが多いと思います。
また、XMLファイルからデータを読み込む場合はparseというメソッドを利用します。parseの返値はElementTree型となります。このElementTree型はXMLファイルからデータを読み込んだり、書き込んだりする際に利用されるラッパークラスです。ここでは、とりあえず上記の様にparseメソッドを呼んで、その後にgetrootメソッドを呼べばElement型のルート要素が取得できると覚えておけば問題ありません。
タグ名、属性(attribute)を参照する方法。
print elem.tag print elem.get("width") print elem.get("height", "1200") print elem.keys() print elem.items()
実行結果
window
1920
1200
['width']
[('width', '1920')]
条件にマッチする要素を検索する方法。
print elem.find(".//buttonbox").tag for e in elem.findall(".//button"): print e.tag print elem.findtext(".//button") print elem.find(".//button").text
実行結果
buttonboxbutton
buttonOK
OK
find,findall,findtextの引数にはXPath形式を利用することが出来ます。詳細については以下を参照して下さい。
http://effbot.org/zone/element-xpath.htm
XML内の要素を1つずつ参照する方法。
for e in elem.getiterator(): print e.tag for e in elem.getiterator("button"): print e.tag for e in list(elem): print e.tag
実行結果
window
title
buttonbox
button
buttonbutton
buttontitle
buttonbox
子要素と親要素の関係を保持する方法。公式のマニュアルではジェネレーターを定義する方法と、対応関係を保持するマップを作成してしまう方法が紹介されています。
def iterparent(elem): for parent in elem.getiterator(): for child in parent: yield parent, child for p,c in iterparent(elem): print c.tag+":"+p.tag parent_map = dict((c, p) for p in tree.getiterator() for c in p) for k in parent_map.keys(): print k.tag+":"+parent_map.get(k).tag
実行結果
title:window
buttonbox:window
button:buttonbox
button:buttonboxtitle:window
buttonbox:window
button:buttonbox
button:buttonbox
以上です。