SOAP XML to PHP Array - php

I'm using $data = file_get_contents('php://input'); when a service is posting xml data to my url. It's giving me an xml string, but I can't figure out how to turn it into a php array. I've tried every solution I can find here on Stack, and it always gives me an empty array. Here's the 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:Header>
<Authentication xmlns="urn:www.blank.com:blank:services:2:0:wsdl">
<username></username>
<password></password>
</Authentication>
</soap:Header>
<soap:Body>
<TransferDataString xmlns="urn:www.blank.com:blank:services:2:0:wsdl">
<data>
<?xml version="1.0"?>
<AssessmentResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://ns.hr-xml.org/2007-04-15">
<ReceiptId idOwner="Blank">
<IdValue name="ReceiptID">2461fg453f99-ea45dsg55-448464-85fgd80-e45fg77e5568b7f1</IdValue>
<IdValue name="bID">1422255467627</IdValue>
</ReceiptId>
<ClientOrderId idOwner="BlankPartner" />
<Results>
<Profile>Blank Credits</Profile>
<SupportingMaterials>
<Description>No Forms Needed</Description>
</SupportingMaterials>
<OverallResult>
<Description>Initial Eligibility</Description>
<Score type="PotentialBlank1Eligibility">0</Score>
<Score type="PotentialBlank2Eligibility">0</Score>
</OverallResult>
<DetailResult>
<Score type="Eligibility">0</Score>
</DetailResult>
</Results>
<AssessmentStatus>
<Status>Completed</Status>
<Details>No Errors</Details>
<StatusDate>2017-12-20T14:31:04.287072-05:00</StatusDate>
</AssessmentStatus>
</AssessmentResult>
</data>
</TransferDataString>
</soap:Body>
</soap:Envelope>
I've replaced some words with "blank" for obscurity.
I've tried the recursive xml2array() functions floating about (here, for instance). Returns empty array.
I've tried:
$xml = simplexml_load_string($string, "SimpleXMLElement", LIBXML_NOCDATA);
$array = json_decode(json_encode((array)$xml), TRUE);
Empty array.
What am I missing?
UPDATE
I am now getting this string:
<?xml version="1.0"?>
<AssessmentResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://ns.hr-xml.org/2007-04-15">
<ReceiptId idOwner="Blank">
<IdValue name="ReceiptID">2461fg453f99-ea45dsg55-448464-85fgd80-e45fg77e5568b7f1</IdValue>
<IdValue name="bID">1422255467627</IdValue>
</ReceiptId>
<ClientOrderId idOwner="BlankPartner" />
<Results>
<Profile>Blank Credits</Profile>
<SupportingMaterials>
<Description>No Forms Needed</Description>
</SupportingMaterials>
<OverallResult>
<Description>Initial Eligibility</Description>
<Score type="PotentialBlank1Eligibility">0</Score>
<Score type="PotentialBlank2Eligibility">0</Score>
</OverallResult>
<DetailResult>
<Score type="Eligibility">0</Score>
</DetailResult>
</Results>
<AssessmentStatus>
<Status>Completed</Status>
<Details>No Errors</Details>
<StatusDate>2017-12-20T14:31:04.287072-05:00</StatusDate>
</AssessmentStatus>
</AssessmentResult>
from this method:
$response = preg_replace("/(<\/?)(\w+):([^>]*>)/", "$1$2$3", $string);
$xml = new SimpleXMLElement($response);
$body = $xml->xpath('//soapBody')[0];
$array = json_decode(json_encode((array)$body), TRUE);
$data = $array['TransferDataString']['data'];
var_dump($data);
But I cannot figure out how to convert that string to a PHP array.

