2

我正在尝试使用suds库在 Python 2.6 中实现 SOAP Web 服务。效果很好,但是在尝试使用lxml解析输出时遇到了问题。

Suds 返回一个suds.sax.text.Text带有来自 SOAP 服务的回复的对象。该类suds.sax.text.Text是 Python 内置Unicode 类的子类。本质上,它可以与以下 Python 语句相媲美:

u'<?xml version="1.0" encoding="utf-8" ?><root><lotsofelements \></root>'

这是不协调的,因为如果 XML 声明是正确的,则内容是 UTF-8 编码的,因此不是Python Unicode 对象(因为它们存储在一些内部编码中,如 UCS4)。

如文档所述, lxml 将拒绝解析它,因为对于它应该被解释为什么编码没有明确的答案。

在我看来,有两种方法可以摆脱这种绑定:

  1. 剥离<?xml>声明,包括编码。
  2. 使用指定的编码将 Suds 的输出转换为字节串。

目前,我从 web 服务接收的数据在 ASCII 范围内,所以任何一种方式都可以,但对我来说,这两种方式都非常像丑陋的黑客,我不太确定如果我开始会发生什么接收需要更广泛的 Unicode 字符的数据。

有什么好主意吗?我无法想象我是这个职位的第一个……</p>

4

2 回答 2

2

你和 lxml 是正确的;有效的 XML 文档必须是按照<?xml .....标头中声明的方式编码的字节流(默认值:UTF-8)。

我建议第三种选择:将其保留在带有 XML 标头的 unicode 中,该标头省略了编码声明,但将版本保留在其中(未来安全)。这将使 lxml 保持快乐并避免再次编码的开销。

我还建议在 suds 网站上进行一些温和的询问,并在其来源中四处寻找。

于 2010-03-16T21:54:50.427 回答
1

嗯,我目前正在实施我的第一个基于 Suds 的解决方案,并使用 lxml 解析我的响应没有问题,但我认为这可能是因为我正在以一种非常生硬和愚蠢的方式进行操作。这是我的代码的样子:

try:
    result = self.client.service.ExportOwnersDetails(fAccess=self.access_id, fParams=params)
except URLError:
    # TODO: Log timeout here, handle
    return
response = str(result.fReturn)

if len(response) == 0 or response.find('<?xml ') == -1:
    # TODO: Log import error here, handle
    return
response = StringIO(response)
xml = etree.parse(response)

就像我说的,不是很聪明(显然我还有一些日志记录要做),但这是我的方法。fAccess、fParams、fReturn 废话是我正在与之集成的第三方提供商的命名约定。

于 2010-03-16T21:30:42.267 回答