首先,我正在使用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
的变量。
然后我使用a2b_qp()
模块的binascii
函数将XML字符串转换为二进制文件,然后将所有这些字符串放入bytearray
。
data = bytearray(binascii.a2b_qp(ET.tostring(root, pretty_print=True)), "UTF-8")
现在在我看来,这个data
变量应该在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字符串,但是我将这个混乱的Notepad ++设置为UTF-8编码:
这个与Notepad ++的混乱设置为ANSI编码:
我认为有经验的人可能会通过看图片知道发生了什么。我已经阅读了很多并试图弄明白,但我已经被困了一段时间了。
答案 0 :(得分:4)
我正在使用UTF-8中的记事本保存的文本文件进行解析 编码。这足以确保它是UTF-8吗?我试过了 chardet模块,但它并没有真正帮助我。
是的,告诉编辑将其保存在给定的编码中足以确保它以该编码保存。如果可能的话,这也应该记录在某个地方的文件中 - 使用XML,<?xml encoding="utf-8"?>
是指定这一点的常用方法 - 但这只是元数据,而不是实际控制编码。当{em>您不知道编码时,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中获得前所未有的废话(因为它是一个字节&lt; - &gt;字节编码)。
修复方法是从头开始将其编码为UTF-8 ,并忘记quoted-printable。 (如果你真的希望它是QP编码的,那么在之后通过binascii.b2a 运行它是UTF8化的。)
ElementTree允许您指定编码:
ET.tostring(root, encoding='utf-8')
将为您提供正确的UTF-8编码XML,它将在Notepad ++中很好地打开。
答案 1 :(得分:3)
我认为你在这里偏离轨道:
binascii.a2b_qp(ET.tostring(root, pretty_print=True))
a2b_qp
假设输入是'quoted printable'(类似于base64),但它实际上是XML。
结果是二进制文件是垃圾邮件。
相反,您应该使用bytearray。传递你的XML字符串和编码("utf-8"
),它将返回你的blob。
编码是有趣的一套心理体操。总结:
unicode
数据类型,而不是str
我希望这会有所帮助
答案 2 :(得分:0)
储存:
xml_string.encode('utf-8')
)Retrieiving:
xml_string.decode('utf-8')