Specific field from XML into PHP - php

I am pretty new to XML sheets in combination with PHP. I am trying to pull data from an XML file that is being returned to me via SOAP call.
My XML is being returned as this.
commented out some of the details
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:partner.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<loginResponse>
<result>
<metadataServerUrl>https://...-api.salesforce.com/service...</metadataServerUrl>
<passwordExpired>false</passwordExpired>
<sandbox>false</sandbox>
<serverUrl>https://...--api.salesforce.com/services/Soap/u/21.0/0...</serverUrl>
<sessionId>....</sessionId>
<userId>....</userId>
<userInfo>
<accessibilityMode>false</accessibilityMode>
<currencySymbol>€</currencySymbol> ... </userInfo>
</result>
</loginResponse>
</soapenv:Body>
</soapenv:Envelope>
So I am trying to pull out of this the sessionID
// UP HERE SOAP CALL --- return data
.......
} else {
$response = curl_exec($soap_do);
curl_close($soap_do);
// print($response); <-- see result XML
// grabbing the sessionid
$xmlresponse = new SimpleXMLElement($response);
$test = $xmlresponse->result->sessionId['value'];
echo $test;
}
This returns blank, but when I start adding the LoginResponse and the Soapenv (body and envelope), i get an error about that I am trying to get a propperty of non-object. I am not sure what I am doing wrong here.

With SimpleXML you can use SimpleXMLElement::children to find children by an XML namespace (here soapenv).
For your case it would something like
$xmlresponse = new SimpleXMLElement($response);
$response = $xmlresponse->children('soapenv', true)->Body->children('', true)->loginResponse->result->sessionId;
var_dump($response);
Which results in
object(SimpleXMLElement)#4 (1) {
[0]=>
string(4) "...."
}

