2012-07-18 72 views
0

我使用Python打開2個文件,更改並替換它們的一些內容並將新輸出寫入第3個文件。 我的2個輸入文件是以'沒有BOM'的UTF-8編碼的XML,它們在其中包含德文,Ö,Ü和ß。 當我在Notepad ++中打開我的輸出XML文件時,未指定編碼(即沒有在'編碼'選項卡中檢查編碼)。我的A,O,U和SS轉化爲類似Python:在寫入文件時如何保存Ä,Ö,Ü

ü 

當我在Python中創建的輸出,我用

with open('file', 'w') as fout: 
    fout.write(etree.tostring(tree.getroot()).decode('utf-8')) 

我有什麼做的呢?

+2

寫入文件時,您想要「編碼」,而不是「解碼」。 – eumiro 2012-07-18 08:44:05

+0

現在的問題是,'ü'不僅僅是記事本+ +的方式來處理XML文件時顯示字符以外的字符,或者序列是否在輸入文件中。看到我的評論http://stackoverflow.com/a/11539528/1346705 – pepr 2012-07-18 10:48:31

回答

1

xml.etree.ElementTree用於Python 2某些說明,而對於其功能parse()。該函數將源作爲第一個參數。或者它可以是一個開放的文件對象,或者它可以是一個文件名。該函數創建ElementTree實例,然後將其傳遞的參數看起來像這樣的tree.parse(...)

def parse(self, source, parser=None): 
    if not hasattr(source, "read"): 
     source = open(source, "rb") 
    if not parser: 
     parser = XMLParser(target=TreeBuilder()) 
    while 1: 
     data = source.read(65536) 
     if not data: 
      break 
     parser.feed(data) 
    self._root = parser.close() 
    return self._root 

可以從第三行,如果文件名獲得通過,該文件以二進制模式打開猜測。這樣,如果文件內容是UTF-8,那麼您正在處理具有UTF-8編碼二進制內容的元素。如果是這種情況,您應該打開也以二進制模式打開輸出文件

另一種可能性是使用codecs.open(filename, encoding='utf-8')打開輸入文件,並將打開的文件對象傳遞給xml.etree.ElementTree.parse(...)。這樣,ElementTree實例將與Unicode字符串一起使用,並且在將內容寫回時應該將結果編碼爲UTF-8。如果是這種情況,您可以使用帶有UTF-8的codecs.open(...)來編寫。您可以將打開的輸出文件對象傳遞給您提到的tree.write(f),您可以讓tree.write(filename, encoding='utf-8')爲您打開文件。

2

我認爲這應該工作:

import codecs 

with codecs.open("file.xml", 'w', "utf-8") as fout: 
    # do stuff with filepointer 
+0

在我的情況下,這返回一個「TypeError:不能轉換'字節'對象隱式地str」 – Kaly 2012-07-18 08:55:37

2

當編寫原始字節串,要以二進制方式打開文件:

with open('file', 'wb') as fout: 
    fout.write(xyz) 

否則open call打開在文本模式下的文件,並期待而不是Unicode字符串,並將爲您編碼。

解碼,就是解釋一個編碼(如utf-8),輸出是unicode文本。如果你想先進行解碼,以文本方式打開文件時指定編碼:

with open(file, 'w', encoding='utf-8') as fout: 
    fout.write(xyz.decode('utf-8')) 

如果不指定編碼Python將使用默認值,這通常是一件壞事。請注意,既然你已經有 UTF-8編碼的字節字符串開始,這實際上是無用的。

請注意,python文件操作決不會將現有的unicode點轉換爲XML character entities(如ü),其他代碼可以做到這一點,但您並未與我們分享。

我發現Joel Spolsky's article on Unicode在理解編碼和unicode方面是非常寶貴的。

+0

如果'xyz'已經是一個字節串然後' xyz.encode'可能會破壞它。 – jfs 2012-07-18 08:55:17

+1

@ J.F.Sebastian:當然,但解碼在這種情況下也不會起作用。我們對OP的代碼知之甚少,無論如何都要正確回答這個問題。 'decode'感覺就像操作系統在不理解的情況下重蹈覆轍,因此連接到Unicode文章。 – 2012-07-18 09:00:02

+0

我收到一個「AttributeError:'字節'對象沒有'encode'屬性。我調整了我的代碼,使其更具體。 – Kaly 2012-07-18 09:00:11

2

要寫ElementTree對象tree到使用'utf-8'字符編碼命名'file'文件:

tree.write('file', encoding='utf-8') 
+0

謝謝。我認爲這是工作! – Kaly 2012-07-18 09:40:08

+0

它可能取決於輸入文件的打開方式。看到我的評論http://stackoverflow.com/a/11539528/1346705。我不確定這裏,但它可能適用於喲意外。 – pepr 2012-07-18 10:45:10

+0

@pepr:''file''不是文件對象,而是文件名。 'ElementTree'自己關心它。這裏沒有意外。 – jfs 2012-07-18 10:46:14

相關問題