簡體   English   中英

讀取UTF-8 XML並使用Python將其寫入文件

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM