php - do something on soap empty response or not found - php

I need to do some search on a WS, I have it working, but I need to be able to know when the soap can not find anything with the word I'm looking.
For example, when I search for KE-5977 I get a response and all the data
<GetChoferesResult xmlns:a="http://schemas.datacontract.org/2004/07/asdf.DTO" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:Choferes>
<a:ChoferesDTO>
<a:dc_patente>KE-5977</a:dc_patente>
<a:dc_patente_habitual>KE-5977</a:dc_patente_habitual>
<a:dc_rut_chofer>10165014-6</a:dc_rut_chofer>
<a:dc_tipo_equipo>4</a:dc_tipo_equipo>
<a:dc_tipo_transportista>E</a:dc_tipo_transportista>
<a:dg_nombre_chofer>JUAN SOTO</a:dg_nombre_chofer>
<a:dg_tipo_de_equipo>CamiĆ³n</a:dg_tipo_de_equipo>
<a:dg_tipo_transportista>Externo (Se llama a transporte ocasionalmente)</a:dg_tipo_transportista>
<a:dn_ano_fabricacion>1988</a:dn_ano_fabricacion>
<a:dq_capacidad_equipo>30.0000</a:dq_capacidad_equipo>
</a:ChoferesDTO>
</a:Choferes>
</GetChoferesResult>
but if I put it wrong like this "KE-7759" I get nothing.
<GetChoferesResult xmlns:a="http://schemas.datacontract.org/2004/07/asdf.DTO" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:Choferes/>
</GetChoferesResult>
</GetChoferesResponse>
</s:Body>
</s:Envelope>
I need to show a message "code not found" when I get an empty response from soap (soap request did not found anything with that code).
Please help me.
Update:
This is taken from SoapUI:
http://i.stack.imgur.com/oy4lc.jpg
In PHP I do it like this:
I ask if $isarray is array just because the response from soap can have multiple responses, to get the values when i get multiple responses i have to ask for "$response->GetChoferesResult->Choferes->ChoferesDTO", if i get only one response, the values are in "$response->GetChoferesResult->Choferes".
$response = $sClient->GetChoferes(array("req"=>array("PatenteHabitual"=>$patente)));
$isarray = $response->GetChoferesResult->Choferes->ChoferesDTO;
$xml = $response->GetChoferesResult->Choferes;
if (is_array($isarray)){
foreach($xml as $chofer){
foreach($chofer as $chofer2){
$rut=$chofer2->dc_rut_chofer;
$nombre=$chofer2->dg_nombre_chofer;
?><option value="<?php echo strtoupper($rut); ?>" selected="selected"><?php echo strtoupper($nombre); ?></option><?php
}
}
}else{
foreach($xml as $chofer){
if($chofer->dc_patente && $chofer->dg_nombre_chofer && $chofer->dc_patente_habitual){
$rut=$chofer->dc_rut_chofer;
$nombre=$chofer->dg_nombre_chofer;
?><option value="<?php echo strtoupper($rut); ?>" selected="selected"><?php echo strtoupper($nombre); ?></option><?php
}else{
?><option value="" selected="selected">Patente no encontrada</option><?php
}
}
}
Also, i would like to know if i can order the responses by a value, in this case by dg_nombre_chofer (by name).
Thanks.

You can use strpos($response, '<a:Choferes/>')
http://php.net/strpos
I use simplexml and convert the object to array using:
function objectsIntoArray($arrObjData, $arrSkipIndices = array()){
$arrData = array();
// if input is object, convert into array
if (is_object($arrObjData)) {
$arrObjData = get_object_vars($arrObjData);
}
if (is_array($arrObjData)) {
foreach ($arrObjData as $index => $value) {
if (is_object($value) || is_array($value)) {
$value = objectsIntoArray($value, $arrSkipIndices); // recursive call
}
if (in_array($index, $arrSkipIndices)) {
continue;
}
$arrData[$index] = $value;
}
}
return $arrData;
}
$process = $response->RetrieveListingDataResult;
$process = utf8_encode($process);
$xml = '<?xml version="1.0" encoding="UTF-8"?>'.$process;
$xmlObj = simplexml_load_string($xml);
$arrXml = objectsIntoArray($xmlObj);

Related

How to loop through two XML files and print result

