2010-11-16 21 views
37

XML SOAP:Cómo analizar XML de SOAP?

<?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> 

Como ir elemento de 'pago'?

trato de analizar (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); 
} 

resultados no tiene ningún :( Alguna idea de cómo analizarlo correcta?

+0

bienvenido a SO. la próxima vez, haga clic en el botón de formato en la parte superior del área de texto para que el código sea más fácil de leer. – stillstanding

+0

@stillstanding: Ooh, al parecer, sobrescribí tu edición tal como la enviaste :) – BoltClock

+0

Esperando ayuda ..... – Anton

Respuesta

-2

¿por qué no intento de u usando un XPath absoluta

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

o como usted sabe que es un pago y el pago no tiene ningún atributo simplemente seleccione directamente del pago

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

foreach ($ xml-> xpath ('// soap: Sobre [1]/soap: Body [1]/PaymentNotification [1]/payment/* ') como $ item) { print_r ($ item); } también vacía ( – Anton

+0

tratar de darle a su segundo espacio de nombres de un valor real y definen a continuación, que podría darle – almightyBob

+0

ejemplo favor – Anton

21

En el código se está consultando para el elemento payment en espacio de nombres por defecto, pero en la respuesta XML se declara como en http://apilistener.envoyservices.com espacio de nombres.

Así, se echa en falta una declaración de espacio de nombres:

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

Ahora puede utilizar el prefijo envoy espacio de nombres en su consulta XPath:

xpath('//envoy:payment') 

El código completo sería:

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

Nota: Eliminé la declaración del espacio de nombres soap porque parece que no la está usando (solo es útil si usa el prefijo del espacio de nombres en sus consultas xpath).

41

Versión PHP> 5.0 tiene un agradable SoapClient integrado. Lo cual no requiere analizar la respuesta xml. Aquí está un ejemplo rápido

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

me salvó un montón de esfuerzo hombre !! –

+2

¿Qué es SoapFunction aquí? – Edward

+0

@Edward es cualquier función (operación) definida en el WSDL del servicio SOAP a la que desea acceder – 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; 

El resultado es:

2010-11-15T15:19:45 
+0

Esto funcionaría, pero no es técnicamente correcto. Está considerando que la respuesta XML de SOAP es un documento DOM, que no lo es. –

56

Una de las formas más sencillas de manejar prefijos de espacio de nombres es simplemente para despojarlos de la respuesta XML antes de pasarlo a través de simplexml como a continuación:

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

Esto devolvería el siguiente:

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

Los espacios de nombre suelen ser engañosos y eliminarlos parece ser la forma más rápida (piratear) de restaurar el objeto xml apropiado. thx –

+14

increíble solución. el jabón apesta. –

+3

En mi caso, tuve que agregar un par de valores de matriz a str_ireplace, pero al final esta fue la única solución de trabajo que encontré. Upvoted. También está de acuerdo con el jabón de @JohnBallinger es una mierda. – GTCrais

0

Esto también es bastante agradable si posteriormente necesita para resolver cualquier objeto en las matrices: $ array = json_decode (json_encode ($ responseXmlObject), true);

Cuestiones relacionadas