Working with CDATA / Soap / PHP - php

So, I have this xml file:
xml
I use this code to get this xml on php with soap
$response = $clientrepasse->__soapCall("GetSchema", array($paramsrepasse));
$return = $clientrepasse->__getLastResponse()
When I show this $return with my print_r function I got this
return
When I use function var_dump it shows that the $return is a string(40000) positions.
I tried:
$xml = simplexml_load_string($return);
When I print $xml it's empty, I need to transform that string to xml and then to json, or something like that, because I need to work on that xml.
Any help will be appreciated. Thank you and sorry about my english.

Your XML has namespaces. simplexml does not load XMLs into an XML object when it has namespaces. You have to register your namespace to be able to load the XML using simplexml_load_string.
Check the link below:
XML to JSON
XML to JSON
Post XML to get the answer specific to your XML .

You shouldn't need to call __getLastResponse(). It gives you the raw HTTP body as a string, which isn't what you want.
This should be all you need:
$response = $clientrepasse->GetSchema($paramsrepasse);
print_r($response);
You don't need to work with XML. $response will be a PHP object that you can work with straight away.
Note that you also don't need to call __soapCall() directly either.

Related

Getting the correct data from an XML file for a SoapClient request

To have a point of reference, let's use this public WSDL: https://www.dataaccess.com/webservicesserver/NumberConversion.wso?WSDL
Now this thing should accept the following xml:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<NumberToWords xmlns="http://www.dataaccess.com/webservicesserver/">
<ubiNum>500</ubiNum>
</NumberToWords>
</soap:Body>
</soap:Envelope>
And here is the code:
$requestData = simplexml_load_file($file);
//enabling or disabling the following line does not seem to make a difference, but I used it at some point to see that it does load something in there
$requestData->registerXPathNamespace("soap", "http://www.w3.org/2003/05/soap-envelope");
//print_r($requestData->xpath('//soap:Body')); //I was using this to check that the data is actually there, and it is...
$webService = new SoapClient($url);
$result = $webService->NumberToWords($requestData);
print_r($result)
And I'm getting this beautiful response:
stdClass Object
(
[NumberToWordsResult] => zero
)
I think it has something to do with how simpleXML load the data in, but I had no luck figuring out what I should do.
As a side note, if I try just manually setting the data:
$requestData = ["ubiNum"=>500];
it works, but I really want to figure out what is going on with the xml parsing/sending
Also if interested, my commented out print_r's result is the following
Array
(
[0] => SimpleXMLElement Object
(
[NumberToWords] => SimpleXMLElement Object
(
[ubiNum] => 500
)
)
)
If you're using SoapClient, you don't need to also construct the whole XML yourself. Depending on the service, you either need to pass style individual variables, or the contents of the "body".
As you say, you can just run:
$webService = new SoapClient($url);
$result = $webService->NumberToWords(["ubiNum"=>500]);
Underneath, the SoapClient class is generating the rest of the XML for you and sending it as an HTTP request.
If you want to get the data to send out of an XML document, you need to extract just that part, rather than trying to send the whole SOAP envelope inside the parameter. In this example, you need to navigate to the "NumberToWords" element; see this reference question for tips on navigating the XML namespaces but in this example you'd use something like this:
$requestData = simplexml_load_file($file);
$soapBody = $requestData->children('http://schemas.xmlsoap.org/soap/envelope/')->Body;
$numberToWords = $soapBody->children('http://www.dataaccess.com/webservicesserver/')->NumberToWords;
// Or to get the 500 directly:
$ubiNum = (int)$numberToWords->ubiNum;
Alternatively, you can just ignore the SoapClient class, construct the XML yourself, and post it with an HTTP client like Guzzle. Often the only extra step you'll need is to set the correct "SOAPAction" HTTP header.

SimpleXMLElement:difference in Curl and file_get_contents

So guys, there is another question.
I've fetched a webpage via curl and constructed XML document:
.......
$data = curl_exec($ch1);
$xml = new SimpleXMLElement($data);
And it worked correctly.
After I used file_get_contents like this
......
$file1 = file_get_contents('https://meet77842937.adobeconnect.com/api/xml?action=report-my-meetings', false, $context);
$xml = new SimpleXMLElement($file1);
The last code cannot construct XML, though I able to see through var_dump that it receives a page. And I stumbled: I think curl is advanced version of file_get_contents but they must not differ in fetching page. Where are the problems?
The error:Extra content at the end of the document
I don't know how but webpage returns some symbol at the end
With regards

