1

All,

Trying to parse this SOAP response but xpath() is returning

Debug Warning: SimpleXMLElement::xpath() Undefined namespace prefix Debug Warning: SimpleXMLElement::xpath() evaluation failed

 $result = '<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <env:Header xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
    <env:Body xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <v4:TrackReply xmlns:v4="http://fedex.com/ws/track/v4">
            ...
        </v4:TrackReply>
    </env:Body>
</soapenv:Envelope>';


 $xml = simplexml_load_string($result,NULL,NULL,'http://schemas.xmlsoap.org/soap/envelope/');



foreach($xml->xpath('env:Body') as $body){

    //drill down here...
}
Slinky
  • 5,662
  • 14
  • 76
  • 130

2 Answers2

2

Try registering the namespace to 'env'

$xml->registerXPathNamespace('env', 'http://schemas.xmlsoap.org/soap/envelope/');

Edit This code sets the namespace of child elements within body

$bodies = $xml->xpath('env:Body');
foreach($bodies as $body){
    $reply = $body->children('v4', TRUE)->TrackReply;
    var_dump($reply);
}

Alternatively, you can get an element like TrackReply directly with:

$xml->registerXPathNamespace('env', 'http://schemas.xmlsoap.org/soap/envelope/');
$xml->registerXPathNamespace('v4', 'http://fedex.com/ws/track/v4');
var_dump($xml->xpath('env:Body/v4:TrackReply'));
brian_d
  • 11,190
  • 5
  • 47
  • 72
  • by calling registerXPathNamespace() I am able to enter my foreach loop because $xml->xpath('env:Body') now creates an empty SimpleXMLElement object – Slinky Jun 23 '11 at 15:48
  • @Slinky see updated answer - the SimpleXMLElement objects do look empty, but actually contain information – brian_d Jun 23 '11 at 16:09
-1

SimpleXML ignores the env: part of the XML structure and instead returns an object constructed like this:

SimpleXMLElement Object
(
    [Header] => SimpleXMLElement Object
        (
        )

    [Body] => SimpleXMLElement Object
        (
        )

)

You can access the body with the following XPath query: $xml->xpath('Body') or just access the child by using the following syntax: $xml->Body.

mensch
  • 4,411
  • 3
  • 28
  • 49