I want to say that you should use SoapClient(http://php.net/manual/tr/class.soapclient.php) for Soap Calls but if you don't want to use it, here is how you can parse this XML :
$xmlresponse = new SimpleXMLElement(str_ireplace([':Envelope', ':Body'], '', $response));
$test = $xmlresponse->soapenv->loginResponse->result->sessionId['value'];
echo $test;

Related

How to convert Soap xml response return by the Amadeus Flight Search API to json

I would like to convert the SOAP XML response into the JSON format. Can anybody please help!
I got below SOAP XML in $response
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:awsse="http://xml.amadeus.com/2010/06/Session_v3" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<soapenv:Header>
<wsa:To>http://www.w3.org/2005/08/addressing/anonymous</wsa:To>
<wsa:From>
<wsa:Address>https://nodeD2.test.webservices.amadeus.com/XXXXXXXX</wsa:Address>
</wsa:From>
<wsa:Action>http://webservices.amadeus.com/FMPTBQ_18_1_1A
</wsa:Action>
<wsa:MessageID>urn:uuid:a4844bc6-2e05-e8e4-b589-6f813ecad262</wsa:MessageID>
<wsa:RelatesTo RelationshipType="http://www.w3.org/2005/08/addressing/reply">urn:uuid:ac1c8436-ecaf-4bbb-a9ff-11b466dffe18</wsa:RelatesTo>
<awsse:Session TransactionStatusCode="End"><awsse:SessionId>00896YTRZQPQ</awsse:SessionId><awsse:SequenceNumber>1</awsse:SequenceNumber><awsse:SecurityToken>TRFTGYNBHUYKIOL</awsse:SecurityToken></awsse:Session>
</soapenv:Header>
<soapenv:Body>
<Fare_MasterPricerTravelBoardSearchReply xmlns="http://xml.amadeus.com/FMPTBR_18_1_1A">
<replyStatus><status><advisoryTypeInfo>FQX</advisoryTypeInfo></status></replyStatus>
<conversionRate><conversionRateDetail><currency>USD</currency></conversionRateDetail></conversionRate>
<familyInformation><refNumber>1</refNumber><fareFamilyname>BAGSEAT</fareFamilyname><description>OPTIMA</description><carrier>IB</carrier><services><reference>1</reference><status>CHA</status></services><services><reference>2</reference><status>CHA</status></services><services><reference>3</reference><status>INC</status></services><services><reference>4</reference><status>NOF</status></services><services><reference>5</reference><status>NOF</status></services><services><reference>6</reference><status>NOF</status></services><services><reference>7</reference><status>NOF</status></services></familyInformation>
</Fare_MasterPricerTravelBoardSearchReply>
</soapenv:Body>
</soapenv:Envelope>
I tried this.
$xml = json_decode(json_encode(simplexml_load_string($response)), true);
print '<pre>';
print_r($xml);
print '</pre>';
I got the solution to the problem, working fine
$response = preg_replace("/(<\/?)(\w+):([^>]*>)/", "$1$2$3", $response);
$response = simplexml_load_string($response);
$dataArray = json_decode(json_encode((array)$response), TRUE);
echo '<pre>';print_r($dataArray);echo '</pre>';die(__FILE__.' On this line '.__LINE__);

parse SOAP xml to php

How can I parse a XML response to PHP? I have tried several solutions but nothing works. Here is the XML I get back:
<soapenv:envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:body>
<ns:getrateresponse xmlns:ns="http://services.gts">
<ns:return xmlns:ax25="http://services.gts/xsd" xmlns:ax26="http://model.gts/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax25:RaterResponseAutoQuotes">
<ax25:carriers xsi:type="ax25:RaterResponseCarriersAutoQuotes">
<ax25:accessorials xsi:type="ax25:RaterResponseAccessorial">
<ax25:aramount>12.66</ax25:aramount>
<ax25:accessorialid>22</ax25:accessorialid>
<ax25:accessorialname>Fuel</ax25:accessorialname>
</ax25:accessorials>
<ax25:ar_final_rate>161.66</ax25:ar_final_rate>
<ax25:carrier_id>0000087</ax25:carrier_id>
<ax25:carrier_name>CON-WAY FREIGHT INC</ax25:carrier_name>
<ax25:service_days>04</ax25:service_days>
</ax25:carriers>
<ax25:message>Success</ax25:message>
<ax25:referencenumber>3184877</ax25:referencenumber>
<ax25:success>true</ax25:success>
</ns:return>
</ns:getrateresponse>
</soapenv:body>
Parse:
foreach($xml->ax25:carriers as $carrier) {
$$carrierObject = array(
"rate" => $carrier->ar_final_rate,
);
array_push($carriers, $$carrierObject);
}
All I care about is the each ax25:carriers ax25:ar_final_rate. I also tried
$result = new SimpleXMLElement($response);
but get back
object(SimpleXMLElement)#2 (0) { }
Here we are using DOMDocument for extracting textContent inside these tags <ax25:ar_final_rate>
Try this code snippet here
<?php
ini_set('display_errors', 1);
$string='<soapenv:envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:body>
<ns:getrateresponse xmlns:ns="http://services.gts">
<ns:return xmlns:ax25="http://services.gts/xsd" xmlns:ax26="http://model.gts/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax25:RaterResponseAutoQuotes">
<ax25:carriers xsi:type="ax25:RaterResponseCarriersAutoQuotes">
<ax25:accessorials xsi:type="ax25:RaterResponseAccessorial">
<ax25:aramount>12.66</ax25:aramount>
<ax25:accessorialid>22</ax25:accessorialid>
<ax25:accessorialname>Fuel</ax25:accessorialname>
</ax25:accessorials>
<ax25:ar_final_rate>161.66</ax25:ar_final_rate>
<ax25:carrier_id>0000087</ax25:carrier_id>
<ax25:carrier_name>CON-WAY FREIGHT INC</ax25:carrier_name>
<ax25:service_days>04</ax25:service_days>
</ax25:carriers>
<ax25:message>Success</ax25:message>
<ax25:referencenumber>3184877</ax25:referencenumber>
<ax25:success>true</ax25:success>
</ns:return>
</ns:getrateresponse>
</soapenv:body>
</soapenv:envelope>';
$domDocument = new DOMDocument();
$domDocument->loadXML($string);
$carriers=array();
$results=$domDocument->getElementsByTagNameNS("http://services.gts/xsd", "ar_final_rate");
foreach($results as $result)
{
array_push($carriers, $result->textContent);
}
print_r($carriers);
Output:
Array
(
[0] => 161.66
)

SimpleXMLElement - Trying to get property of non-object

In a response we receive an xml file, then convert to SimpleXMLElement, then access the elements and attributes as needed. However, we are getting "Trying to get property of non-object" when xml is loaded directly from string response vs from saved response.
//This code works
$response = simplexml_load_file( "response.xml" );
var_dump($response);
echo $response->RESPONSE->RESPONSE_DATA->FILE_INFORMATION['Order_Number'];
//Returns
//object(SimpleXMLElement)#153 (4) { ["#attributes"]=> array(1)...the rest of the xml file...
//Order_Number
//This code returns error
$response = simplexml_load_string( $response );
var_dump($response);
echo $response->RESPONSE->RESPONSE_DATA->FILE_INFORMATION['Order_Number'];
//Returns
//object(SimpleXMLElement)#153 (1) { [0]=> string(33864) "" }
//Notice: Trying to get property of non-object in...
What would cause the xml to fail when using simplexml_load_string instead of simplexml_load_file?
Here is a snippet of the xml file:
<?xml version="1.0" encoding="UTF-8"?>
<RESPONSE_GROUP>
<RESPONSE>
<RESPONSE_DATA>
<FILE_INFORMATION Order_Number="19222835">
...
</FILE_INFORMATION>
</RESPONSE_DATA>
</RESPONSE>
</RESPONSE_GROUP>
You've just overlooked a little detail here. It is correct what you say for the first part:
$response = simplexml_load_file( "response.xml" );
This loads the XML document from the file. However when you look at the second part:
$response = simplexml_load_string( $response );
You don't load from string response. $response represents the SimpleXMLElement you've just created from file. The more "correct" example is:
$buffer = file_get_contents( "response.xml" );
$response = simplexml_load_string( $buffer );
You perhaps just were confused due to variable-reuse (taken the same named variable for two different things).
And better as var_dump is to check with $response->asXML() as it will show you the document as XML which shows better what you have (or not).
This works for me:
<?php
$response = '<?xml version="1.0" encoding="UTF-8"?>
<RESPONSE_GROUP>
<RESPONSE>
<RESPONSE_DATA>
<FILE_INFORMATION Order_Number="19222835">
...
</FILE_INFORMATION>
</RESPONSE_DATA>
</RESPONSE>
</RESPONSE_GROUP>';
//This code returns error
$response = simplexml_load_string( $response );
var_dump($response);
echo $response->RESPONSE->RESPONSE_DATA->FILE_INFORMATION['Order_Number'];
?>
Output:
object(SimpleXMLElement)#1 (1) {
["RESPONSE"]=>
object(SimpleXMLElement)#2 (1) {
["RESPONSE_DATA"]=>
object(SimpleXMLElement)#3 (1) {
["FILE_INFORMATION"]=>
string(33) "
...
"
}
}
}
19222835

