XPathでnamespaceにハマった。
lxml で XPath 使ってる時に namespace でハマったのでメモ。 ありがちなところでハマった。 恥さらしの為にもメモりますです。
どんなところでハマったかと言うと、 例えばこんな感じの test.xml なXMLがありまして、
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://example.com/hoge/1.0">
<child>
<type>1</type>
<name>hoge</name>
</child>
<child>
<type>1</type>
<name>hige</name>
</child>
<child>
<type>0</type>
<name>hage</name>
</child>
</root>
これを lxml でパースしてやろうとした訳です。 で、何も考えずにこんな事したら中身が取れなかった。
>>> from lxml import etree
>>> xml = etree.parse(open('test.xml', 'r'), parser=etree.XMLParser())
>>> xml
<etree._ElementTree object at 0x1290940> # ココは取れてる。
>>> root = xml.getroot()
>>> root
<Element {http://example.com/hoge/1.0}root at 1236c60> # ココもOK。
>>> # ココからが問題。
>>> root.xpath('./child')
[] # 空っぽ?
仕事中に色々試してみるも、 結局 namespace の指定の仕方が解らず撃沈。 が、家に帰ってきてから本家のドキュメント見てみると、 あっさりやり方が書いてあった。 どうやら xpath の第2引数で、 namespace を指定出来るらしい。
>>> root.xpath('./n:child', namespaces={'n':'http://example.com/hoge/1.0'})
[<Element {http://example.com/hoge/1.0}child at 1292fc0>,
<Element {http://example.com/hoge/1.0}child at 1292ea0>,
<Element {http://example.com/hoge/1.0}child at 1297030>]
>>>
>>> root.xpath('./n:child/n:name/text()', namespaces={'n':'http://example.com/hoge/1.0'})
['hoge', 'hige', 'hage']
とりあえず、めでたく XPath での問い合わせが出来た ![]()
それにしても恥ずかしいな。この凡ミス。 なんで本家のドキュメントを読もうと思わなかったんだろ? そこが本当に不思議。
- Posted at:
- 2007/12/25 23:46:20
- 4 Comments
- 1 TrackBack
- Trackback:
- http://humming.via-kitchen.com/2007/12/25/namespace-trap-on-xpath/trackback/
TrackBacks
[Django][Python][jQuery][その他]巡回 - 常山日記
Django Snippets: noemptylines packjs templatetag Blog: なにも知らないけど、Pythonって面白そうだからやってみるシリーズ。 Просмотр SQL запросов, сделанных Django ORM Installing Django with PostgreSQL on Ubuntu Some django stuff Let
- Created at:
- 2007/12/27 02:07:01
Comments
aodag
./*[local-name() = 'child' and namespace-uri() = 'http://example.com/hoge/1.0']
でも取れたと思うよ
nobu
おお!まじですか!
XPathはまだまだ解らない事だらけです。
kishir
参考に見させてもらっているのですが、
最後のnamespaces内の「,」は「:」ですよね?
さぁ〜俺も「enjoy! lxml」
nobu
まさしくその通りですな!
さっそく訂正させて頂きます。