在Python中从socketstream构建/解析XML文档

时间:2011-08-04 12:25:46

标签: python elementtree

我在解析第三方通过套接字发送的(多个)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预计会将最新事件发布给实时分析图表系统中的任意数量的订阅者。

1 个答案:

答案 0 :(得分:0)

您可以查看lxml.etree中的feed parsing。但是,随着文档的不断增长,您仍然会遇到问题。

XML blob是否被新行字符分隔?如果是这样,我建议您缓冲,直到您点击一个新行,然后将每行发送到xml解析器。 ÁlaTwisted's LineReceiver

实际上,如果是我,我可能会在Twisted中写这个应用程序。将网络服务粘合在一起对我来说是一个常见的用例。