PHP SOAP is not buildung a correct request

i am trying to build a specific SOAP Request in PHP with the standard SOAP-Class.
That's the Request i want to build in PHP:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.autoscout24.com/webapi/" xmlns:data="http://www.autoscout24.com/webapi/data/">
<soapenv:Header/>
<soapenv:Body>
<web:FindArticles>
<web:request>
<data:client_id>1234</data:client_id>
<data:culture_id>de-DE</data:culture_id>
<data:profile_id>CPCMS_DE</data:profile_id>
<data:revision>3</data:revision>
<data:vehicle_search_parameters>
<data:address>
<data:countries>
<data:country_id>D</data:country_id>
</data:countries>
</data:address>
<data:dealer_id>2141356852</data:dealer_id>
</data:vehicle_search_parameters>
</web:request>
</web:FindArticles>
</soapenv:Body>
</soapenv:Envelope>
I tried to figure out how it works:
try {
$result = $client->FindArticles(
array( new SoapParam((string)"de-DE", "culture_id") )
);
} catch (SoapFault $exc) {
var_dump($client->__getLastRequest());
echo $exc->getMessage();
}
This PHP Call echoes the following SOAP-Envelope:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.autoscout24.com/webapi/"><SOAP-ENV:Body>
<ns1:FindArticles/>
</SOAP-ENV:Body></SOAP-ENV:Envelope>
As you can see, PHP ignores my SOAPParameters.
Why is that and how to fix it?
Thanks in Advance!
Florian
I haven't used soapparam yet, I always do it this way:
$arrCallParams = array();
$arrCallParams['culture_id']='de-DE';
$result= $client->FindArticles($arrCallParams);

SimpleXML Returns 0 Element

I'm taking my response from a Soap Request, and passing it into a new SimpleXML construct.
$response = $this->client->$method(array("Request" => $this->params));
$response_string = $this->client->__getLastResponse();
$this->response = new Classes_Result(new SimpleXMLElement($result));
If I echo the $response_string, it outputs a proper xml string. Here is a snippet as it's quite long.
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body><GetClassesResponse xmlns="http://clients.mindbodyonline.com/api/0_5">
<GetClassesResult>
<Status>Success</Status>
<XMLDetail>Full</XMLDetail>
<ResultCount>6</ResultCount>
<CurrentPageIndex>0</CurrentPageIndex>
<TotalPageCount>1</TotalPageCount>
<Classes>
<Class>
<ClassScheduleID>4</ClassScheduleID>
<Location>
<SiteID>20853</SiteID>
....</soap:Envelope>
Hoever, when I try to work with this object, I get errors or if I dump the object it outputs:
object(SimpleXMLElement)#51 (0)
Any ideas why this might be happening?
You are not actually using $response_string, and you have not set $result anywhere, which you have passed to new SimpleXMLElement($result).
Perhaps you intend to build a SimpleXML object with the $response_string string via simplexml_load_string()?
$response = $this->client->$method(array("Request" => $this->params));
$response_string = $this->client->__getLastResponse();
// Load XML via simplexml_load_string()
$this->response = new Classes_Result(simplexml_load_string($response_string));
// Or if you do expect a SimpleXMLElement(), pass in the string
$this->response = new Classes_Result(new SimpleXMLElement($response_string));
The <soap:Body> element of your SOAP response is namespaced with (soap). To loop over it with SimpleXML, you must provide the correct namespace:
// After creating new SimpleXMLElement()
var_dump($this->response->children("http://schemas.xmlsoap.org/soap/envelope/"));
// class SimpleXMLElement#2 (1) {
// public $Body =>
// class SimpleXMLElement#4 (0) {
// }
// }
To loop over the body:
foreach ($this->response->children("http://schemas.xmlsoap.org/soap/envelope/") as $b) {
$body_nodes = $b->children();
// Get somethign specific
foreach ($body_nodes->GetClassesResponse->GetClassesResult as $bn) {
echo $bn->ResultCount . ", ";
echo $bn->TotalPageCount;
}
}
// 6, 1

Categories