休息了一段时间后,我再次接近这个问题。不过这一次,我偶然发现了这篇不错的文章(感谢我的前同事迈克)。如果未在模式标记中声明属性elementFormDefault,则假定 unqualified 作为其值。通过赋予它“合格”的值,将发生以下情况:
但是,如果您将 elementFormDefault="qualified" 添加到文档/文字包装的 WSDL 中的所有模式,那么消息中的所有元素都将使用它们的父名称空间来限定。
通常,您不想使用 elementFormDefault="qualified",因为它会使消息膨胀,但一年或更早之前,不同供应商之间存在互操作性问题,设置此属性有时可以解决问题。
即使我没有使用文档/文字,我也想尝试一下。我将该属性添加到我的模式标记中,并向另一个调用发出请求。这是我得到的回复:
<ns1:getUserResponse>
<return>
<ns1:firstname>First</ns1:firstname>
<ns1:lastname>Last</ns1:lastname>
</return>
</ns1:getUserResponse>
如您所见,“return”元素的子元素以命名空间为前缀。在这一点上,我真的很兴奋,因为我终于离我想去的地方更近了。不幸的是,返回元素没有命名空间前缀。我再次尝试了较早的电话(请参阅问题帖子),但响应与以前相同。
我不能在这个问题上花更多时间。毕竟这只是一个原型。这就是为什么我决定挂钩 Zend_Soap_Server 的句柄函数,在输出之前修改响应。
class Custom_Soap_Server extends Zend_Soap_Server
{
public function __construct($wsdl = null, array $options = null)
{
parent::__construct($wsdl, $options);
// Response of handle will always be returned
$this->setReturnResponse(true);
}
public function handle($request = null)
{
$response = parent::handle($request);
echo str_replace(array('<return>', '</return>'), array('<ns1:return>', '</ns1:return>'), $response);
return;
}
}
老实说,这是一个令人讨厌的黑客行为。我总是假设只有一个命名空间。替换函数可以写得更好。但它毕竟是一个原型,这是我第一个想到让它工作的想法。
在使用新的自定义类而不是 Zend_Soap_Server 之后,所有返回元素都以 ns1 为前缀。