How to use nuSOAP for messages with multiple namespaces
Asked Answered
W

4

7

I'm trying to access a WebService using nuSOAP (because I'm bound to PHP4 here) that uses more than 1 namespace in a message. Is that possible?

An example request message would look like this:

<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>

I tried to following:

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

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

in the hope that nuSOAP would try to match these names to the correct namespaces and nodes. Then I tried to use soapval() to generate the elements and their namespace - but if I call an operation, nuSOAP creates the following request:

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

So something goes wrong during the "matching" phase.

Weanling answered 1/4, 2009 at 8:34 Comment(0)
W
5

After trying around with the matching, I found two possible solutions:

1) Don't use the WSDL to create the nusoap_client and soapval() to create the message This has the disadvantage that the message contains a lot of overhead (the namespace is defined in each element). Not so fine.

2) Instead of relying on the matching of parameters, construct your reply in xml and put all the definition for prefixes in the first element - e.g.

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

Still not a very nice solution, but it works :-)

Weanling answered 9/4, 2009 at 12:49 Comment(0)
P
4

Building on Irwin's post, I created the xml manually and had nusoap do the rest. My webhost does not have the php soap extension, so I had to go with nusoap, and the web service I'm trying to consume required the namespaces on each tag (e.g. on username and password in my example here).

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>';

Then I had an error that said:

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

So I went the lazy route and went into nusoap.php and added this code before line 7674 to make it happy:

    if(empty($this->operation)) {
        $this->operation = "";
    }
Phenosafranine answered 8/6, 2010 at 21:41 Comment(1)
After scouring the internet for days this is the only thing that helped me figure it out. Thank you! I didn't get that error but I had to set $client->endpoint = '<endpoint url>';Srini
E
2

Another bypass this issue would be a modification to nusoap_client::call() function. Next to the this line (7359 in version 1.123) in nusoap.php:

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

I added this one:

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

And it worked! Since I only needed this library for one project, it was OK for me to hardcode this hack. Otherwise, I would dig more and modify the function to accept array instead of string for a namespace parameter.

Extrabold answered 14/12, 2010 at 1:6 Comment(0)
D
0

Yeah, i've been having this same problem (found your q via google!) and i've come across this: http://www.heidisoft.com/blog/using-nusoap-consume-net-web-service-10-min Here, the dev creates the xml body of the message in coe and then uses nusoap to submit.

Denoting answered 5/11, 2009 at 11:20 Comment(1)
Hmm, seems the link is currently not working. From what you say, it seems they followed a similar approach (creating the xml "manually"), right?Weanling

© 2022 - 2024 — McMap. All rights reserved.