Moodle LMS 可用于对学生进行测验。一种可选的问题类型(不透明)使用 SOAP 向服务请求问题(代码位于https://goo.gl/iGDIiy)。
使用https://goo.gl/kESENq中定义的 WSDL 在 PHP 中实现了一个有效的“问题服务器”
我遇到的复杂情况是问题类型中的代码期望一些返回值是一个字符串。来自正常运行的测试服务器的响应看起来像......
<SOAP-ENV:Body>
<ns1:getEngineInfoResponse>
<getEngineInfoReturn xsi:type="SOAP-ENC:string">
<engineinfo>
注意 xsi:type=..string。PHP 应用程序实际上将数据作为 XML 格式的字符串返回:
/**
* A dummy implementation of the getEngineInfo method.
* @return string of XML.
*/
public function getEngineInfo() {
return '<engineinfo>
我正在尝试将其连接到 Python+SOAP 服务器。我试过同时使用 ZSI 和 Spyne。对于 ZSI,我使用示例服务器提供的 WSDL 来生成代码存根。相应的代码只是简单地返回一个字符串,很像 PHP 代码。对此的回应是:
<ns1:getEngineInfoResponse>
<getEngineInfoReturn>
<engineinfo>
请注意缺少字符串类型修饰符。这个响应被 Moodle 中的 PHP 代码作为一个对象接收,该对象包含一个没有名称但包含返回的 XML 字符串的字段。因为它是一个包含字符串的对象,而不仅仅是一个字符串,所以代码无法正确解析结果。
使用 Spyne,我得到:
soap11env:Body>
<tns:getEngineInfoResponse>
<tns:getEngineInfoReturn><engineinfo>
从此代码:
@srpc(_returns=String, _body_style='wrapped',
_out_variable_name="getEngineInfoReturn"
)
def getEngineInfo():
resp = "<engineinfo>\n"
这还返回一个包含适当字符串的单个元素(现在名为 getEngineInfoReturn)的对象。但是,接收方(对生成的 WSDL 感到满意)仍然需要一个字符串,而不是包含字符串的对象。
我宁愿让 Spyne 版本工作而不是 ZSI 版本,因为它更容易使用。我以前使用过 SOAP,但不确定 PHP 代码是否对返回格式做出了无根据的假设,或者我是否应该能够迫使 Spyne 生成该格式。通过阅读装饰器功能的源代码,我认为我不能。
那么,这是一个编码不佳的客户端还是预期的 SOAP 模式正常?我怎样才能让 Spyne(或 ZIS)产生类似的东西?