解析XMPP类似XML流的最佳方法是什么?

4 投票
2 回答
2473 浏览
提问于 2025-04-15 22:11

我正在开发一个服务器应用程序,它通过TCP套接字接收数据,这些数据是类似XMPP的XML格式。也就是说,<root>元素的每个子元素基本上代表一个独立的请求(称为stanza)。一旦收到</root>,连接就会关闭。

我知道我必须使用像SAX这样的流解析器。不过,为了方便起见,我更希望能有一个树状的接口来访问每个stanza的子元素。(每个请求发送的数据量不大,所以我觉得把每个stanza作为一个整体来读取是合理的。)

在Python中(最好是3.x版本),实现这个功能的最佳方法是什么?

这是我想要构建的代码。如果你有其他的解决方案,也欢迎告诉我。

import socketserver
import settings

class MyServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    pass

class MyRequestHandler(socketserver.StreamRequestHandler):
    def handle(self):
        pass

if __name__ == '__main__':
    server = MyServer((settings.host, settings.port), MyRequestHandler)
    server.serve_forever()

2 个回答

1

我们在Skates项目中做的事情是,使用Sax解析器来处理数据流,但我们用这个解析器为每个接收到的段落(stanza)构建一个完整的文档。

3

你需要使用一种基于推送的解析器,它会发出SAX事件。简单来说,你想要一个可以通过调用pushChunk(data)来处理部分数据的解析器,并且它能处理第一级子标签结束事件,从而生成你的数据块。然后,这些数据块可以发送给应用程序进行处理。

如果你想看看这个的例子,这里有我写的libstrophe的expat解析器,这是一个XMPP客户端库:http://github.com/metajack/libstrophe/blob/master/src/parser_expat.c

为每个数据块构建一个完整的文档是相当耗费资源的。其实可以用一个解析器实例来实现,而不是为每个数据块不断创建新的文档解析器。

如果你需要一个可用的Python版本,你可以使用或提取Twisted Words中的代码(我记得是twisted.words.xish)。

撰写回答