我有一个网络应用程序(使用Twisted),它通过互联网接收xml的块(因为整个xml可能不会完整地存在于单个数据包中)。我的思维过程是在收到xml消息时慢慢构建它。我已定居"来自xml.etree.ElementTree的iterparse。我已经涉足了一些代码,以下(非Twisted代码)工作正常:
import xml.etree.ElementTree as etree
from io import StringIO
buff = StringIO(unicode('<notorious><burger/></notorious>'))
for event, elem in etree.iterparse(buff, events=('end',)):
if elem.tag == 'notorious':
print(etree.tostring(elem))
然后我构建了以下代码来模拟如何在我的结尾接收数据:
import xml.etree.ElementTree as etree
from io import StringIO
chunks = ['<notorious>','<burger/>','</notorious>']
buff = StringIO()
for ch in chunks:
buff.write(unicode(ch))
if buff.getvalue() == '<notorious><burger/></notorious>':
print("it should work now")
try:
for event, elem in etree.iterparse(buff, events=('end',)):
if elem.tag == 'notorious':
print(etree.tostring(elem))
except Exception as e:
print(e)
但是代码吐了出来:
&#39;未找到任何元素:第1行,第0列&#39;
我无法绕过它。当第二个示例中的stringIO在第一个代码示例中具有相同的stringIO内容时,为什么会发生该错误?
PS:
由于
答案 0 :(得分:3)
文件对象和类文件对象具有文件位置。一旦它被读/写,文件位置就会前进。在将文件对象传递给etree.iterparse
之前,您需要更改文件位置(使用<file_object>.seek(..)
),以便它可以从文件的开头读取。
...
buff.seek(0) # <-----
for event, elem in etree.iterparse(buff, events=('end',)):
if elem.tag == 'notorious':
print(etree.tostring(elem))
答案 1 :(得分:1)
即使你写完后你关闭了文件,文件位置也指向最后一个pos。所以你必须使用seek命令移动文件pos fd.seek(0) 现在您可以使用et.parse命令打开并解析文件。