質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

Unicode

Unicodeはエンコーディングの標準規格です。1つの文字コード体系で多国語の表現を可能にすることを目指して作られています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

2回答

1392閲覧

lxmlのElementのattributeをunicodeとしてtostringしたい

hayataka2049

総合スコア30933

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

Unicode

Unicodeはエンコーディングの標準規格です。1つの文字コード体系で多国語の表現を可能にすることを目指して作られています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2018/04/13 02:13

編集2018/04/13 05:04

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="&#x3075;&#x304C;">フガ</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="&#x307B;&#x3052;"><fuga f="ふが"><piyo p="ぴよ"/></fuga></hoge>' 7>>> tree[0].attrib["h"] 8'ほげ'

これはlxmlのバグかもしれませんが、今のところ既知の報告や関連情報を見つけられていないので、もう少し調べて出てこなければバグレポートでも投げてみます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hayataka2049

2018/04/13 03:56

実はデバッグで出していて、どうやっても要素だけtostringするとうまくいかなかったという経緯での質問です。けっきょく実用上の不具合は回避できましたが、これはtostringの仕様ですかね・・・
defghi1977

2018/04/13 04:38

データ自体に損失は無いので, 適宜数値文字参照部を正規表現などで抽出し, 得られた文字コードから得られた文字に置換すればイケると思います. python 数値文字参照 でググると結構それらしきものがヒットしますし(デバッグのために処理を自作するというのもなんとも本末転倒な感じがしますが)
hayataka2049

2018/04/13 05:08

質問文に追記した通り、アクセス自体はElement.attrib経由でできました。デバッグの用は済みましたが、うーん・・
guest

回答2

0

Issue trackerには上がってなさそうですが、怪しい挙動ですね。でもソース(ココとかココ)を追っかけてると問題の根っこはlxmlを突き抜けてlibxmlに到達するんじゃないかなぁとちょっと思ったり。興味本位の野次馬ですが、ご参考までに。

投稿2018/04/14 11:07

YouheiSakurai

総合スコア6142

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hayataka2049

2018/04/14 11:27

調べていただきありがとうございます。根が深いのか・・・
st12491343

2018/08/16 18:04

あんな回答されたら皆回答しずらいですよね?どうするつもりですか?こっちは真剣に質問したんですけど、心外です。
st12491343

2018/08/16 18:28

脅してる文をスクショしておきます。ちゃんと謝罪をして下さい。言葉に責任を持ってください。後、無視はしないで下さい。
st12491343

2018/08/16 18:47

人間を人間が脅す行為覚悟決めて発言お願いします。
hayataka2049

2018/08/16 19:01 編集

とりあえず関係ないところにコメントするのはやめてくださいな。他の方に迷惑がかかります
YouheiSakurai

2018/08/17 02:27

べき論・責任論でゴリ押しする輩は相手にしないのが吉。
guest

0

I found if a node is not the root of its tree and you want to dump it as a root, then its attributes will not be parsed correctly. So the solution is:

python3

1etree.tostring(tree[0].__copy__(), encoding="utf-8").decode() 2>>> '<hoge h="ほげ"><fuga f="ふが"><piyo p="ぴよ"/></fuga></hoge>'

投稿2022/08/31 03:37

Bluemond

総合スコア6

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YouheiSakurai

2022/08/31 08:07

This is very interesting and awesome!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問