views:

41

answers:

2

Hello,

After researching this on SO and google for hours now... I hope to get some help here: (I am just one step away from running a regex to remove the namespaces completely)

First this is the XML:

<?xml version="1.0" encoding="utf-16"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"&gt;
  <soap:Header xmlns="http://webservices.site.com/definitions"&gt;
    <SessionId>0119A|1</SessionId>
  </soap:Header>
  <soap:Body>
    <Security_AuthenticateReply xmlns="http://xml.site.com/QQ"&gt;
      <processStatus>
        <statusCode>P</statusCode>
      </processStatus>
    </Security_AuthenticateReply>
  </soap:Body>
</soap:Envelope>

Now this is what my code in PHP looks like:

$response = simplexml_load_string( $str ,NULL, 
false, "http://schemas.xmlsoap.org/soap/envelope/" );
// just making sure the name space is "registered"
// but I tested all examples also with this removed
$response->registerXPathNamespace("soap",
    "http://schemas.xmlsoap.org/soap/envelope/");
$_res = $response->xpath('//soap:Header');
print_r($_res);
/*** result: simple query for the root "soap" namespace, this looks good! (so far..)
Array
(
    [0] => SimpleXMLElement Object
        (
            [SessionId] => 0119A|1
        )

)
***/

// now we query for the "SessionId" element in the XML
$_res = $response->xpath('//soap:Header/SessionId');
print_r($_res);
/*** result: this does not return anything!
Array
(
)
***/

// another approach
$_res = $response->xpath('//soap:Header/SessionId/text()');
print_r($_res);
/*** result: this does not return anything at all!
***/

// Finally, without using XPath this does work
$_res = $response->xpath('//soap:Header');
$_res = (string)$_res[0]->SessionId;
echo $_res;
/*** result: this worked
0119A|1
***/

How can I get the SOAP message working with XPATH???

Thanks, Roman

+3  A: 

You need to register the default namespace used by <SessionId> element as well. Because <SessionId> is in the default namespace it does not have any prefix but in order to your XPath to work, you need to bind also this namespace to some prefix and then use that prefix in your XPath expression.

$response->registerXPathNamespace("ns",
    "http://webservices.site.com/definitions");
$_res = $response->xpath('//soap:Header/ns:SessionId');

XPath (1.0) expressions without a namespace prefix always match only to targets in no-namespace.

jasso
+1 For right answer **and explanation**
Alejandro
+1  A: 

The multiple namespaces are messing with it, adding the following works for me

$response->registerXPathNamespace("site", "http://webservices.site.com/definitions");
$_res = $response->xpath('//site:SessionId');

also, see this previous stack overflow question

Dave
Both answers were good, since you were the faster one (by one minute) I chose it as the right answer :)
Romansky