I've been trying unsuccessfully with PHP to loop through two XML files and print the result to the screen. The aim is to take a country's name and output its regions/states/provinces as the case may be.
The first block of code successfully prints all the countries but the loop through both files gives me a blank screen.
The countries file is in the format:
<row>
<id>6</id>
<name>Andorra</name>
<iso2>AD</iso2>
<phone_code>376</phone_code>
</row>
And the states.xml:
<row>
<id>488</id>
<name>Andorra la Vella</name>
<country_id>6</country_id>
<country_code>AD</country_code>
<state_code>07</state_code>
</row>
so that country_id = id.
This gives a perfect list of countries:
$xml = simplexml_load_file("countries.xml");
$xml1 = simplexml_load_file("states.xml");
foreach($xml->children() as $key => $children) {
print((string)$children->name); echo "<br>";
}
This gives me a blank screen except for the HTML stuff on the page:
$xml = simplexml_load_file("countries.xml");
$xml1 = simplexml_load_file("states.xml");
$s = "Jamaica";
foreach($xml->children() as $child) {
foreach($xml1->children() as $child2){
if ($child->id == $child2->country_id && $child->name == $s) {
print((string)$child2->name);
echo "<br>";
}
}
}
Where have I gone wrong?
Thanks.
I suspect your problem is not casting the name to a string before doing your comparison. But why are you starting the second loop before checking if it's needed? You're looping through every single item in states.xml needlessly.
$countries = simplexml_load_file("countries.xml");
$states = simplexml_load_file("states.xml");
$search = "Jamaica";
foreach($countries->children() as $country) {
if ((string)$country->name !== $search) {
continue;
}
foreach($states->children() as $state) {
if ((string)$country->id === (string)$state->country_id) {
echo (string)$state->name . "<br/>";
}
}
}
Also, note that naming your variables in a descriptive manner makes it much easier to figure out what's going on with code.
You could probably get rid of the loops altogether using an XPath query to match the sibling value. I don't use SimpleXML, but here's what it would look like with DomDocument:
$search = "Jamaica";
$countries = new DomDocument();
$countries->load("countries.xml");
$xpath = new DomXPath($countries);
$country = $xpath->query("//row[name/text() = '$search']/id/text()");
$country_id = $country[0]->nodeValue;
$states = new DomDocument();
$states->load("states.xml");
$xpath = new DomXPath($states);
$states = $xpath->query("//row[country_id/text() = '$country_id']/name/text()");
foreach ($states as $state) {
echo $state->nodeValue . "<br/>";
}

How to get values and atributes of this XML in php?

I have such php code:
$xml = #simplexml_load_file('2.xml', 'SimpleXMLElement',LIBXML_NOCDATA);
print_r($xml);
How to get values of:
DialingNumber,StartTime,AnswerTime ?
foreach ($xml as $show)
{
echo (string)$show['DialedNumber'];
echo (string)$show['AnswerNumber'];
echo (string)$show['WaitDuration'];
}
NOT WORKING ! How to get values of: DialingNumber,StartTime,AnswerTime ?
There are problems with the the XML file itself, which can be 'corrected' with just replacing some of the entities with some dummy data. The second part is to reference the correct path to the data you want to output.
$filename = '2.xml';
$data = file_get_contents($filename);
$data = str_replace(["&rs", "&rc"], "", $data); // Remove entity references
$xml = simplexml_load_string($data);
foreach ($xml->Tablix1->DialedNumber_Collection->DialedNumber->Details_Collection->Details
as $details)
{
echo (string)$details['DialedNumbers'].PHP_EOL;
echo (string)$details['AnswerNumber'].PHP_EOL;
echo (string)$details['WaitDuration'].PHP_EOL;
}
Can you try as below?
foreach ($xml as $show)
{
echo (string)$show[0]['DialedNumber'];
echo (string)$show[0]['AnswerNumber'];
echo (string)$show[0]['WaitDuration'];
}

Finding a value in XML (from a parameter) PHP

I am looking for a way to find the value of a parameter 'duration' from an XML access
Source :
http://gdata.youtube.com/feeds/api/videos/bSCs7NzghSg
I tried something like :
preg_match('#<yt:duration seconds=\'(.*?)\'/>#is',$xml,$resultduration);
$duration = $resultTitre[count($resultduration)-1];
but value return 0
This can be done with SimpleXML. Use the children() method for finding the children and attributes() method for accessing the attributes.
Here's a function for that purpose:
function getDuration($url) {
$xml = simplexml_load_file($url);
$duration = $xml->children('media', true)
->group->children('yt', true)
->duration->attributes('', true)->seconds;
return $duration;
}
Usage:
$url = 'http://gdata.youtube.com/feeds/api/videos/bSCs7NzghSg';
echo getDuration($url); // => 2461
Demo!
$file = 'http://gdata.youtube.com/feeds/api/videos/bSCs7NzghSg';
$xml = simplexml_load_file($file);
$result = $xml->xpath('//yt:duration');
foreach ($result as $node) {
echo (double) $node['seconds'];
echo ' ';
}

Troubleshooting parsing of XML document using PHP SimpleXml

