如何将nuSOAP用于具有多个名称空间的消息

问题描述 投票:7回答:5

我正在尝试使用在消息中使用多个名称空间的nuSOAP(因为在这里我绑定到PHP4)访问WebService。有可能吗?

示例请求消息如下所示:

<soapenv:Envelope ...
  xmlns:ns1="http://domain.tld/namespace1"
  xmlns:ns2="http://domain.tld/namespace2">
  <soapenv:Header/>
  <soapenv:Body>
    <ns1:myOperation>
      <ns2:Person>
        <ns2:Firstname>..</ns2:Firstname>
        ..
      </ns2:Person>
      <ns1:Attribute>..</ns1:Attribute>
    </ns1:myOperation>
  </soapenv:Body>
</soapenv:Envelope>

我尝试遵循:

$client = new nusoap_client("my.wsdl", true);
$params = array(
  'Person' => array(
    'FirstName'  => 'Thomas',
    ..
   ),
   'Attribute' => 'foo'
 );

 $result = $client->call('myOperation', $params, '', 'soapAction');

希望nuSOAP会尝试将这些名称与正确的名称空间和节点进行匹配。然后,我尝试使用soapval()生成元素及其名称空间-但是,如果我调用操作,nuSOAP将创建以下请求:

<SOAP-ENV:Envelope ...>
  <SOAP-ENV:Body>
    <queryCCApplicationDataRequest xmlns="http://domain.tld/namespace1"/>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

所以在“匹配”阶段出现了问题。

php soap php4 nusoap
5个回答
5
投票

尝试匹配之后,我找到了两种可能的解决方案:

1)不要使用WSDL创建nusoap_client和soapval()创建消息这样做的缺点是消息包含很多开销(名称空间在每个元素中定义)。不太好。

2)而不是依赖参数的匹配,而是在xml中构造您的答复,并将所有前缀定义都放在第一个元素中-例如。

$params = "<ns1:myOperation xmlns:ns1="..." xmlns:ns2="...">
      <ns2:Person>
        <ns2:Firstname>..</ns2:Firstname>
        ..
      </ns2:Person>
      <ns1:Attribute>..</ns1:Attribute>
    </ns1:myOperation>";

仍然不是一个很好的解决方案,但是它可以工作:-)


4
投票

[建立在Irwin的帖子上,我手动创建了xml,其余的工作则由nusoap完成。我的网络主机没有php soap扩展名,因此我不得不使用nusoap,而我尝试使用的Web服务需要在每个标签上使用名称空间(例如,此处的示例中的用户名和密码)。

require_once('lib/nusoap.php');

$client = new nusoap_client('https://service.somesite.com/ClientService.asmx');
$client->soap_defencoding = 'utf-8';
$client->useHTTPPersistentConnection(); // Uses http 1.1 instead of 1.0
$soapaction = "https://service.somesite.com/GetFoods";

$request_xml = '<?xml version="1.0" encoding="utf-8" ?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
  <env:Body>
    <n1:GetFoods xmlns:n1="https://service.somesite.com">
      <n1:username>banjer</n1:username>
      <n1:password>theleftorium</n1:password>
    </n1:GetFoods>
  </env:Body>
</env:Envelope>
';

$response = $client->send($request_xml, $soapaction, ''); 

echo '<h2>Request</h2><pre>' . htmlspecialchars($client->request, ENT_QUOTES) . '</pre>';
echo '<h2>Response</h2><pre>' . htmlspecialchars($client->response, ENT_QUOTES) . '</pre>';
echo '<h2>Debug</h2><pre>' . htmlspecialchars($client->getDebug(), ENT_QUOTES) . '</pre>';

然后我说了一个错误:

Notice: Undefined property: nusoap_client::$operation in ./lib/nusoap.php  on line 7674

所以我走了懒惰的路线,进入nusoap.php,并在第7674行之前添加了此代码,以使其变得高兴:

    if(empty($this->operation)) {
        $this->operation = "";
    }

2
投票

另一个绕过此问题的方法是对nusoap_client :: call()函数的修改。 nusoap.php中此行(版本1.123中的7359)旁边:

$nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace);

我添加了这个:

$nsPrefix = $this->wsdl->getPrefixFromNamespace("other_ns_name");

而且有效!由于我只需要为一个项目使用该库,因此可以硬编码此hack。否则,我将进行更多挖掘并修改函数以接受数组,而不是名称空间参数的字符串。


0
投票

[是的,我遇到了同样的问题(通过Google找到了您的q!),我遇到了这个问题:http://www.heidisoft.com/blog/using-nusoap-consume-net-web-service-10-min在这里,开发人员在coe中创建消息的xml正文,然后使用nusoap提交。


0
投票

必须配置使用nusoap参数

https://github.com/pwnlabs/nusoap

添加全局名称空间

$client->namespaces['tem'] = "http://tempuri.org/";

并为元素添加本地名称空间

 $dom  = new \DOMDocument('1.0');
            $document = $dom->createElement('tem:CAV_GET_DATA');
            $document = $dom->appendChild($document);
            $el = $dom->createElement("tem:UsuarioID", '111');
            $document->appendChild($el);
            $el = $dom->createElement("tem:Password", '111');
            $document->appendChild($el);
            $el = $dom->createElement("tem:idEmpleado", 111);
            $document->appendChild($el);
            $param = $dom->saveXML($dom->documentElement, LIBXML_NOEMPTYTAG);

示例完成

 $client = new nusoap_client('urlexamplee?WSDL', 'wsdl');
            $client->soap_defencoding = 'UTF-8';
            $client->response_timeout = 300
            $namespaces['tem'] = "http://tempuri.org/";

$dom  = new \DOMDocument('1.0');
                $document = $dom->createElement('tem:CAV_GET_DATA');
                $document = $dom->appendChild($document);
                $el = $dom->createElement("tem:UsuarioID", '111');
                $document->appendChild($el);
                $el = $dom->createElement("tem:Password", '111');
                $document->appendChild($el);
                $el = $dom->createElement("tem:idEmpleado", 111);
                $document->appendChild($el);
                $param = $dom->saveXML($dom->documentElement, LIBXML_NOEMPTYTAG);

 $responseService = $this->client->call(
                'CAV_GET_DATA',
                $param

            );

请求

<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tem="http://tempuri.org/" xmlns:ns6704="tem"><SOAP-ENV:Body><tem:CAV_GET_DATA><tem:UsuarioID>example</tem:UsuarioID><tem:Password>example</tem:Password><tem:idEmpleado>000000</tem:idEmpleado></tem:CAV_GET_DATA></SOAP-ENV:Body></SOAP-ENV:Envelope>
© www.soinside.com 2019 - 2024. All rights reserved.