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

3

我有一个问题,需要解析第三方通过套接字发送的连续(多个)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))

事情进展得很顺利......然而,在iparse中的for循环每次都会遍历整个文档。是否有可能让iparse在流中逐个构建并遍历一个格式良好的标签节点(事件)呢?请注意,我无法设置块大小以读取格式良好的包。我可以使用缓冲区,然后构建数据包,并在数据包格式良好后才发送到iparse,但那可能会引入不必要的延迟吗?有更好的方法来处理这个问题吗?
编辑:每个事件都是独特的,但包含根下的任意节点。iparse预计将最新事件发布给实时分析图形系统中的任意数量的订阅者。

你能给我们举个你想要的结果的例子吗? - Snakes and Coffee
对问题进行了编辑,以更好地反映所需的输出。 - pynoob
我想我帮不了你。这个问题有点超出了我的能力范围。 - Snakes and Coffee
1个回答

0

你可以看一下lxml.etree中的Feed Parsing。然而,由于你的文档不断增长,仍然会遇到问题。

XML块是否由换行符分隔?如果是这样,我建议您缓冲直到遇到新行,然后将每行发送到XML解析器。类似于Twisted's LineReceiver

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


感谢您提供有关Feed解析器的信息...然而,像您指出的那样,这个解决方案在文档继续增长时会存在问题。我还遇到的另一个问题是,Feed解析器需要显式调用close()才能再次使用。看起来我将被迫使用缓冲区,然后将格式良好的字符串传输到 iparse(现在可以重写为xmltree.fromstring()而不是使用iterparse)。 :( - pynoob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接