check youtube video is embeddable <yt:noembed> via xml

I have following link http://gdata.youtube.com/feeds/api/videos/tYMYv1zsAxE and it return an xml file in which is located noembed tag in case the video is not embeddable.
i want to create a loop on list of videos to check which is embeddable and which is not.
Based on your clarification, it sounds like you're asking a question about parsing XML. Here's an alternative: get back JSON, and parse that. You can make a request like
http://gdata.youtube.com/feeds/api/videos/tYMYv1zsAxE?v=2&alt=jsonc&prettyprint=true
and then look at the data->accessControl->embed element within the JSON response.
Or, you know, just parse and access the YouTube API XML exactly like you'd parse the XML from any other source. There's nothing magic going on with the YouTube API XML.
$vidID = "tYMYv1zsAxE";
$url="http://gdata.youtube.com/feeds/api/videos/$vidID?v=2&alt=jsonc&prettyprint=true";
$json = file_get_contents($url, true);
$json_output = json_decode($json);
echo $json_output->data->accessControl->embed;
Simple way to check if youtube video is embeddable.
Thanks to #Jeff Posnick

PHP Soap - How to remove xsi:type= from XML tag

I'm sending a SOAP request that looks like:
<SOAP-ENV:Body>
<api:GetOrder xsi:type="SOAP-ENC:Struct">
<api_orderId xsi:type="xsd:int">1234</api_orderId>
</api:GetOrder>
</SOAP-ENV:Body>
But needs to look like this (SoapUI generated):
<soapenv:Body>
<api:GetOrder>
<api:orderId>1234</api:orderId>
</api:GetOrder>
</soapenv:Body>
My PHP Code:
$client = $this->getConnection();
$soap_options = array('soapaction' => $config->getValue('soapaction_url') . 'GetOrder');
$obj = new stdClass();
$obj->api_orderId = 59698;
$results = $client->__soapCall('GetOrder', array(new SoapParam($obj, "api:GetOrder")), $soap_options);
2 questions really:
1) How can I remove the "xsi:type" from the request? (If I add xsi:type in to my SoapUI request, I get back a "400 Bad Request"
2) Instead of "api_orderId" I need to send "api:orderId", but I can't name an object with a colon, so do I have to pass the name and value as an array somehow?
Appreciate any help, thank you.
EDIT:
I wasn't able to figure out any other way to send these requests and I essentially ended up doing as Mr.K suggested below.
I wrote a custom class to extend SoapClient. Then overrode the __doRequest method to send my own custom SOAP request.
The only downside is that SOAP no longer returns me an array of objects, so I also had to parse the XML of the SOAP response.
Also I suspect that the performance of doing it this way is a bit slower, but I didn't notice it.
Try with Simple XML parsing, and create the new request as you like.
Read the tag values from Original request, assign those values to a new XML object using parsing. You can create string of XML message and load it as an XML object in PHP.
Just like get it from there, put it inside this..and Send!..

Parse XML received from a GET request

As a part of a school project, i am making a call of the school's api.
Method: GET
Response Format: Xml
Now i use curl to make the web request.
$ch=curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
$data=curl_exec($ch);
curl_close($ch);
Now how do i parse the xml output to get the data i want?
Hope the question is clear
This depends on the exact nature of the content and, moreover, its structure.
The basics are to use DOMDocument (or, alternatively, simplexml, which I dislike as an API) to parse the document, then to use DOM traversal or XPath to find the content you want.
An example might look like this:
$dom = new DOMDocument;
$dom->loadXML($data); // data from cURL request
$xpath = new DOMXPath($dom);
$names = $xpath->query('//student/name'); // find all name elements that are direct children of student elements
foreach ($names as $name) {
echo $name->nodeValue;
}
The exact code you want depends on the structure of the XML and what content you want to get out of it.
Use SimpleXML:
$xml = simplexml_load_string($data);
Take a look at SimpleXML, DOMDocument, XMLParser and XPath. I usually prefer SimpleXML, but as many people, as many opinions...
You will find lots of examples in the documentation to this PHP classes.
assuming that $data contains xml you can use SimpleXML to parse it

Categories