Python で XML を扱うときのお話し。わりとはまったので備忘録をかねて。
Python 2.5 以降であれば XML を扱うのに便利なモジュール ElementTree が内蔵されています。で、これを使って XML を読み込もうと思ったのですが…なぜか期待した通りに動作しない。具体的には findall で何もヒットしない。
で、しばらく悩んでもわからないので iterator で全出力をしてみたら…
from xml.etree import ElementTree d=ElementTree.parse(open(filename,'rb')) for i in d.getroot(): print i.tag
以下のように出力されました。
{http://URL}Header
{http://URL}Body
最初見た瞬間なんじゃこりゃ⁉と叫んだのはわりと内緒です。
で、しばらく悩んで、いろんな人に相談した結果…URL の中身は xmlns の値(ネームスペース)で、どうやら XML というのはそういうものらしい。とのこと。
とはいえ、これじゃ若干めんどくさいのでいったん読み込んで、xmlns の中身を削除して、ElementTree はデータを引数として渡すことは出来ないっぽいので、cStringIO で…というわりと面倒な方法で対処しました。
import re, cStringIO from xml.etree import ElementTree xmlns_re = re.compile(r'^(.*?xmlns=")(.*?)(".*)$', re.I|re.S) fp=open(filename,'rb') data=fp.read() fp.close() data=xmlns_re.sub(r'\1\3', data) fp=cStringIO.StringIO(data) d=ElementTree.parse(fp) fp.close()
もう少しうまいやり方がありそうだけど…XML はめんどくさいな(^^ゞ