LoginSignup
32
26

More than 5 years have passed since last update.

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

Last updated at Posted at 2015-03-16

初めに

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

32
26
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
26