Using xpath on a PHP SimpleXML object, SOAP + namespaces (not working..)
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/">
<soap:Header xmlns="http://webservices.site.com/definitions">
<SessionId>0119A|1</SessionId>
</soap:Header>
<soap:Body>
<Security_AuthenticateReply xmlns="http://xml.site.com/QQ">
<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 a开发者_C百科nything 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
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
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.
精彩评论