Soap php запросы xml php

Parsing SOAP XML response with php

One of the simplest ways to handle namespace prefixes is simply to strip them from the XML response before passing it through to simplexml such as below:,PHP version > 5.0 has a nice SoapClient integrated. Which doesn’t require to parse response xml. Here’s a quick example, This works but only with static xml passed to the «$xml» variable. Return empty result when passed SOAP Response to it. – Sonu Singh Jadoun Feb 12 ’20 at 13:16 ,In your code you are querying for the payment element in default namespace, but in the XML response it is declared as in http://apilistener.envoyservices.com namespace.

One of the simplest ways to handle namespace prefixes is simply to strip them from the XML response before passing it through to simplexml such as below:

$your_xml_response = ''; $clean_xml = str_ireplace(['SOAP-ENV:', 'SOAP:'], '', $your_xml_response); $xml = simplexml_load_string($clean_xml); 

This would return the following:

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

Answer by Aubrie Hopkins

Simply calling $xml->SOAP-ENV:Envelope will result in an error due to the fact that hyphens and colons are not valid characters for object variables or methods. Whenever you are entering a new namespace, you can use SimpleXMLElement::children() to define the name space. The second argument tells the method that you are defining a prefix and not a namespace URL.,Please note that the SimpleXMLElement::children() method will always return a SimpleXMLElement whether the node has any children or not.,Setting an authorization header when using file_get_contents with PHP, Extreme Teams: Why Pixar, Netflix, AirBnB, and Other Cutting-Edge Companies Succeed Where Most Fail

// Mocks our SOAP response $soap_response =     Parsing SOAP responses with SimpleXML Awesome post about parsing SOAP responses. 2014-07-13 Josh Sherman @joshtronic  http://phpave.com/parsing-soap-responses-with-simplexml/  How to parse XML with SimpleXML Awesome post about parsing XML. 2014-07-29 Josh Sherman @joshtronic  http://phpave.com/how-to-parse-xml-with-simplexml/     XML; // Loads the XML $xml = simplexml_load_string($soap_response); // Grabs the posts $posts = $xml->children('SOAP-ENV', true)->Body->children('ns1', true)->Posts->Post; // Take the posts and generate some markup foreach ($posts as $post) < $twitter_url = 'https://twitter.com/' . $post->Author->Twitter; echo ' 

' . $post->Title . '

' . $post->Author->Name . '

' . $post->Description . '

Link . '">Read Article
'; >

Answer by Ramon Berg

I’m afraid I’m at a loss on how to parse this XML with namespaces and prefixes. Here’s the SOAP reply I get from a Curl request:,XML namespaces are used for providing uniquely named elements and attributes in an XML document:,First I use curl to login and send the SOAP request as outlined in this answer: https://stackoverflow.com/a/7157785/1121877,The rate data can be accessed like this:

Читайте также:  Css import construct 2

I’m afraid I’m at a loss on how to parse this XML with namespaces and prefixes. Here’s the SOAP reply I get from a Curl request:

Edit: here’s some things I’ve tried (amongst others):

$xml = simplexml_load_string($soap); $result = $xml->children('http://schemas.xmlsoap.org/soap/envelope/') ->children('https://service.printapi.de/interface/') ->getproductpricekonfigurationresult ->objektpreisnetto; echo $result->objektpreisnetto; 

Here’s an even more basic example I tried, which also returns nothing:

$xml = simplexml_load_string($soap); foreach ($xml->children('http://schemas.xmlsoap.org/soap/envelope/') as $child) < echo "Child node: " . $child . "
"; >

Answer by Tyson Sosa

If you can’t use SoapClient to retrieve the SOAP response in a PHP object, then use SimpleXML to parse the soap response.,For example (where $xmlstr contains the SOAP response):,The best solution would be to use PHP’s SoapClient class to do the call which will return you an object and then converting this object to an array, like so:,I want to convert a soap xml response and store it in a database. Here is the XML that I have.

I want to convert a soap xml response and store it in a database. Here is the XML that I have.

     200 example2 ex2 [email protected]e2.com example2, example2 example2, example2 example2 111111 1111111111 11.11,-11.11 /example2/exam2/ex2      

