我在解析第三方通过套接字发送的(多个)xml文档的连续流时遇到问题。通过套接字发送的xml流的示例是:
<?xml version="1.0"?><event><user id="1098"/><viewpage>109958</viewpage></event>
<?xml version="1.0"?><event><user id="1482"/><actions><edit>102865</edit><commit>1592356</commit></actions></event>
etc.
这是我正在使用的代码:
import socket
import xml.etree.cElementTree as etree
from StringIO import StringIO
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "IP.IP.IP.IP"
port = "8080"
addr = (host,port)
s.connect(addr)
def iparse(packet):
for _, element in etree.iterparse(packet):
print ("%s, %s" %(element.tag, element.text))
element.clear()
#if complete <event> node received, publish node
data = "<feeds>"
while 1:
chunk = s.recv(1024)
#replace the xml doc declarations as comments
data += (chunk.replace("<?","<!--")).replace("?>","-->")
iparse(StringIO(data))
事情很好......但是,for
中的iparse
循环每次都会遍历整个文档。 iparse
是否有可能构建并迭代一个格式正确的标记节点(事件),因为它在流上显示?请注意,我无法设置块大小来读取格式正确的数据包。我可以使用缓冲区,然后构建数据包,只有在数据包格式正确后才发送到iparse
,但这可能会引入不必要的延迟?有没有更好的方法来解决这个问题?
修改
每个事件都是不同的,但在根<event>
下包含任意节点。 iparse
预计会将最新事件发布给实时分析图表系统中的任意数量的订阅者。
答案 0 :(得分:0)
您可以查看lxml.etree
中的feed parsing。但是,随着文档的不断增长,您仍然会遇到问题。
XML blob是否被新行字符分隔?如果是这样,我建议您缓冲,直到您点击一个新行,然后将每行发送到xml解析器。 ÁlaTwisted's LineReceiver。
实际上,如果是我,我可能会在Twisted中写这个应用程序。将网络服务粘合在一起对我来说是一个常见的用例。