Python
XML

Pythonで名前空間付きのXMLを操作する(ElementTree)

More than 3 years have passed since last update.


初めに

xml.etree.ElementTree

http://docs.python.jp/2/library/xml.etree.elementtree.html

を使って、名前空間付きのxmlを解析します。

本文ではkml(Google Earthなどに使われてるフォーマット)

http://ja.wikipedia.org/wiki/KML

をターゲットにしているが、実態はXMLなので同様に扱うとする。


対象データ


対象のKML

<?xml version='1.0' encoding='UTF-8'?>

<kml xmlns="http://earth.google.com/kml/2.0">
<Document>
<name>Hoge</name>
<Style id="Mapit">
<IconStyle>
<color>FFFFFFFF</color>
<scale>1.0</scale>
</IconStyle>
</Style>
<Style id="kml">
<LineStyle>
<color>FF0080FF</color>
<width>1</width>
</LineStyle>
<PolyStyle>
<color>AADDDDDD</color>
</PolyStyle>
</Style>
・・・
</Document>
</kml>

一部省略しているが、とりあえずこんな形をしているKMLを対象とする。

PolyStyle->color

の値がAADDDDDDになっていますが、これを変えたいとします。


プログラムコード


XML書き換えプログラム

# -*- coding: utf-8 -*-

from xml.etree import ElementTree

#KMLファイルを読み込み
tree = ElementTree.parse("in.kml")
#namespaceを付加する
#これをしないと再書き出しの際に、全てのタグにns0:PolyStyleみたいになる
ElementTree.register_namespace('', 'http://earth.google.com/kml/2.0')

# //PolyStyle/colorを探す
for node in tree.findall(".//{http://earth.google.com/kml/2.0}PolyStyle/{http://earth.google.com/kml/2.0}color"):
# 内容書き換え
node.text="AA001122"

#書き出し
#3つ目の引数はtrueなら<?xml ・・?>を付加する。
tree.write("out.kml","UTF-8",True)


PolyStyle->color

の値がAA001122となって書き出されます。


解説

xml.etree.ElementTree.findallは、頭に"."がいる。

(FutureWarningとか言われる)

XPathのサブセットが扱えるらしい。

http://docs.python.jp/3/library/xml.etree.elementtree.html

(Python2に関する記事は、見つけられてない)

ここで問題なのが名前空間である。


名前空間

<kml xmlns="http://earth.google.com/kml/2.0">


がルートにあるため、それ以下は全て名前空間がかかる。

なのでパスを指定するときは、{}内で名前空間を付加し、タグを指定しなけばならない。

しかもPolyStyle->colorなので2回書かないといけない。


xpath

//{http://earth.google.com/kml/2.0}PolyStyle/{http://earth.google.com/kml/2.0}color"


(なにかいい方法が有りましたら教えて下さい。。。)

次に、register_namespace をする意味は、

writeで書きだしたXMLが


register_namespaceをしない出力

<ns0:PolyStyle>

<ns0:color>AADDDDDD</ns0:color>
</ns0:PolyStyle>

みたいになるのを回避します。


ゆるぼ

register_namespaceしてるのでXPath指定がもっとスマート

(名前空間URIを何度も書かなくていいとか)に記述できないかなぁ。。。


参考

XPathで指定したテキストがある次の要素を取得する方法

http://qiita.com/yuki2006/items/1f96450fc744769872c5

[Python]ElementTreeのnamespaceをゴニョゴニョする

http://d.hatena.ne.jp/nullpobug/20110420/1303293319