Answer by Zavier Johnston

   VENDORKEYAUTHORIZED8e072cc1a 
 true)); $params->vendorKey = 'blahblah'; $params->dealerId = 'fakename'; $submit = $client->GetAuthToken($params); $response = $client->__getLastResponse(); $xmlString = preg_replace("/(]*>)/", "$1$2$3", $response); $xml = SimpleXML_Load_String($xmlString); $xml = new SimpleXMLElement($xml->asXML()); $parse = $xml->soapBody->GetAuthTokenResponse->GetAuthTokenResult; $token_xml = new SimpleXMLElement($parse->asXML()); $token = simplexml_load_string($token_xml); $AuthToken = $token->Status->Message; echo $AuthToken; ?> 

Answer by Presley Portillo

I found a perfect solution to parse SOAP response to an Array:,we can get body of the response from SOAP the following ways,The following SOAP response structure can be easily converted in an array using a combination of the previous methods. Using only the the function «simplexml_load_string» removing the colon «:» it returned null in some cases.

SOAP Response

    94567 3958 3 Declinada 202 93815.0 86815.0 0.0 COP 24-07-2015 12:18:40 PM REJECT 1 VISA 411111 1111  3      

PHP conversion:

$response = preg_replace("/(]*>)/", "$1$2$3", $response); $xml = new SimpleXMLElement($response); $body = $xml->xpath('//SBody')[0]; $array = json_decode(json_encode((array)$body), TRUE); print_r($array); 
Array ( [ns2transaccionResponse] => Array ( [respuestaTransaccion] => Array ( [idTransaccion] => 94567 [referencia] => 3958 [idEstado] => 3 [nombreEstado] => Declinada [codigoRespuesta] => 202 [valor] => 93815.0 [iva] => 86815.0 [baseDevolucion] => 0.0 [isoMoneda] => COP [fechaProcesamiento] => 24-07-2015 12:18:40 PM [mensaje] => REJECT [tarjetaRespuesta] => Array ( [idFranquicia] => 1 [nombreFranquicia] => VISA [numeroBin] => 411111 [numeroProducto] => 1111 ) [procesadorRespuesta] => Array ( [idProcesador] => 3 ) ) ) ) 

I found a perfect solution to parse SOAP response to an Array:

$plainXML = mungXML( trim($soapXML) ); $arrayResult = json_decode(json_encode(SimpleXML_Load_String($plainXML, 'SimpleXMLElement', LIBXML_NOCDATA)), true); print_r($arrayResult); // FUNCTION TO MUNG THE XML SO WE DO NOT HAVE TO DEAL WITH NAMESPACE function mungXML($xml) < $obj = SimpleXML_Load_String($xml); if ($obj === FALSE) return $xml; // GET NAMESPACES, IF ANY $nss = $obj->getNamespaces(TRUE); if (empty($nss)) return $xml; // CHANGE ns: INTO ns_ $nsm = array_keys($nss); foreach ($nsm as $key) < // A REGULAR EXPRESSION TO MUNG THE XML $rgx = '#' // REGEX DELIMITER . '(' // GROUP PATTERN 1 . '\' // A COLON (EXACTLY ONE) . ')' // END GROUP PATTERN . '#' // REGEX DELIMITER ; // INSERT THE UNDERSCORE INTO THE TAG NAME $rep = '$1' // BACKREFERENCE TO GROUP 1 . '_' // LITERAL UNDERSCORE IN PLACE OF GROUP 2 ; // PERFORM THE REPLACEMENT $xml = preg_replace($rgx, $rep, $xml); > return $xml; > // End :: mungXML() 
$xml = new SimpleXMLElement($soapResponse); foreach($xml->xpath('//soap:body') as $header) < $output = $header->registerXPathNamespace('default', 'http://FpwebBox.Fareportal.com/Gateway.asmx'); > 
$doc = new DOMDocument('1.0', 'utf-8'); $doc->loadXML( $soapResponse ); $XMLresults = $doc->getElementsByTagName("SearchFlightAvailability33Response"); $output = $XMLresults->item(0)->nodeValue; 

Источник

SOAP

PROBLEM (with SOAP extension under PHP5) of transferring object, that contains objects or array of objects. Nested object would not transfer.

SOLUTION:
This class was developed by trial and error by me. So this 23 lines of code for most developers writing under PHP5 solves fate of using SOAP extension.

/*
According to specific of organization process of SOAP class in PHP5, we must wrap up complex objects in SoapVar class. Otherwise objects would not be encoded properly and could not be loaded on remote SOAP handler.

Function «getAsSoap» call for encoding object for transmission. After encoding it can be properly transmitted.
*/
abstract class SOAPable public function getAsSOAP () foreach( $this as $key =>& $value ) $this -> prepareSOAPrecursive ( $this -> $key );
>
return $this ;
>

