Python 如何编写去掉UTF-8的ElementTree

Python 如何编写去掉UTF-8的ElementTree,python,unicode,utf-8,tostring,elementtree,Python,Unicode,Utf 8,Tostring,Elementtree,我已经生成了一个巨大的(50MB)XML元素树,在原始数据中的某个地方有一些UTF-8字母没有被剥离。ElementTree.write和.tostring似乎在unicode上阻塞了,尽管tostring中有一个“encoding='UTF-8'”选项。文档非常有限,我甚至不确定tostring是否对UTF-8友好(查看源代码) 所以我的问题是——我如何去除整个elementtree中的任何非ascii字符,以便将这个怪物写入磁盘(生成它需要8个小时)?我现在已经把它腌了。我还在大多数数据上使

我已经生成了一个巨大的(50MB)XML元素树,在原始数据中的某个地方有一些UTF-8字母没有被剥离。ElementTree.write和.tostring似乎在unicode上阻塞了,尽管tostring中有一个“encoding='UTF-8'”选项。文档非常有限,我甚至不确定tostring是否对UTF-8友好(查看源代码)

所以我的问题是——我如何去除整个elementtree中的任何非ascii字符,以便将这个怪物写入磁盘(生成它需要8个小时)?我现在已经把它腌了。我还在大多数数据上使用了一个名为latin1_to_ascii的函数:

def latin1_to_ascii(unicrap):
        """
        This takes a UNICODE string and replaces Latin-1 characters with
        something equivalent in 7-bit ASCII. Anything not converted is deleted.
    #the unicode hammer approach: http://code.activestate.com/recipes/251871-latin1-to-ascii-the-unicode-hammer/
    """
    xlate={0xc0:'A', 0xc1:'A', 0xc2:'A', 0xc3:'A', 0xc4:'A', 0xc5:'A',
            0xc6:'Ae', 0xc7:'C',
            0xc8:'E', 0xc9:'E', 0xca:'E', 0xcb:'E',
            0xcc:'I', 0xcd:'I', 0xce:'I', 0xcf:'I',
            0xd0:'Th', 0xd1:'N',
            0xd2:'O', 0xd3:'O', 0xd4:'O', 0xd5:'O', 0xd6:'O', 0xd8:'O',
            0xd9:'U', 0xda:'U', 0xdb:'U', 0xdc:'U',
            0xdd:'Y', 0xde:'th', 0xdf:'ss',
            0xe0:'a', 0xe1:'a', 0xe2:'a', 0xe3:'a', 0xe4:'a', 0xe5:'a',
            0xe6:'ae', 0xe7:'c',
            0xe8:'e', 0xe9:'e', 0xea:'e', 0xeb:'e',
            0xec:'i', 0xed:'i', 0xee:'i', 0xef:'i',
            0xf0:'th', 0xf1:'n',
            0xf2:'o', 0xf3:'o', 0xf4:'o', 0xf5:'o', 0xf6:'o', 0xf8:'o',
            0xf9:'u', 0xfa:'u', 0xfb:'u', 0xfc:'u',
            0xfd:'y', 0xfe:'th', 0xff:'y',
            0xa1:'!', 0xa2:'{cent}', 0xa3:'{pound}', 0xa4:'{currency}',
            0xa5:'{yen}', 0xa6:'|', 0xa7:'{section}', 0xa8:'{umlaut}',
            0xa9:'{C}', 0xaa:'{^a}', 0xab:'<<', 0xac:'{not}',
            0xad:'-', 0xae:'{R}', 0xaf:'_', 0xb0:'{degrees}',
            0xb1:'{+/-}', 0xb2:'{^2}', 0xb3:'{^3}', 0xb4:"'",
            0xb5:'{micro}', 0xb6:'{paragraph}', 0xb7:'*', 0xb8:'{cedilla}',
            0xb9:'{^1}', 0xba:'{^o}', 0xbb:'>>', 
            0xbc:'{1/4}', 0xbd:'{1/2}', 0xbe:'{3/4}', 0xbf:'?',
            0xd7:'*', 0xf7:'/',0x92:'a'
            }
    r = ''
    for i in unicrap:
            if xlate.has_key(ord(i)):
                    r += xlate[ord(i)]
            elif ord(i) >= 0x80:
                    pass
            else:
                    r += str(i)
    return r
