0

I'm trying to parse the following SOAP response, and need some guidance:

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
    <env:Header/>

    <env:Body>
        <ns2:LookupResponse xmlns:ns2="http://path-to/schemas">
        <ns2:Name>My Name</ns2:Name>
        <ns2:Address1>test</ns2:Address1>
        <ns2:Address2>test</ns2:Address2>
        ...
        </ns2:LookupResponse>
    </env:Body>
</env:Envelope>

I retreive the response via cURL:

$url        = 'https://path-to-service';
$success    = FALSE;
$ch         = curl_init();

curl_setopt($ch, CURLOPT_URL,           $url);                                                                
curl_setopt($ch, CURLOPT_RETURNTRANSFER,    true);  
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,    false);
curl_setopt($ch, CURLOPT_SSLVERSION,        3);
curl_setopt($ch, CURLOPT_POST,          true);
curl_setopt($ch, CURLOPT_POSTFIELDS,        $request);
curl_setopt($ch, CURLOPT_HTTPHEADER,        array(
                                                    'Content-Type: text/xml; charset=utf-8', 
                                                    'Content-Length: ' . strlen($request) 
                                                ));

$ch_result  = curl_exec($ch);
$ch_error   = curl_error($ch);

curl_close($ch);

I'm new to all of this, so forgive obvious errors, but I am then trying to iterate through the response as an object, as parsed by the simpleXML extension, referencing the SO answer here and using the simplexml_debug plugin to echo object content.

if(empty($ch_error))
{
    $xml    = simplexml_load_string($ch_result, NULL, NULL, "http://schemas.xmlsoap.org/soap/envelope/");
    $xml    ->registerXPathNamespace('env', 'http://schemas.xmlsoap.org/soap/envelope/');
    $xml    ->registerXPathNamespace('ns2', 'http://path-to/schemas');


    echo '<pre>';
    simplexml_dump($xml);
    echo '</pre>';

}
else
{
    echo 'error';
    show($ch_error);
    exit;
}

This gives me the following:

SimpleXML object (1 item)
[
Element {
    Namespace: 'http://schemas.xmlsoap.org/soap/envelope/'
    Namespace Alias: 'env'
    Name: 'Envelope'
    String Content: ''
    Content in Namespace env
        Namespace URI: 'http://schemas.xmlsoap.org/soap/envelope/'
        Children: 2 - 1 'Body', 1 'Header'
        Attributes: 0
}
]

I want to get to the stage where I can iterate through the Body of the XML document, using either a foreach loop, or merely pointing directly to the relevant data ($title = (string)$data->title;). How can I proceed from my current position to get to that stage? I don't really know what comes next, and I just flat-out don't understand the documentation provided for the SOAP extension in PHP. I would rather use 'basic' code to achieve what I need.

Community
  • 1
  • 1
Eamonn
  • 1,338
  • 2
  • 21
  • 53

1 Answers1

5

This topic should help you solving your problem.

Adapted to your problem :

$xml = simplexml_load_string($ch_result, NULL, NULL, "http://schemas.xmlsoap.org/soap/envelope/");
$ns = $xml->getNamespaces(true);
$soap = $xml->children($ns['env']);
$res = $soap->Body->children($ns['ns2']);

foreach ($res->LookupResponse as $item) {
    echo $item->Name.PHP_EOL;
}
Community
  • 1
  • 1
Tyrael
  • 123
  • 1
  • 6
  • Thanks for that reference. Trying this (with the same code): `$xml = simplexml_load_string($ch_result); $ns = $xml->getNamespaces(true); $envelope = $xml->children($ns['env']); $body = $envelope->body->children($ns['ns2']); echo $body->Name;` returns `Warning: main(): Node no longer exists`. Clearly I'm missing a step somewhere (although the logic is becoming clear to me)... – Eamonn Mar 28 '14 at 13:17
  • 2
    `$body` contains the parent of `LookupResponse` so you have to loop over them to get all the considered names ! You can do it like that : `foreach ($body->LookupResponse as $item) { echo $item->Name.PHP_EOL; }`. Also be **very** careful about the case of your elements : body <> Body ! So you have to write : `$body = $envelope->Body->children($ns['ns2']);`. – Tyrael Mar 28 '14 at 13:25