private function prepareSOAPrecursive (& $element ) if( is_array ( $element )) foreach( $element as $key =>& $val ) $this -> prepareSOAPrecursive ( $val );
>
$element =new SoapVar ( $element , SOAP_ENC_ARRAY );
>elseif( is_object ( $element )) if( $element instanceof SOAPable ) $element -> getAsSOAP ();
>
$element =new SoapVar ( $element , SOAP_ENC_OBJECT );
>
>
>

class PersonList extends SOAPable protected $ArrayOfPerson ; // variable MUST be protected or public!
>

class Person extends SOAPable //any data
>

$client =new SoapClient ( «test.wsdl» , array( ‘soap_version’ => SOAP_1_2 , ‘trace’ => 1 , ‘classmap’ => array( ‘Person’ => «Person» , ‘PersonList’ => «PersonList» ) ));

$PersonList =new PersonList ;

$client -> someMethod ( $PersonList );

?>

So every class, which will transfer via SOAP, must be extends from class SOAPable.
As you can see, in code above, function prepareSOAPrecursive search another nested objects in parent object or in arrays, and if does it, tries call function getAsSOAP() for preparation of nested objects, after that simply wrap up via SoapVar class.

So in code before transmitting simply call $obj->getAsSOAP()

If you are having an issue where SOAP cannot find the functions that are actually there if you view the wsdl file, it’s because PHP is caching the wsdl file (for a day at a time). To turn this off, have this line on every script that uses SOAP: ini_set(«soap.wsdl_cache_enabled», «0»); to disable the caching feature.

Juste a note to avoid wasting time on php-soap protocol and format support.

Until php 5.2.9 (at least) the soap extension is only capable of understanding wsdl 1.0 and 1.1 format.

The wsdl 2.0, a W3C recommendation since june 2007, ISN’T supported in php soap extension.
(the soap/php_sdl.c source code don’t handle wsdl2.0 format)

The wsdl 2.0 is juste the 1.2 version renamed because it has substantial differences from WSDL 1.1.

The differences between the two format may not be invisible if you don’t care a lot.

The typical error message if you provide a wsdl 2.0 format file :
PHP Fatal error: SOAP-ERROR: Parsing WSDL: Couldn’t find in ‘wsdl/example.wsdl’ in /path/client.php on line 9

Was calling an asmx method like $success=$x->AuthenticateUser($userName,$password) and this was returning me an error.

However i changed it and added the userName and password in an array and its now KAWA.

If anyone is trying to use this for accessing Sabre’s web services, it won’t work. Sabre checks the request header «Content-Type» to see if it is «text/xml» . If it is not text/xml then it sends an error back.

You will need to create a socket connection and use that to send the request over.

Here is an example of a php client talking to a asmx server:

// Prepare SoapHeader parameters
$sh_param = array(
‘Username’ => ‘username’ ,
‘Password’ => ‘password’ );
$headers = new SoapHeader ( ‘http://soapserver.example.com/webservices’ , ‘UserCredentials’ , $sh_param );

// Prepare Soap Client
$soapClient -> __setSoapHeaders (array( $headers ));

// Setup the RemoteFunction parameters
$ap_param = array(
‘amount’ => $irow [ ‘total_price’ ]);

// Call RemoteFunction ()
$error = 0 ;
try <
$info = $soapClient -> __call ( «RemoteFunction» , array( $ap_param ));
> catch ( SoapFault $fault ) <
$error = 1 ;
print( »
alert(‘Sorry, blah returned the following ERROR: » . $fault -> faultcode . «-» . $fault -> faultstring . «. We will now take you back to our home page.’);
window.location = ‘main.php’;
» );
>

if ( $error == 0 ) <
$auth_num = $info -> RemoteFunctionResult ;

// Setup the OtherRemoteFunction() parameters
$at_param = array(
‘amount’ => $irow [ ‘total_price’ ],
‘description’ => $description );

// Call OtherRemoteFunction()
$trans = $soapClient -> __call ( «OtherRemoteFunction» , array( $at_param ));
$trans_result = $trans -> OtherRemoteFunctionResult ;
.
> else <
// Record the transaction error in the database

// Kill the link to Soap
unset( $soapClient );
>
>
>
>

Источник

Оцените статью