I've used xpath to process XML element before, however I'm struggling to get the syntax right for this particular XML.
I'm trying to parse a guardian API response. Sample response:
<response user-tier="approved" current-page="1" start-index="1" page-size="10" pages="1" total="10" status="ok">
<results>
<tag type="series" web-title="Cycling" section-name="Life and style" id="lifeandstyle/series/cycling" api- url="http://content.guardianapis.com/lifeandstyle/series/cycling" section-id="lifeandstyle" web- url="http://www.guardian.co.uk/lifeandstyle/series/cycling"/>
<tag type="keyword" web-title="Cycling" section-name="Sport" id="sport/cycling" api- url="http://content.guardianapis.com/sport/cycling" section-id="sport" web- url="http://www.guardian.co.uk/sport/cycling"/>
<tag type="keyword" web-title="Cycling" section-name="Life and style" id="lifeandstyle/cycling" api-url="http://content.guardianapis.com/lifeandstyle/cycling" section-id="lifeandstyle" web-url="http://www.guardian.co.uk/lifeandstyle/cycling"/>
<results>
<response>
Here is my first try coding it in PHP (I've connected using cURL):
$news_items = new SimpleXMLElement($result); //loads the result of the cURL into a simpleXML response
$news_items = $guardian_response->xpath('results');
foreach ($news_items as $item) { //for each statement every entry will load the news_item and the web_url for the document
$item_block = "<p class=\"web_title\">";
$item_block = "<p class=\"web_url\">";
}
It doesn't retrieve anything, is there any flaws in my code?
<?php
function getAttribute($object, $attribute) {
foreach($object->attributes() as $a => $b) {
if ($a == $attribute) { $return = $b; }
}
if($return) { return $return; }
}
try {
$xml = simplexml_load_file( "parse.xml" );
/* Pay attention to the XPath, include all parents */
$result = $xml->xpath('/response/results/tag');
while(list( , $node) = each($result)) {
echo getAttribute( $node, "type" );
}
} catch( Exception $e ) {
echo "Exception on line ".$e->getLine()." of file ".$e->getFile()." : ".$e->getMessage()."<br/>";
}
?>

PHP Converting XML to array

I was trying to find a way to convert any xml feed into an associative array, I noticed many other people have looked for the same thing, and there has been many attempts, some of them have failed, I found the following way of doing it, credit goes to
http://gaarf.info/2009/08/13/xml-string-to-php-array/
I slightly changed the code, and here is the outcome.
function xmlNameSpaceToArray(SimpleXmlIterator $xml, $nameSpaces=Null){
$output = Null;
$preparedArray = array();
for($xml->rewind(); $xml->valid(); $xml->next()) {
$key = $xml->key();
if(!isset($preparedArray[$key])) { $preparedArray[$key] = array(); $i=0; }
else $i = count($preparedArray[$key]);
$simple = true;
foreach($xml->current()->attributes() as $k=>$v) {
$preparedArray[$key][$i][$k]=(string)$v;
$simple = false;
}
if($nameSpaces) foreach($nameSpaces as $nid=>$name) {
foreach($xml->current()->attributes($name) as $k=>$v) {
$preparedArray[$key][$i][$nid.':'.$k]=(string)$v;
$simple = false;
}
}
if($xml->hasChildren()) {
if($simple) $preparedArray[$key][$i] = xmlNameSpaceToArray($xml->current(), $nameSpaces);
else $preparedArray[$key][$i]['content'] = xmlNameSpaceToArray($xml->current(), $nameSpaces);
} else {
if($simple) $preparedArray[$key][$i] = strval($xml->current());
else $preparedArray[$key][$i]['content'] = strval($xml->current());
}
$i++;
}
$output = $preparedArray;
return $preparedArray;
}
function xmlToArray($xmlFilePath){
$xml = new SimpleXmlIterator($xmlFilePath , null, true);
$nameSpaces = $xml->getNamespaces(true);
$output = xmlNameSpaceToArray($xml,$nameSpaces);
return $output;
}
$xmlFilePath = 'http://forums.devshed.com/rss/feed-5.xml';
$output = xmlToArray($xmlFilePath);
print_r($output);
What I'm trying to find out now is potential problems this could have, the goal is to make this work for EVERY well structured XML feed, without any php warnings, notices and without losing any data.
Can you find a flaw in this or a feed that doesn't work? It worked for everything I tested it for.
Easiest way to do this is to use the built in functions, then convert to an array.
<?php
$obj = simplexml_load_string($xml); // Parse XML
$array = json_decode(json_encode($obj), true); // Convert to array
?>
This piece of XML seems to break it.
<BackupJob ID="2011-11-09-05-00-00" StartTime="2011-11-09 04:56:51" EndTime="2011-11-09 05:02:01" BackupJobStatus="BS_STOP_SUCCESS" NumOfWarnEntries="0" NumOfErrorEntries="0" NumOfNewFiles="0" TotalNewFilesSize="0" NumOfUpdatedFiles="1" TotalUpdatedFilesSize="8709755" NumOfDeletedFiles="0" TotalDeletedFilesSize="0" NumOfMovedFiles="0" TotalMovedFilesSize="0" NumOfUpdatedPermissionFiles="0" TotalUpdatedPermissionFilesSize="0"></BackupJob>
http://php.net/manual/en/book.simplexml.php
The syntax looks something like this for your example
<aaaa Version="1.0">
<bbb>
<cccc>
<dddd Id="id:pass" />
<eeee name="hearaman" age="24" />
</cccc>
</bbb>
</aaaa>
PHP code
<?php
$xml = new SimpleXMLElement($xmlString);
echo $xml->bbb->cccc->dddd['Id'];
echo $xml->bbb->cccc->eeee['name'];
// or...........
foreach ($xml->bbb->cccc as $element) {
foreach($element as $key => $val) {
echo "{$key}: {$val}";
}
}

Categories