To access the inner data elements...
$xml = simplexml_load_string($data);
$xml->registerXPathNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
$data = $xml->xpath("//soap:Body");
$innerData = (string)$data[0]->TransferDataString->children("urn:www.blank.com:blank:services:2:0:wsdl")->data;
// Convert data to array
$xml2 = simplexml_load_string(trim($innerData));
$array = json_decode(json_encode($xml2), true);
print_r($array);
You can then process the data either as XML, or convert it to an array.
The first part extracts the soap:Body and then it manipulates that to get at the final inner content.

Example:
$dom = new DOMDocument("1.0", "UTF-8");
$dom->preserveWhiteSpace = false;
$dom->loadXml($source);
$xpath = new DOMXPath($dom);
$xpath->registerNamespace("xsd", "http://www.w3.org/2001/XMLSchema");
$xpath->registerNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
$xpath->registerNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
$xpath->registerNamespace("xmlns", "urn:www.blank.com:blank:services:2:0:wsdl");
// Read the data element
$data = $xpath->query('//soap:Body/xmlns:TransferDataString/xmlns:data')->item(0)->nodeValue;
$data = trim($data);
echo $data;

Related

Get value from json response with SOAP request

After successfully getting a response from a SOAP request in JSON format, I cannot extract one property out of it.
Beholde the response I got from postman.
<?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>
<AutenticacionResponse xmlns="https://figs.software/">
<AutenticacionResult xsi:type="xsd:string">{"CodRespuesta":"00","Respuesta":"bd026f95-61cf-4947-80df-bf519d544995","URL":null,"NCF":null}</AutenticacionResult>
</AutenticacionResponse>
</soap:Body>
</soap:Envelope>
My goad is to get the token of the Respuesta property.
I'm using curl of PHP to establish the connection:
I try to convert the response I got into an array like this:
$response = preg_replace("/(<\/?)(\w+):([^>]*>)/", "$1$2$3", $response);
$xml = new SimpleXMLElement($response);
$body = $xml->xpath('//soapBody ')[0];
$array = json_decode(json_encode((array)$body), TRUE);
echo $array['AutenticacionResponse']['AutenticacionResult'];
echo gettype($array);
I have this result:
{"CodRespuesta":"00","Respuesta":"d5810796-9563-4423-aff3-089d61e170b6","URL":null,"NCF":null}
array
How can I get the value of Respuesta ?
Without touching your code I get the answer by just doing
$json = json_decode($array['AutenticacionResponse']['AutenticacionResult'], true);
echo $json['Respuesta'];
And I would have done like this
<?php
$response = <<<XML
<?xml version="1.0"?>
<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>
<AutenticacionResponse xmlns="https://figs.software/">
<AutenticacionResult xsi:type="xsd:string">{"CodRespuesta":"00","Respuesta":"bd026f95-61cf-4947-80df-bf519d544995","URL":null,"NCF":null}</AutenticacionResult>
</AutenticacionResponse>
</soap:Body>
</soap:Envelope>
XML;
$response = preg_replace("/(<\/?)(\w+):([^>]*>)/", "$1$2$3", $response);
$xml = new SimpleXMLElement($response);
$json = json_decode($xml->soapBody->AutenticacionResponse->AutenticacionResult, true);
echo $json['Respuesta'];

Extract value from xml tag

