2

I'm building a SOAP message for the first time and playing it with PHP.

The requirements are SOAP version 1.1 with Style/Enconding: Document/Literal pattern.

Using SimpleXMLElement:

    $soapEnv = '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://www.w3.org/2003/05/soap-envelope"></soap:Envelope>';
    $soapEnvElement = new \SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?>' . $soapEnv);
    $soapEnvElement->addChild('soap:Header');
    $bodyElement = $soapEnvElement->addChild('soap:Body');
    $bodyElement->addChild('node');
    echo $soapEnvElement->asXML();

Expected output:

<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
  <soap:Header/>
  <soap:Body>
    <node/>
  </soap:Body>
</soap:Envelope>

Actual output:

<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
  <soap:Header/>
  <soap:Body>
    <soap:node/>
  </soap:Body>
</soap:Envelope>

Question

Why is this happening?

Is it possible to disable this behavior?

IMSoP
  • 89,526
  • 13
  • 117
  • 169
Alexandre Thebaldi
  • 4,546
  • 6
  • 41
  • 55
  • 1
    Possible duplicate of [PHP SimpleXML->addChild - unwanted empty namespace attribute](https://stackoverflow.com/questions/4672274/php-simplexml-addchild-unwanted-empty-namespace-attribute) – splash58 Dec 18 '17 at 20:57
  • @spash58 , the link you provided does answer what AlexandreThebaldi asked, but it's worth keeping this question as a non-duplicate, because it is slightly different. – Brian Gottier Dec 19 '17 at 00:29

1 Answers1

0

@splash58's comment does indeed answer your question.

The linked question has an answer that explains perfectly what is going on.

For SimpleXML c needs a namespace. If you specify one, it gets an xmlns attribute because what you specified has not been declared before. If you don't specify a namespace for c, it inherits the namespace from the parent node. The only option here is ns1. (This happens to d.)

To prevent inhertance of the parent namespace and omit empty xmlns you'd need an namespace like xmlns="http://example.com" at the parent. Then $it->addChild('c', 'no ns', 'http://example.com') gives you no ns.

Proof:

<?php

// Notice here that I added the extra namespace for http://example.com.
$soapEnv = '<soap:Envelope xmlns="http://example.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://www.w3.org/2003/05/soap-envelope"></soap:Envelope>';
$soapEnvElement = new \SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?>' . $soapEnv);
$soapEnvElement->addChild('soap:Header');
$bodyElement = $soapEnvElement->addChild('soap:Body');
// Here I am applying the empty namespace so it doesn't inherit from the parent node.
$bodyElement->addChild('node', '', 'http://example.com');
echo $soapEnvElement->asXML();

Which outputs:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns="http://example.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
    <soap:Header/>
    <soap:Body>
        <node/>
    </soap:Body>
</soap:Envelope>
Community
  • 1
  • 1
Brian Gottier
  • 4,522
  • 3
  • 21
  • 37
  • By the way, do you know how to add the `xmlns` attribute directly on `node` element when creating it? This would be a most appropriate behavior for my case. By default, PHP creates an empty `xmlns` that I can't fill it after. – Alexandre Thebaldi Dec 19 '17 at 09:43