假设我有这个XML(它是一个SOAP调用)
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ext="http://api.movilway.net/schema/extended">
<soapenv:Header/>
<soapenv:Body>
<ext:GetBalanceRequest>
<ext:AuthenticationData>
<ext:Username>Foo</ext:Username>
<ext:Password>Bar$123!password</ext:Password>
<ext:SessionID>as3hy4ri37g2f345</ext:SessionID>
</ext:AuthenticationData>
<ext:DeviceType>3</ext:DeviceType>
</ext:GetBalanceRequest>
</soapenv:Body>
</soapenv:Envelope>
(Foo,Bar $ 123!密码,as3hy4ri37g2f345和3只是样本值)
通常,当我想进行简单的SOAP调用时,我使用SoapClient
这样:
$sc = new SoapClient('http://my.url/my/service?wsdl');
$result = $sc->someMethod(array('some' => 'params'));
但是这个似乎使用了xsd名称空间和嵌套结构。
问:如何使用名称空间前缀(在本例中为ext:)和带有名称空间前缀(和嵌套结构)的参数调用方法?
编辑:我尝试的内容涉及将命名空间作为uri选项。并得到了这样的例外:
SoapFault:函数(“GetBalanceRequest”)不是此服务的有效方法
我试过的代码是:
try {
$client = new SoapClient('http://THEURLHERE/Path/To/The/Service?wsdl', array('uri' => 'http://api.movilway.net/schema/extended'));
print_r($client->GetBalanceRequest(
array(
'AuthenticationData' => array(
'Username' => 'MYUSERHERE',
'Password' => 'MYPASSWORDHERE'
),
'DeviceType' => 1
)
));
} catch(Exception $e) {
print_r($e);
}
假设我没有错误或错误,因为我直接从文档中获得了所需的XML。
Q + :我必须在代码中添加哪些内容才能发送此类请求?
答案 0 :(得分:1)
首先,正确的术语不是&#34;扩展&#34;,而是&#34;命名空间&#34; - 这里的命名空间被称为&#34;扩展&#34;这简直是巧合。并在示例中获得了别名ext:
。
其次,XML命名空间只是一种说法&#34;这些元素和属性属于特定类型&#34 ;;它不会自动暗示超出普通XML的任何特殊结构 - 例如,它与XSD没有自动关系。命名空间由URI唯一标识,不需要实际指向任何位置(请参阅this previous answer for more on that)。在文档中,它被赋予一个任意前缀,因此您不必在每个元素旁边写入URI。
SOAP本身使用名称空间http://schemas.xmlsoap.org/soap/envelope/
表示SOAP&#34; envelope&#34;的元素,这里给出了别名soapenv
。 &#34;身体&#34; SOAP消息不在该命名空间中,因此SOAP服务通常将其元素声明为其他特定命名空间的一部分;如果他们没有,他们将成为默认的,无名的命名空间。
因此,理论如此之多。练习:
如果您正在使用WSDL加载Web服务,并且正确形成了WSDL,那么SOAPClient类应该自动为您的请求添加适当的命名空间。由于请求完全存在于该命名空间内,因此无需区分命名空间AuthenticationData
中的&#34; http://api.movilway.net/schema/extended
&#34;只是&#34; AuthenticationData
&#34;。
如果由于某种原因这不起作用,或者您没有WSDL,则可能需要create SoapVar
objects并为其分配适当的命名空间。
但是,基于您刚编辑到问题中的错误消息,上述所有内容可能完全无关,因为问题可能与命名空间无关 - 您在WSDL模式下运行,客户端是告诉你这个方法不存在。所以,对我来说显而易见的问题是,该方法是否在WSDL文件中明确定义了?