PythonでElementTreeを使ってXMLを処理する方法 - hikm's blog

ElementTreeはpythonXMLを扱うためのライブラリです。バージョン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>

Elementの作成

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

実行結果
buttonbox

button
button

OK
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
button

button
button

title
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:buttonbox

title:window
buttonbox:window
button:buttonbox
button:buttonbox

以上です。