0

我对 SOAP 和 WSDL 世界还很陌生。我该怎么做才能确保命名空间始终位于返回元素中?

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://someurl.com">
    <SOAP-ENV:Body>
        <ns1:sayHelloResponse>
            <return>Say Hello Kelvin</return>
        </ns1:sayHelloResponse>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

我想要的是:

<ns1:sayHelloResponse>
    <ns1:return>Say Hello Kelvin</ns1:return>
</ns1:sayHelloResponse>

我正在使用 PHP 和 Zend 框架。WSDL 由Zend_Soap_AutoDiscovery生成。但这不应该是一个障碍,因为无论如何我都会修改它的输出。

谢谢你的帮助。

4

1 回答 1

1

休息了一段时间后,我再次接近这个问题。不过这一次,我偶然发现了这篇不错的文章(感谢我的前同事迈克)。如果未在模式标记中声明属性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 为前缀。

于 2012-06-28T13:36:59.433 回答