1

xml.etree を使用して、€ 記号を含む xml ファイルを読み書きしようとしています。

私の簡略化されたコードは次のようになります。

optionsdirectory = os.getcwd()
optionsfile = os.path.join(optionsdirectory, "conf")
optionstree = ET.parse(optionsfile)
options = optionstree.getroot()
for option in options:
    if option.tag == "currency":
        option.text = "€"
optionstree.write(optionsfile, encoding="UTF-8")

実行すると次のエラーが表示されます。

File "C:\curr.py", line 8
    optionstree.write(optionsfile, encoding="UTF-8")
File "C:\Python27\lib\xml\etree\ElementTree.py", line 815, in write
    serialize(write, self._root, encoding, qnames, namespaces)
File "C:\Python27\lib\xml\etree\ElementTree.py", line 934, in _serialize_xml
    _serialize_xml(write, e, encoding, qnames, None)
File "C:\Python27\lib\xml\etree\ElementTree.py", line 932, in _serialize_xml
    write(_escape_cdata(text, encoding))
File "C:\Python27\lib\xml\etree\ElementTree.py", line 1068, in _escape_cdata
    return text.encode(encoding, "xmlcharrefreplace")
UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 2114: ordinal not in range(128)

xml.etree を使用して € 記号を xml ファイルに書き込む方法はありますか?

4

3 に答える 3

6

Unicodeリテラルを使用する必要があります。文字の代わりにUnicodeエスケープを使用する方が簡単です。

option.text = u"\u20AC"  # Euro sign

Unicodeリテラルを使用せず、代わりにバイト(文字列)リテラルを使用すると、PythonはデフォルトのエンコーディングであるASCIIを使用して値をUnicodeリテラルにデコードしようとします。これにより、表示されたUnicodeDecodeErrorが発生します。

エスケープされていない文字を本当に使用たい場合は、ソースファイルのエンコーディングを上部に指定してください。

# -*- coding: utf-8 -*-

エディターがUTF-8を使用してファイルを保存していることを確認してください。ただし、Unicodeリテラルを使用する必要があります。

option.text = u"€"
于 2012-09-29T19:39:10.583 に答える
0

非 ASCII 文字を含む XML ファイルを作成する方法を次に示します。# coding:で宣言されたエンコーディングでソース ファイルを保存し、 Unicode リテラル ( ) を使用する必要があることに注意してくださいu'string'。以下の例では、ファイルを UTF-8 と ASCII の両方で記述して、どちらの場合でも ElementTree がファイルを正しく読み取ることを示しています。

# coding: utf8
from xml.etree import ElementTree as et

# Create the root element.
root = et.Element('test')
root.text = u'123€456'

# Wrap the root in an ElementTree and write files.
tree = et.ElementTree(root)
tree.write('utf8.xml',encoding='UTF-8')
tree.write('ascii.xml',encoding='ascii')

# Verify that each file can be read correctly.
tree = et.parse('utf8.xml')
print tree.getroot().text
tree = et.parse('ascii.xml')
print tree.getroot().text

# display the raw contents of the files
with open('utf8.xml','rb') as f:
    print repr(f.read())
with open('ascii.xml','rb') as f:
    print repr(f.read())

出力に注意してください。0xE2 0x82 0xAC は、ユーロ文字の UTF-8 16 進数シーケンスです。 €文字参照です。

123€456
123€456
"<?xml version='1.0' encoding='UTF-8'?>\n<test>123\xe2\x82\xac456</test>"
"<?xml version='1.0' encoding='ascii'?>\n<test>123&#8364;456</test>"
于 2012-09-30T17:08:15.977 に答える
0

私は自分はウェブページが得意だと思っていましたが、私の人生では、他の人が持っているように、このサイトの投稿に「応答」する方法を理解できません. だから私はこの新しい答えを作成する必要があります...

マーク・トロネンさん、返信ありがとうございます。あなたの応答と Martijn Pieters の応答の両方に、Unicode リテラルの使用が含まれていました。しかし、それは私にはうまくいきません。私が扱っている XML ファイルは、€ 記号を含むファイル名を書き出すことによって作成されます。次のコードでファイル名を取得します。

for file in os.listdir(r'C:\test'):
    filenamelist = filenamelist + " " + file

これらのファイル名の中には、ファイル名自体に € 記号が含まれるものがあります。次に、これらのファイル名を次のように XML 属性として書き込みます。

optionsdirectory = os.getcwd()
optionsfile = os.path.join(optionsdirectory, "conf.xml")
optionstree = ET.parse(optionsfile)
options = optionstree.getroot()
for option in options:
    if option.tag == "filenames":
        option.text = filenamelist
optionstree.write(optionsfile, encoding="UTF-8")

最初に、空の「filenames」属性を含む xml ファイル「conf.xml」を作成します。私はそれが不器用であることを知っていますが、それは私の目的のために機能します。

したがって、€ 記号を Unicode リテラルから取得することはできません。上記のコードを実行すると、元の投稿に投稿したエラーが表示されます。これは、基本的に、「filenamelist」で€記号に遭遇すると手を投げると言っています。

于 2012-09-30T17:38:20.320 に答える