[英]Reading UTF-8 XML and writing it to a file with Python
我正在嘗試解析UTF-8 XML文件並將其中的一些部分保存到另一個文件中。 問題是,這是我的第一個Python腳本,我對我發現的字符編碼問題感到困惑。
我的腳本在嘗試將非ascii字符寫入文件時立即失敗,但它可以將其打印到命令提示符(至少在某種程度上)
這是XML(來自至少重要的部分,它是包含UI字符串的* .resx文件)
<?xml version="1.0" encoding="utf-8"?>
<root>
<resheader name="foo">
<value>bar</value>
</resheader>
<data name="lorem" xml:space="preserve">
<value>ipsum öä</value>
</data>
</root>
這是我的python腳本
from xml.dom.minidom import parse
names = []
values = []
def getStrings(path):
dom = parse(path)
data = dom.getElementsByTagName("data")
for i in range(len(data)):
name = data[i].getAttribute("name")
names.append(name)
value = data[i].getElementsByTagName("value")
values.append(value[0].firstChild.nodeValue.encode("utf-8"))
def writeToFile():
with open("uiStrings-fi.py", "w") as f:
for i in range(len(names)):
line = names[i] + '="'+ values[i] + '"' #varName='varValue'
f.write(line)
f.write("\n")
getStrings("ResourceFile.fi-FI.resx")
writeToFile()
這是追溯:
Traceback (most recent call last): File "GenerateLanguageFiles.py", line 24, in writeToFile() File "GenerateLanguageFiles.py", line 19, in writeToFile line = names[i] + '="'+ values[i] + '"' #varName='varValue' UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 2: ordinal not in ran ge(128)
我應該如何修復我的腳本,以便它能正確讀寫UTF-8字符? 我正在嘗試生成的文件將用於Robots Framework的測試自動化。
你將需要刪除調用encode()
-也就是說,更換nodeValue.encode("utf-8")
用nodeValue
-然后更改調用open()
到
with open("uiStrings-fi.py", "w", "utf-8") as f:
這使用open()
的“Unicode識別”版本,您需要從codecs
模塊導入,所以也添加
from codecs import open
到文件的頂部。
問題是,當您調用nodeValue.encode("utf-8")
,您將Unicode字符串(Python的內部表示,可以存儲所有Unicode字符)轉換為常規字符串(只能存儲單字節字符0) -255)。 稍后,當您構造要寫入輸出文件的行時, names[i]
仍然是Unicode字符串,但values[i]
是常規字符串。 Python嘗試將常規字符串轉換為Unicode,這是更通用的類型,但由於您沒有指定顯式轉換,它使用ASCII編解碼器,這是默認值,而ASCII無法處理字節值更大的字符不幸的是,其中一些確實出現在字符串values[i]
因為UTF-8編碼經常使用那些高范圍字節。 所以Python抱怨說它看到了一個無法處理的角色。 正如我上面所說,解決方案是將轉換從Unicode推遲到字節,直到最后一刻,然后使用支持Unicode的版本open(它將為您處理編碼)來實現。
現在我考慮一下,而不是我上面所說的,另一種解決方案是用names[i].encode("utf-8")
替換names[i]
。 這樣,您也可以將names[i]
轉換為常規字符串,而Python沒有理由嘗試將values[i]
轉換回Unicode。 盡管如此,人們可以認為將字符串保留為Unicode對象是好的做法,直到將它們寫入文件為止......如果沒有別的,我相信unicode
成為Python 3中的默認值。
XML解析器在讀取文件時解碼輸入的UTF-8編碼,並且生成的DOM的所有文本節點和屬性都是unicode對象。 當您從DOM中選擇有趣的數據時,您將values
重新編碼為UTF-8,但不對names
進行編碼。 結果values
數組包含編碼的字節字符串,而names
數組仍包含unicode對象。
在拋出編碼錯誤的行中,Python嘗試連接這樣的unicode名稱和字節字符串值。 為此,兩個值必須是相同的類型,Python嘗試將字節字符串values[i]
轉換為unicode,但它不知道它是UTF-8編碼並且在嘗試使用ASCII編解碼器時失敗。
解決這個問題的最簡單方法是將所有字符串保留為Unicode對象,並在將它們寫入文件時將它們編碼為UTF-8:
values.append(value[0].firstChild.nodeValue) # encode not yet
...
f.write(line.encode('utf-8')) # but now
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.