Как анализировать 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);
}
Результат пуст:(
Любые идеи, как правильно его разобрать?
Ответы
Ответ 1
Один из простейших способов обработки префиксов пространства имен - просто отделить их от ответа 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
)
)
)
)
Ответ 2
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;
Ответ 3
В вашем коде вы запрашиваете элемент 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).
Ответ 4
$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
Ответ 5
почему бы вам не попробовать использовать абсолютный xPath
//soap:Envelope[1]/soap:Body[1]/PaymentNotification[1]/payment
или так как вы знаете, что это платеж и платеж не имеют каких-либо атрибутов, просто выберите непосредственно из оплаты
//soap:Envelope[1]/soap:Body[1]/PaymentNotification[1]/payment/*