soapenv simplexmlelement simplexml_load_string respuesta read leer php xml soap

php - simplexmlelement - Cómo analizar XML SOAP?



soap xml php (7)

¿Por qué no intentas usar un xPath absoluto?

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

o ya que sabe que se trata de un pago y el pago no tiene ningún atributo, simplemente seleccione directamente desde el pago

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

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>

¿Cómo obtener el elemento ''pago''?

Intento 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); }

El resultado está vacío :( ¿Alguna idea de cómo analizarla es correcta?


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

Entonces, te falta una declaración de espacio de nombres :

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

Ahora puede usar el prefijo del espacio de nombres del envoy 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 de soap porque parece que no la está usando (solo es útil si usa el prefijo del espacio de nombres en sus consultas de xpath).


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


La versión de PHP> 5.0 tiene un buen SoapClient integrado. Lo cual no requiere analizar la respuesta xml. Aquí hay un ejemplo rápido

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


Primero, necesitamos filtrar el XML para analizar eso en un objeto

$response = strtr($xml_string, [''</soap:'' => ''</'', ''<soap:'' => ''<'']); $output = json_decode(json_encode(simplexml_load_string($response))); var_dump($output->Body->PaymentNotification->payment);


Una de las maneras más sencillas de manejar prefijos de espacio de nombres es simplemente quitarlos de la respuesta XML antes de pasarlos a simplexml como se muestra 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 lo 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 ) ) ) )


$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