2010-11-16 3 views
37

SOAP XML:Как разобрать 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); 
} 

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

+0

добро пожаловать в SO. в следующий раз нажмите кнопку формата в верхней части текстового поля, чтобы код был легче читать. – stillstanding

+0

@stillstanding: Ох, по-видимому, я переписал ваше редактирование так же, как вы его отправили :) – BoltClock

+0

В ожидании помощи ..... – Anton

ответ

-2

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

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

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

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

foreach ($ xml-> xpath ('// soap: Envelope [1]/soap: Body [1]/PaymentNotification [1]/payment/* ') как $ item) { print_r ($ item); } тоже пусто ( – Anton

+0

попробуйте дать ваше второе пространство имен фактического значения и определить, что тогда – almightyBob

+0

вы могли бы дать пример пожалуйста – Anton

21

В вашем коде вы запрашиваете элемент 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).

41

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; 
+0

спас меня много усилий! –

+2

Что такое SoapFunction? – Edward

+0

@Edward это любая функция (операция), определенная в WSDL службы SOAP, которую вы хотите получить. – Ivan

6
$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 
+0

Это будет работать, но это не технически правильно. Вы рассматриваете XML-ответ SOAP как документ DOM, которого нет. –

56

Один из самых простых способов обработки префиксов пространства имен просто лишить их из ответа 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

Пространства имен обычно вводят в заблуждение, и удаление его, по-видимому, является самым быстрым (взломанным) способом восстановления надлежащего объекта xml. thx –

+14

Удивительное решение. мыло сосет. –

+3

В моем случае мне пришлось добавить еще пару значений массива в str_ireplace, но в итоге это было единственным рабочим решением, которое я нашел. Upvoted. Также согласился с мылом @JohnBallinger. – GTCrais

0

Это также очень приятно, если вы впоследствии должны решить любые объекты в массивы: массива $ = json_decode (json_encode ($ responseXmlObject), правда);

Смежные вопросы