xml.parsers.expatのよくわからない挙動
icon-naming-utilsに含まれる「legacy-icon-mapping.xml」をxml.parsers.expatを使ってパースし、
「link要素の値」->(「context要素のdir属性」, 「icon要素のname属性」)
となる辞書を返すpythonスクリプトを書いてみた。
iconmap2.py:
# -*- coding: utf-8 -*- from __future__ import with_statement from xml.parsers.expat import ParserCreate _cnt = "" _name = "" _data = "" _dict = {} def make(buf=False): """Make database which is accessible by Databese.dict""" global _cnt global _name global _data global _dict map_file = "/usr/share/icon-naming-utils/legacy-icon-mapping.xml" p = ParserCreate() p.buffer_text = buf p.StartElementHandler = start_element p.EndElementHandler = end_element p.CharacterDataHandler = char_data try: with open(map_file, 'rb') as f: p.ParseFile(f) except IOError, err: print err return _dict def start_element(name, attrs): global _cnt global _name if name == 'context': _cnt = attrs["dir"] if name == 'icon': _name = attrs["name"] _dict[_name] = (_cnt, _name) def end_element(name): global _cnt global _name global _data if name == 'link': _dict[_data] = (_cnt, _name) def char_data(data): global _data _data = data.strip()
legacy-icon-mapping.xml:
<?xml version="1.0" standalone="yes" ?> <!DOCTYPE mapping SYSTEM "legacy-icon-mapping.dtd"> <mapping> <context dir="actions"> <icon name="address-book-new"> <link>stock_new-address-book</link> </icon> <!-- 中略 --> <icon name="view-sort-descending"> <link>gtk-sort-descending</link> </icon> <!-- 中略 --> </context> <!-- 中略 --> </mapping>
>>> import mapdict2 >>> a = mapdict2.make() >>> a["stock_new-address-book"] (u'actions', u'address-book-new')
一見うまくいっているが実は反される辞書の一部のkeyが壊れており、インスタンスの「buffer_text」属性をTrueにすることでこれを防ぐことができる。
>>> reload(mapdict2) # reloadしないと次のmapdict2.make()でさっきのaも変更されてしまう。 >>> b = mapdict2.make(True) # 今度はbuffer_text=Trueで >>> set(b.keys())-set(a.keys()) # 辞書のkeyを比べてみると・・・、 set([u'stock_text_right', u'gnome-mime-application-vnd.stardivision.calc', u'gtk-sort-descending']) >>> set(a.keys())-set(b.keys()) set([u'rt-descending', u'ock_text_right', u'lc'])
buffer_text=True | buffer_text=False |
---|---|
stock_text_right | ock_text_right |
gnome-mime-application-vnd.stardivision.calc | lc |
gtk-sort-descending | rt-descending |
上記3つのkeyがおかしくなっていた。python 3.0でもこの結果は同じだった。これはやはりexpatのバグなのだろうか?
使用したpythonのバージョン: 2.5.2
2009/01/25追記
解決した