首先,我正在使用UTF-8编码用记事本保存的文本文件进行解析.这足以确保它是UTF-8吗?我尝试了chardet模块,但它并没有真正帮助我.这里有几行文本文件,如果有人能找到更多:
CUSTOMERLOC|1|N/A|N/A|LEGACY COPPER|N/A|Existing|N/A|NRZ|NRZ|N/A|N/A
FTSMAR08|01/A|N/A|N/A|LEGACY COPPER|N/A|Existing|N/A|NRZ|NRZ|N/A|N/A
FTSMAR08|01/B|N/A|N/A|LEGACY COPPER|N/A|Existing|N/A|NRZ|NRZ|N/A|N/A
我使用lxml模块编写我的XML,并使用了tostring()方法并将其分配给一个名为data的变量.
然后我使用binascii模块的a2b_qp()函数将XML字符串转换为二进制文件,并将所有这些都放入bytearray中.
data = bytearray(binascii.a2b_qp(ET.tostring(root, pretty_print=True)), "UTF-8")
现在在我看来,这个数据变量应该在bytearray中包含二进制形式的XML.
所以,然后我使用了更新游标并将数据插入到表的BLOB字段中.
row[2] = data
cursor.updateRow(row)
一切似乎都有效,但是当我使用以下代码阅读BLOB字段时:
with arcpy.da.SearchCursor("Point", ['BlobField']) as cursor:
for row in cursor:
binaryRep = row[0]
open("C:/Blob.xml, 'wb').write(binaryRep.tobytes())
当我打开Blob.xml文件时,我希望看到我首先以可读形式创建的XML字符串,但是我把这个混乱的记事本设置为UTF-8编码:
而这个记事本设置为ANSI编码的混乱:
我以为有经验的人可能会通过看图片知道发生了什么.我已经阅读了很多,并试图弄明白,但我已经被困了一段时间了.
最佳答案
I’m parsing from a text file which I saved with notepad in UTF-8
encoding. Is this enough to make sure it’s in UTF-8? I tried the
chardet module, but it didn’t really help me.
是的,告诉编辑将其保存在给定的编码中足以确保它以该编码保存.如果可能的话,这也应该记录在某个文件中 – 使用XML,<?xml encoding =“utf-8”?>是指定此方法的常用方法 – 但这只是元数据,并不实际控制编码.当你不知道编码时,chardet是很有用的 – 但它应该作为最后的手段保留它的猜测. UTF8通常是一个很好的默认假设,特别是对于XML.
这一行的原因:
data = bytearray(binascii.a2b_qp(ET.tostring(root, pretty_print=True)), "UTF-8")
给你废话是它做了一些讨厌的东西,并最终得到mojibake.
ET.tostring()默认以ASCII格式编码(因此将丢失任何非ASCII范围的数据,但现在不在此处).所以,现在你有一个ASCII字符串. binascii.a2b_qp使用引用的可打印编码对其进行解码.因此,它将其从一切都是可打印的ASCII字符变为某种情况(不一定是这种情况)(qp使用3个可打印的ASCII字符编码任何不在可打印ASCII范围内的字节).这意味着,例如,如果您的文本中有任何内容= 00,则会将其转换为空字节.问题是你所拥有的不是QP编码的,因此QP解码会导致无意义.
然后使用bytearray将其再次编码为UTF8. bytearray假设如果你给它一个编码,那么字符串是一个unicode字符串 – 你打破这个假设,并给它原始的二进制数据(这已经没有意义).将原始二进制数据编码为UTF8并不是特别有意义的事情,这一点让我相信您正在使用Python 2.当您尝试执行此操作时,Python 3正确地抛出错误:
>>> bytearray(b'123', 'utf8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: encoding or errors without a string argument
关于什么是字节以及什么是解码字符,Python 2非常模糊,这使问题类型的问题更容易遇到.如果可以的话,这是升级到Python 3的一个很好的理由.但它没有帮助你从a2b_qp中获得的前一个废话(因为它是一个字节< – >字节编码).
修复是从一开始就用UTF-8对其进行编码,而忘记了quoted-printable. (如果你确实希望它是QP编码的,那么在UTF8ified之后通过binascii.b2a运行它).
ElementTree允许您指定编码:
ET.tostring(root, encoding='utf-8')
将为您提供正确的UTF-8编码XML,它将在记事本中很好地打开.