Как анализировать XML SOAP?

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> 

Как получить элемент «платеж»?

Я пытаюсь разобрать (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); } 

Результат пуст 🙁 Любые идеи, как правильно его разобрать?

Один из простейших способов обработки префиксов пространства имен – просто удалить их из ответа XML, прежде чем передавать его в simplexml, например, ниже:

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

Это вернет следующее:

 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 версия> 5.0 имеет красивый SoapClient интегрированный. Для чего не требуется анализировать ответ xml. Вот краткий пример

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

В вашем коде вы запрашиваете элемент payment в пространстве имен по умолчанию, но в ответе XML он объявлен как в пространстве имен http://apilistener.envoyservices.com .

Итак, вам не хватает объявления пространства имен :

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

Теперь вы можете использовать префикс пространства имен envoy в вашем запросе xpath:

 xpath('//envoy:payment') 

Полный код:

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

Примечание . Я удалил декларацию пространства имен soap поскольку вы, кажется, не используете его (полезно, если вы будете использовать префикс пространства имен в запросах xpath).

 $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; 

Результат:

 2010-11-15T15:19:45 

почему бы вам не попробовать использовать абсолютный xPath

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

или так как вы знаете, что это платеж и платеж не имеют каких-либо атрибутов, просто выберите непосредственно из платежа

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