I´m trying to extract the RecordID = "1014276" from a tag
I tried with :
$result = curl_exec($ch);
curl_close($ch);
$xml2 = simplexml_load_string($result);
echo $latitude = (string) $xml2['RecordID'];
This is the XML response:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<ns1:createDataResponse xmlns:ns1="http://3e.pl/ADInterface">
<StandardResponse RecordID="1014276" xmlns="http://3e.pl/ADInterface"/>
</ns1:createDataResponse>
</soap:Body>
</soap:Envelope>
This involves a bit more than just accessing the attribute, first you have to select the correct element. Using XPath is the most comment way in this sort of structure.
As this has a default namespace defined for the data, you will need to register this with the SimpleXMLElement first (using $xml2->registerXPathNamespace("ns1","http://3e.pl/ADInterface");.
You can then find the element using the XPAth expression //ns1:StandardResponse. As the xpath() method returns a list of found elements, use [0] to just extract the first match. You should then be able to extract the attribute as in your code using the resultant element...
$xml2 = simplexml_load_string($result);
$xml2->registerXPathNamespace("ns1","http://3e.pl/ADInterface");
$response = $xml2->xpath("//ns1:StandardResponse")[0];
echo (string) $response['RecordID'];
You can apporach this as
$xml = '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<ns1:createDataResponse xmlns:ns1="http://3e.pl/ADInterface">
<StandardResponse RecordID="1014276" xmlns="http://3e.pl/ADInterface"/>
</ns1:createDataResponse>
</soap:Body>
</soap:Envelope>';
$p = xml_parser_create();
xml_parse_into_struct($p, $xml, $values, $index);
xml_parser_free($p);
echo $values[3]['attributes']['RECORDID'];

Parsing XML in PHP with SimpleXML

I am trying to parse the below XML , i have tryed loads of different solutions, i have provided an example of what i have tryed. I have read the SimpleXML documents and i still cant get this right. In the Example below all im trying to do is Echo out a line in the XML.
<?php
$xmlstr = '
<?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>
<SubmitLeadResponse xmlns="https://test.com/">
<SubmitLeadResult>
<Result>C</Result>
<RedirectURL>https://testred.com</RedirectURL>
<ApplicantID>123</ApplicantID>
<ConfirmedPrice>0</ConfirmedPrice>
<PotentialPrice>0</PotentialPrice>
</SubmitLeadResult>
</SubmitLeadResponse>
</soap:Body>
</soap:Envelope>'
;
?>
<?php
$SubmitLeadResponse = new SimpleXMLElement($xmlstr);
echo $SubmitLeadResponse->SubmitLeadResult[0]->RedirectURL;
?>
You can try below code for SimpleXML
<?php
$xml ='<?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>
<SubmitLeadResponse xmlns="https://test.com/">
<SubmitLeadResult>
<Result>C</Result>
<RedirectURL>https://testred.com</RedirectURL>
<ApplicantID>123</ApplicantID>
<ConfirmedPrice>0</ConfirmedPrice>
<PotentialPrice>0</PotentialPrice>
</SubmitLeadResult>
</SubmitLeadResponse>
</soap:Body>
</soap:Envelope>';
$get_xml = str_ireplace(['SOAP-ENV:', 'SOAP:'], '', $xml);
$xml = simplexml_load_string($get_xml);
print"<pre>";
print_r((string)$xml->Body->SubmitLeadResponse->SubmitLeadResult->RedirectURL);
echo "<br /><br /><br />";
print_r($xml);
?>
I've changed your code a bit. Here's a working sample to get the RedirectURL:
<?php
$xmlstr = '<?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>
<SubmitLeadResponse xmlns="https://test.com/">
<SubmitLeadResult>
<Result>C</Result>
<RedirectURL>https://testred.com</RedirectURL>
<ApplicantID>123</ApplicantID>
<ConfirmedPrice>0</ConfirmedPrice>
<PotentialPrice>0</PotentialPrice>
</SubmitLeadResult>
</SubmitLeadResponse>
</soap:Body>
</soap:Envelope>';
$doc = new DOMDocument();
$doc->loadXML( $xmlstr );
$RedirectURL = $doc->getElementsByTagName( "RedirectURL" );
$RedirectURL = $LoginResults->item(0)->nodeValue;
var_dump( $RedirectURL );
Sample provided from this source: There are also more informations to reading SOAP-envelopes without a soapclient
Please note that it's good practice to omit the php closing tag and stay in the php-context as long as possible to avoid unexpected outputs (linebreaks).
Your XML contains namespaced elements, so it's a little more complicated to parse. It can be done by passing the namespace values to children() like so:
Codepad demo
$SubmitLeadResponse = new SimpleXMLElement($xmlstr);
echo (string)$SubmitLeadResponse
->children('http://schemas.xmlsoap.org/soap/envelope/')
->Body
->children('https://test.com/')
->SubmitLeadResponse
->SubmitLeadResult
->RedirectURL;
Outputs
https://testred.com
Note: SimpleXML doesn't like new lines before the XML string, so remove the new line, making it:
$xmlstr = '<?xml version="1.0" encoding="utf-8"?>

Convert CURL XML response into Array in PHP

I am trying to convert a XML response via CURL to an array in PHP. I have tried with the below code but not getting expected result array.
With using simplexml_load_string:
$xml = simplexml_load_string($response);
$json = json_encode($xml);
$arr = json_decode($json,true);
print_r($arr);//giving array () empty
With using SimpleXMLElement:
$xml = new SimpleXMLElement($response);
print_r($xml); //giving SimpleXMLElement Object ( ) empty array
My Curl response :
<?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" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">
<soap:Header>
<OGHeader transactionID="00239870" timeStamp="2009-02-23T01:55:01.4625+05:30" primaryLangID="E" xmlns="http://webservices.micros.com/og/4.3/Core/">
<Origin entityID="WEST" systemType="ORS" />
<Destination entityID="OWS" systemType="WEB" />
</OGHeader>
<wsa:Action>http://webservices</wsa:Action>
<wsa:MessageID>urn:uuid:a9a70c23-3d94-4640-9aac-8ac63694733a</wsa:MessageID>
<wsa:RelatesTo>urn:uuid:eb565d90-b682-45e9-b18d-c03fa7323019</wsa:RelatesTo>
<wsa:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To>
</soap:Header>
<soap:Body>
<CreateBookingResponse xmlns:r="http://webservices" xmlns:hc="http://webservices/" xmlns:c="http://webservices" xmlns="http://webservices">
<Result resultStatusFlag="FAIL">
<c:Text>
<c:TextElement></c:TextElement>
</c:Text>
<c:OperaErrorCode>PRIOR_STAY</c:OperaErrorCode>
</Result>
</CreateBookingResponse>
</soap:Body>
</soap:Envelope>
Try this instead :
<?php
$xml = simplexml_load_string($response);
var_dump($xml->asXML());
Your xml is there as you can see.
Simplexml implements ArrayIterator, therefore you can iterate using foreach or use any of the simpleXmlElement methods to navigate through it (such as children() or xpath()).

Struggling to read a node with SimpleXML

Here is my XML response from an API:
<?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>
<GetCertificateResponse xmlns="http://url.com">
<GetCertificateResult>
<ReturnValue xmlns="">
<Status>Success</Status>
<Message/>
<CertificateNumber/>
<URL/>
</ReturnValue>
</GetCertificateResult>
</GetCertificateResponse>
</soap:Body>
</soap:Envelope>
How can I reaq the status node? I've tried so many combos:
$getCertificateXMLResponse = simplexml_load_string($getCertificateXMLResponse);
echo $getCertificateXMLResponse->GetCertificateResponse->GetCertificateResult->ReturnValue->Status;
You can also do it with Xpath
$xml = simplexml_load_string($soap, NULL, NULL, "http://schemas.xmlsoap.org/soap/envelope/");
$xml->registerXPathNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
$result = $xml->xpath('//Status');
echo $result[0];
it's... ugly.. but works
$xml = new SimpleXMLElement(file_get_contents('a.xml'),0,false,'');
$namespaces = $xml->getDocNamespaces(true);
$xml->registerXPathNamespace('empty', $namespaces['']);
$xml->registerXPathNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
$status = array_shift($xml->xpath("soap:Body/empty:GetCertificateResponse/empty:GetCertificateResult/ReturnValue/Status"));
echo $status->asXML();
i'm curious to see more elegant solution.
and indeed take a look at things like nusoap.

Categories