How to parse SOAP XML?

PhpXmlSoap

Php Problem Overview


SOAP XML:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <PaymentNotification xmlns="http://apilistener.envoyservices.com">
      <payment>
        <uniqueReference>ESDEUR11039872</uniqueReference>      
        <epacsReference>74348dc0-cbf0-df11-b725-001ec9e61285</epacsReference>
        <postingDate>2010-11-15T15:19:45</postingDate>
        <bankCurrency>EUR</bankCurrency>
        <bankAmount>1.00</bankAmount>
        <appliedCurrency>EUR</appliedCurrency>
        <appliedAmount>1.00</appliedAmount>
        <countryCode>ES</countryCode>
        <bankInformation>Sean Wood</bankInformation>
  <merchantReference>ESDEUR11039872</merchantReference>
   </payment>
    </PaymentNotification>
  </soap:Body>
</soap:Envelope>

How to get 'payment' element?

I try to parse (PHP)

$xml = simplexml_load_string($soap_response);
$xml->registerXPathNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
foreach ($xml->xpath('//payment') as $item)
{
    print_r($item);
}

Result is empty :( Any ideas how to parse it correct?

Php Solutions


Solution 1 - Php

One of the simplest ways to handle namespace prefixes is simply to strip them from the XML response before passing it through to simplexml such as below:

$your_xml_response = '<Your XML here>';
$clean_xml = str_ireplace(['SOAP-ENV:', 'SOAP:'], '', $your_xml_response);
$xml = simplexml_load_string($clean_xml);

This would return the following:

SimpleXMLElement Object
(
    [Body] => SimpleXMLElement Object
        (
            [PaymentNotification] => SimpleXMLElement Object
                (
                    [payment] => SimpleXMLElement Object
                        (
                            [uniqueReference] => ESDEUR11039872
                            [epacsReference] => 74348dc0-cbf0-df11-b725-001ec9e61285
                            [postingDate] => 2010-11-15T15:19:45
                            [bankCurrency] => EUR
                            [bankAmount] => 1.00
                            [appliedCurrency] => EUR
                            [appliedAmount] => 1.00
                            [countryCode] => ES
                            [bankInformation] => Sean Wood
                            [merchantReference] => ESDEUR11039872
                        )

                )

        )

)

Solution 2 - Php

PHP version > 5.0 has a nice SoapClient integrated. Which doesn't require to parse response xml. Here's a quick example

$client = new SoapClient("http://path.to/wsdl?WSDL");
$res = $client->SoapFunction(array('param1'=>'value','param2'=>'value'));
echo $res->PaymentNotification->payment;

Solution 3 - Php

In your code you are querying for the payment element in default namespace, but in the XML response it is declared as in http://apilistener.envoyservices.com namespace.

So, you are missing a namespace declaration:

$xml->registerXPathNamespace('envoy', 'http://apilistener.envoyservices.com');

Now you can use the envoy namespace prefix in your xpath query:

xpath('//envoy:payment')

The full code would be:

$xml = simplexml_load_string($soap_response);
$xml->registerXPathNamespace('envoy', 'http://apilistener.envoyservices.com');
foreach ($xml->xpath('//envoy:payment') as $item)
{
    print_r($item);
}

Note: I removed the soap namespace declaration as you do not seem to be using it (it is only useful if you would use the namespace prefix in you xpath queries).

Solution 4 - Php

$xml = '<?xml version="1.0" encoding="utf-8"?>
				<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
				  <soap:Body>
				    <PaymentNotification xmlns="http://apilistener.envoyservices.com">
				      <payment>
				        <uniqueReference>ESDEUR11039872</uniqueReference>
				        <epacsReference>74348dc0-cbf0-df11-b725-001ec9e61285</epacsReference>
				        <postingDate>2010-11-15T15:19:45</postingDate>
				        <bankCurrency>EUR</bankCurrency>
				        <bankAmount>1.00</bankAmount>
				        <appliedCurrency>EUR</appliedCurrency>
				        <appliedAmount>1.00</appliedAmount>
				        <countryCode>ES</countryCode>
				        <bankInformation>Sean Wood</bankInformation>
				  <merchantReference>ESDEUR11039872</merchantReference>
				   </payment>
				    </PaymentNotification>
				  </soap:Body>
				</soap:Envelope>';
		$doc = new DOMDocument();
		$doc->loadXML($xml);
		echo $doc->getElementsByTagName('postingDate')->item(0)->nodeValue;
		die;

Result is:

2010-11-15T15:19:45

Solution 5 - Php

First, we need to filter the XML so as to parse that into an object

$response = strtr($xml_string, ['</soap:' => '</', '<soap:' => '<']);
$output = json_decode(json_encode(simplexml_load_string($response)));
var_dump($output->Body->PaymentNotification->payment);

Solution 6 - Php

This is also quite nice if you subsequently need to resolve any objects into arrays: $array = json_decode(json_encode($responseXmlObject), true);

Solution 7 - Php

First, we need to filter the XML so as to parse that change objects become array

//catch xml
$xmlElement = file_get_contents ('php://input');
//change become array
$Data = (array)simplexml_load_string($xmlElement);
//and see
print_r($Data);

Solution 8 - Php

why don't u try using an absolute xPath

//soap:Envelope[1]/soap:Body[1]/PaymentNotification[1]/payment

or since u know that it is a payment and payment doesn't have any attributes just select directly from payment

//soap:Envelope[1]/soap:Body[1]/PaymentNotification[1]/payment/*

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAntonView Question on Stackoverflow
Solution 1 - PhpAranView Answer on Stackoverflow
Solution 2 - PhpIvanView Answer on Stackoverflow
Solution 3 - PhpNeeme PraksView Answer on Stackoverflow
Solution 4 - PhpBảo NamView Answer on Stackoverflow
Solution 5 - PhpUTKARSH SINGHALView Answer on Stackoverflow
Solution 6 - PhpomarjebariView Answer on Stackoverflow
Solution 7 - PhpDavid KurniawanView Answer on Stackoverflow
Solution 8 - PhpalmightyBobView Answer on Stackoverflow