定义拉丁1到ascii(unicrap):
"""
这将采用UNICODE字符串,并用
7位ASCII中的等效值。未转换的内容将被删除。
#unicode-hammer方法:http://code.activestate.com/recipes/251871-latin1-to-ascii-the-unicode-hammer/
"""
xlate={0xc0:'A',0xc1:'A',0xc2:'A',0xc3:'A',0xc4:'A',0xc5:'A',
0xc6:'Ae',0xc7:'C',
0xc8:'E',0xc9:'E',0xca:'E',0xcb:'E',
0xcc:'I',0xcd:'I',0xce:'I',0xcf:'I',
0xd0:'Th',0xd1:'N',
0xd2:'O',0xd3:'O',0xd4:'O',0xd5:'O',0xd6:'O',0xd8:'O',
0xd9:'U',0xda:'U',0xdb:'U',0xdc:'U',
0xdd:'Y',0xde:'th',0xdf:'ss',
0xe0:'a',0xe1:'a',0xe2:'a',0xe3:'a',0xe4:'a',0xe5:'a',
0xe6:'ae',0xe7:'c',
0xe8:'e',0xe9:'e',0xea:'e',0xeb:'e',
0xec:'i',0xed:'i',0xee:'i',0xef:'i',
0xf0:'th',0xf1:'n',
0xf2:'o',0xf3:'o',0xf4:'o',0xf5:'o',0xf6:'o',0xf8:'o',
0xf9:'u',0xfa:'u',0xfb:'u',0xfc:'u',
0xfd:'y',0xfe:'th',0xff:'y',
0xa1:“!”,0xa2:“{cent}”,0xa3:“{pound}”,0xa4:“{currency}”,
0xa5:“{yen}”,0xa6:“|”,0xa7:“{section}”,0xa8:“{umlaut}”,

0xa9:'{C}',0xaa:'{^a}',0xab:'我会再次运行这个过程,在创建树的过程中将输入字符串解码为unicode。八个小时可能会很长,但您可以做其他事情,而不是等待来自其他人的内存修补指针


在继续之前,请确保对一小部分数据进行测试,以确认您的代码是否正常工作。

我觉得问题更可能是您正在处理的输出文件的编码问题。您能否提供更多关于如何编写的代码?我看不出
ElementTree.write()
ElementTree.tostring()
可能会窒息。

您需要解释“原始数据中的某个地方有一些未剥离的UTF-8字母”——比如什么是“UTF-8字母”,以及为什么要剥离它们

如果您解释一下“ElementTree.write和.tostring似乎在unicode上阻塞”的意思也会有所帮助。请编辑您的问题,以显示完整的错误消息并进行回溯

为什么要使用该函数将unicode转换为ASCII?这仅仅是为了克服您遇到的问题吗

很可能您正在将UTF-8编码的
str
对象馈送到ElementTree。不要这样做。将
unicode
对象馈送到ElementTree,它就可以工作了:

>>> e = et.Element('root')
>>> e.text = u''.join(unichr(i) for i in xrange(0x400, 0x408))
>>> e.text
u'\u0400\u0401\u0402\u0403\u0404\u0405\u0406\u0407'
如果您必须具有ASCII输出(您正在通过7位宽的通道进行通信?):

>>et.tostring(e)
'ЀЁЂЃЄЅІЇ'
UTF-8工程:

>>> et.tostring(e, 'UTF-8')
"<?xml version='1.0' encoding='UTF-8'?>\n<root>\xd0\x80\xd0\x81\xd0\x82\xd0\x83\xd0\x84\xd0\x85\xd0\x86\xd0\x87</root>"
>et.tostring(如“UTF-8”)
“\n\xd0\x80\xd0\x81\xd0\x82\xd0\x83\xd0\x84\xd0\x85\xd0\x86\xd0\x87”

您应该使用来编写文件,而不是使用“tostring”;这样可以避免重复处理。

好的,即使你们认为我这样做很疯狂,但它仍然有效:

我在Notepad++中打开了pickle文件,用regex手动找到了所有“\x???”字符,并将它们删除。然后我将pickle导入python,在命令行使用ElementTree保存为XML文件:

f=打开('pulsewire/pulse_cleaned.pickle','rb')

进口泡菜

数据=pickle.load(f)

将xml.etree.ElementTree作为ET导入


bob=ET.ElementTree(数据)8小时?您使用的是
xml.etree.ElementTree
还是
xml.etree.cElementTree
?可能是一个非常高效的键击…此python脚本的输出是一个xml文件,由另一个只接受ascii Us或latin1而不接受unicode的专有程序解释。那么是否有任何方便的方法来修改每个元素和子元素元素树中的ent、tag、tail等,就好像它是一个字符串一样?这样我就可以读取每个字母并返回ord[128]或更少的字符。但还没有看到类似的内容。
>>> et.tostring(e, 'UTF-8')
"<?xml version='1.0' encoding='UTF-8'?>\n<root>\xd0\x80\xd0\x81\xd0\x82\xd0\x83\xd0\x84\xd0\x85\xd0\x86\xd0\x87</root>"