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?
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
)
)
)
)
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;
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).
$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
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);
This is also quite nice if you subsequently need to resolve any objects into arrays: $array = json_decode(json_encode($responseXmlObject), true);
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);
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/*
Success story sharing