lxmlを使ってattributeに日本語が含まれるXMLの処理をしています。
ツリー全体に対してtostringをすると上手くいきますが、単一のElementを対象に処理するとattributeの日本語をうまく変換することができません。
以下のような状況です。
python
1>>> from lxml import etree 2>>> root = etree.fromstring('<hoge><fuga f="ふが">フガ</fuga></hoge>') 3>>> etree.tostring(root, encoding="utf-8").decode() 4'<hoge><fuga f="ふが">フガ</fuga></hoge>' # うまいく 5>>> etree.tostring(root.xpath("//fuga")[0], encoding="utf-8").decode() 6'<fuga f="ふが">フガ</fuga>' # これだと駄目
このような場合、どのように取り扱うのが適当でしょうか?
よろしくおねがいします。
追記
色々試してみたところ、Element.attrib["f"]でアクセスすると日本語(ユニコード文字)になるようでした。また、「取り出されたもののルート」だけ数値文字参照に化けることが判明しました。
python
1>>> from lxml import etree 2>>> tree = etree.fromstring('<root><hoge h="ほげ"><fuga f="ふが"><piyo p="ぴよ"></piyo></fuga></hoge></root>') 3>>> etree.tostring(tree, encoding="utf-8").decode() 4'<root><hoge h="ほげ"><fuga f="ふが"><piyo p="ぴよ"/></fuga></hoge></root>' 5>>> etree.tostring(tree[0], encoding="utf-8").decode() 6'<hoge h="ほげ"><fuga f="ふが"><piyo p="ぴよ"/></fuga></hoge>' 7>>> tree[0].attrib["h"] 8'ほげ'
これはlxmlのバグかもしれませんが、今のところ既知の報告や関連情報を見つけられていないので、もう少し調べて出てこなければバグレポートでも投げてみます。
単なる数値文字参照であって, 実用上何ら問題がないと思いますが何か不具合でもあるのでしょうか? https://ja.wikipedia.org/wiki/%E6%96%87%E5%AD%97%E5%8F%82%E7%85%A7
実はデバッグで出していて、どうやっても要素だけtostringするとうまくいかなかったという経緯での質問です。けっきょく実用上の不具合は回避できましたが、これはtostringの仕様ですかね・・・
データ自体に損失は無いので, 適宜数値文字参照部を正規表現などで抽出し, 得られた文字コードから得られた文字に置換すればイケると思います. python 数値文字参照 でググると結構それらしきものがヒットしますし(デバッグのために処理を自作するというのもなんとも本末転倒な感じがしますが)
質問文に追記した通り、アクセス自体はElement.attrib経由でできました。デバッグの用は済みましたが、うーん・・