我有一个巨大的(50MB)XML ElementTree,我已经生成了原始数据中的某些地方,有些UTF-8字母没有被删除。即使在tostring中有一个“encoding ='UTF-8'”选项,ElementTree.write和.tostring似乎也会阻塞unicode。文档相当有限,我甚至不确定tostring是否符合UTF-8(查看源代码)。
所以我的问题 - 如何删除任何非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
“核选项”功能仅适用于字符串,现在我有一个元素中的数据我似乎无法剥离我错过的东西。
答案 0 :(得分:1)
你需要解释“原始数据中的某些地方是一些没有被删除的UTF-8字母” - 比如什么是“UTF-8字母”,以及为什么要剥离它们。 / p>
如果你解释了“ElementTree.write和.tostring似乎在unicode上窒息”的意思,那也会有所帮助。请编辑您的问题以显示完整的错误消息和追溯。
为什么要使用该功能将你的unicode打成ASCII?它只是为了克服你遇到的问题吗?
您可能正在将以UTF-8编码的str
个对象提供给ElementTree。不要那样做。为它提供unicode
个对象,它只是起作用:
>>> 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)
'<root>ЀЁЂЃЄЅІЇ</root>'
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>"
您应该使用ElementTree.write method来编写文件,而不是使用'tostring';它节省了双重处理。
答案 1 :(得分:0)
我再次运行该过程,在树创建过程中将输入字符串解码为unicode。八个小时可能需要很长时间,但你可以做其他事情,而不是等待内存修补的指针。
确保测试一小部分数据以确认您的代码是否正常工作。
答案 2 :(得分:0)
听起来我觉得问题更可能是输出文件的编码 - 就像你正在使用的那样。你可以提供更多代码来解决你的问题吗?我看不出ElementTree.write()
和ElementTree.tostring()
如何窒息它。
答案 3 :(得分:0)
好吧,即使你们认为我这样做也很疯狂,但它确实有效:
我在Notepad ++中打开了pickle文件并手动找到所有“\ x ??”正则表达式的字符,并删除它们。然后我将pickle导入python,在命令行使用ElementTree保存为XML文件:
f = open('pulsewire / pulse_cleaned.pickle','rb')
导入泡菜
data = pickle.load(f)
将xml.etree.ElementTree导入为ET
bob = ET.ElementTree(data)&lt; - 需要首先将元素包装在树中
bob.write( “pulsewire / testtree.xml”)