BMN
BMN

Reputation: 8508

PHP - Use multiple xmlns in Envelope with SoapClient

I'm trying to make a SOAP call with multiple xmlns namespaces in the soap call envelope, but I can't figure out how to do it properly...

Here's the code I have right now :

$soapClient = new SoapClient(WSDL_URL, array(
            "trace" => true,
            "exceptions" => true
        ));
$soapClient->__setLocation(WSDL_LOCATION);

$request = '
        <ns1:someNodeName xmlns="http://some.webservice.url.com">
            <ns2:someOtherNodeName>
                // [REQUEST DETAILS]
            </ns2:someOtherNodeName>
        </ns1:someNodeName>
    ';

$params = new SoapVar($request, XSD_ANYXML);

try {
    $results = $soapClient->someFunctionName($params);
    return $results;
}
catch (Exception $e) {
    $error_xml =  $soapClient->__getLastRequest();
    echo $error_xml . "\n";
    echo $e->getMessage() . "\n";
}

This code gives me an XML request like the following :

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://some.webservice.url.com">
    <SOAP-ENV:Body>
        <ns1:someNodeName xmlns="http://some.webservice.url.com">
            <ns2:someOtherNodeName>
                // [REQUEST DETAILS]
            </ns2:someOtherNodeName>
        </ns1:someNodeName>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

What I'm trying to change is the Envelope line, to get something like :

<SOAP-ENV:Envelope 
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:ns1="http://some.webservice.url.com" 
    xmlns:ns2="http://some.other.webservice.url.com"
>

Is there any way I can achieve this please ?

Upvotes: 3

Views: 1809

Answers (1)

ThW
ThW

Reputation: 19512

The XMLNS attributes are namespace definitions, they are added if you add nodes in that namespace. They do not need to be on the root element, but on the element that uses it or one of its ancestors.

$request = '
    <ns1:someNodeName 
       xmlns:ns1="http://some.webservice.url.com"                 
       xmlns:ns2="http://some.other.webservice.url.com">
        <ns2:someOtherNodeName>
            // [REQUEST DETAILS]
        </ns2:someOtherNodeName>
    </ns1:someNodeName>
';

If you create XML dynamically you should use an XML extension like DOM or XMLWriter. They have specific methods to create elements with namespaces and will add the definitions automatically.

$xmlns = [
  'ns1' => "http://some.webservice.url.com",                 
  'ns2' => "http://some.other.webservice.url.com"
];

$document = new DOMDocument();
$outer = $document->appendChild(
  $document->createElementNS($xmlns['ns1'], 'ns1:someNodeName')
);
$inner = $outer->appendChild(
  $document->createElementNS($xmlns['ns2'], 'ns2:someOtherNodeName')
);
$inner->appendChild(
  $document->createComment('[REQUEST DETAILS]')
);

$document->formatOutput = TRUE;
echo $document->saveXml($outer);

Output:

<ns1:someNodeName xmlns:ns1="http://some.webservice.url.com">
  <ns2:someOtherNodeName xmlns:ns2="http://some.other.webservice.url.com">
    <!--[REQUEST DETAILS]-->
  </ns2:someOtherNodeName>
</ns1:someNodeName>

Upvotes: 1

Related Questions