I've retrieved data from an XML file like so
$response = simplexml_load_file($url);
print_r displays the following
SimpleXMLElement Object
(
[artist] => SimpleXMLElement Object
(
[#attributes] => Array
(
[type] => Group
[id] => b9fb5447-7f95-4a6a-a157-afed2d7b9f4c
)
[name] => He Is Legend
[sort-name] => He Is Legend
[country] => US
[area] => SimpleXMLElement Object
(
[#attributes] => Array
(
[id] => 489ce91b-6658-3307-9877-795b68554c98
)
[name] => United States
[sort-name] => United States
[iso-3166-1-code-list] => SimpleXMLElement Object
(
[iso-3166-1-code] => US
)
)
)
)
So I can output fields like name and country by
echo $response->artist->name;
echo $response->artist->country;
However I'm stuck when it comes to being able to access data in the attribute arrays.
How can I get the type of group from the first attributes array for example?
Edit
I'm also trying to return the details from a function like so
func getDetails($id) {
$response = simplexml_load_file('http://musicbrainz.org/ws/2/artist/'.$id);
$data = array();
$data['type'] = $response->artist->attributes()->type;
$data['country'] = $response->artist->country;
return $data;
}
print_r(getDetails());
Gives me
MusicBrainz Object
(
)
You can access them using the attributes() method:
echo $response->artist->attributes()->type;
The example #5 in the SimpleXML documentation shows another example.
Related
I'l try to get the movie title and info from the omdb API. This is my code:
<?php
$enter = $_GET["enter"];
$content = file_get_contents("https://www.omdbapi.com/?s=$enter&r=xml");
$xml = simplexml_load_string($content);
if($xml) {
echo "<h2>" .$xml->title. "</h2>";
}
else
{
echo "Nothing found. Add the info manualy";
}
?>
The "enter" value is from the search form with AJAX. He create only an empty h2 tag. How can i get also the data from the API?
Thank you,
Julian
You should familiarize yourself with the structure of the xml to know how to access its elements. print_r(get_object_vars($xml)) will show you a structure like this:
Array
(
[#attributes] => Array
(
[totalResults] => 3651
[response] => True
)
[result] => Array
(
[0] => SimpleXMLElement Object
(
[#attributes] => Array
(
[title] => World War Z
[year] => 2013
[imdbID] => tt0816711
[type] => movie
[poster] => https://images-na.ssl-images-amazon.com/images/M/MV5BMTg0NTgxMjIxOF5BMl5BanBnXkFtZTcwMDM0MDY1OQ##._V1_SX300.jpg
)
)
[1] => SimpleXMLElement Object
(
[#attributes] => Array
(
[title] => Captain America: Civil War
[year] => 2016
[imdbID] => tt3498820
[type] => movie
[poster] => https://images-na.ssl-images-amazon.com/images/M/MV5BMjQ0MTgyNjAxMV5BMl5BanBnXkFtZTgwNjUzMDkyODE#._V1_SX300.jpg
)
)
...
...
...
[9] => SimpleXMLElement Object
(
[#attributes] => Array
(
[title] => War
[year] => 2007
[imdbID] => tt0499556
[type] => movie
[poster] => https://images-na.ssl-images-amazon.com/images/M/MV5BMTgzNTA4MTc3OF5BMl5BanBnXkFtZTcwOTA0ODk0MQ##._V1_SX300.jpg
)
)
)
)
So you receive an array with results where you need to pick from. Alternatively if you know the exact title the API has the t=title option which only returns a single result (see documentation).
So assuming you use the s=title option which returns multiple results, you can use something like this to pick information from the first result:
<?php
$enter = $_GET["enter"];
$content = file_get_contents("https://www.omdbapi.com/?s=$enter&r=xml");
$xml = simplexml_load_string($content);
# show the structure of the xml
# print_r(get_object_vars($xml));
if($xml) {
print "<h2>" .$xml->result[0]['title']. "</h2>";
print "<br>imdbID=" . $xml->result[0]['imdbID'] ;
} else {
echo "Nothing found. Add the info manualy";
}
?>
I have a SOAP Response from a Web Service and have extracted the XML data as a SimpleXMLElement. I have then iterated through this object to extract the various fields I need and save them into an array, which becomes an array of SimpleXMLElement objects.
I am now trying to export this data into a MySQL Database which, according to my research, means turning the array into a String and then using mysql_query("INSERT INTO (whatever) VALUES (whatever)");. I have tried implode and serialize but neither work and I get the error:
Fatal error: Uncaught exception 'Exception' with message 'Serialization of 'SimpleXMLElement' is not allowed'
This is what the array I have created from the SimpleXMLELement looks like:
Array
(
[0] => Array
(
[uid] => SimpleXMLElement Object
(
[0] => WOS:000238186400009
)
[journal] => SimpleXMLElement Object
(
[#attributes] => Array
(
[type] => source
)
)
[publication] => SimpleXMLElement Object
(
[#attributes] => Array
(
[type] => item
)
[0] => Abundance of hedgehogs (Erinaceus europaeus) in relation to the density and distribution of badgers (Meles meles)
)
[year] => 2006
[author1] => SimpleXMLElement Object
(
[0] => Young, RP
)
[address] => SimpleXMLElement Object
(
[0] => Cent Sci Lab, Sand Hutton, Yorks, England
)
[author2] => SimpleXMLElement Object
(
[0] => Davison, J
)
[author3] => SimpleXMLElement Object
(
[0] => Trewby, ID
)
[citations] => SimpleXMLElement Object
(
[#attributes] => Array
(
[local_count] => 15
[coll_id] => WOS
)
)
) ... etc ...
)
Can anyone help me with the method to get this data into my database, please? Do I need to change it into (yet) another format?
You have to iterate through your array to create a new array fulfilled with strings instead of SimpleXMLElement, such as :
<?php
// your array (already built)
$arraySimpleXml = array(
"example1" => new SimpleXMLElement("<test>value</test>"),
"example2" => new SimpleXMLElement("<test>value2</test>")
);
// output array, to store in database
$result = array();
foreach($arraySimpleXml as $key => $simpleXml) {
$result[$key] = $simpleXml->asXML();
}
// gets your result as a string => you can now insert it into mysql
$dbInsertion = serialize($result);
?>
So I worked out how to change the data into a standard array rather than an array of SimpleXMLElements so that I can successfully insert it into a MySQL database.
When iterating the SimpleXMLElement object to extract the data I needed I cast the type as String so that now my array has the format (as opposed to above):
Array
(
[0] => Array
(
[uid] => WOS:000238186400009
[journal] => JOURNAL OF ZOOLOGY
[publication] => Abundance of hedgehogs (Erinaceus europaeus) in relation to the density and distribution of badgers (Meles meles)
[year] => 2006
[author1] => Young, RP
[address] => Cent Sci Lab, Sand Hutton, Yorks, England
[author2] => Davison, J
[author3] => Trewby, ID
[citations] => 15
)
)
Thought I'd post this in case anyone has a similar problem in future. To do this, when iterating the data instead of:
$uid = $record->UID;
I did:
$uid = (string)$record->UID;
For each of the data fields I required. This ensures the data is stored as a String and so removes the SimpleXMLElement format.
I need to pass multiple NameValueLists via SOAP, but I have no idea how to include their data.
This is how it should look like:
<Variations>
<VariationSpecificsSet>
<NameValueList>
<Name>Size</Name>
<Value>XL</Value>
</NameValueList>
<NameValueList>
<Name>Color</Name>
<Value>Black</Value>
</NameValueList>
</VariationSpecificsSet>
</Variations>
Part of my PHP code:
$params->Item->Variations = new ArrayObject();
$params->Item->Variations->VariationSpecificsSet = new ArrayObject();
$params->Item->Variations->VariationSpecificsSet->NameValueList = new ArrayObject();
$list = new ArrayObject();
$list->name = 'title';
$list->value = "value";
$arr[0] = $list;
$arr[1] = $list;
$params->Item->Variations->VariationSpecificsSet->NameValueList = $arr;
$ebay->ebayCall( "VerifyAddFixedPriceItem", $params );
Debug output of $params:
[Variations] => ArrayObject Object
(
[VariationSpecificsSet] => ArrayObject Object
(
[NameValueList] => Array
(
[0] => ArrayObject Object
(
[name] => title
[value] => value
[storage:ArrayObject:private] => Array
(
)
)
[1] => ArrayObject Object
(
[name] => title
[value] => value
[storage:ArrayObject:private] => Array
(
)
)
[2] => ArrayObject Object
(
[name] => title
[value] => value
[storage:ArrayObject:private] => Array
(
)
)
)
[storage:ArrayObject:private] => Array
(
)
)
[storage:ArrayObject:private] => Array
(
)
)
The resulting request: No names, neither values in the NameValueLists
<ns1:Variations>
<ns1:VariationSpecificsSet>
<ns1:NameValueList/>
<ns1:NameValueList/>
<ns1:NameValueList/>
</ns1:VariationSpecificsSet>
</ns1:Variations>
How do I put the data correctly in the NameValueLists? The debug output seems good to me, but it wont show up in the XML. I can't be the first one..?
Edit: I found a question on SO that describes exactly my problem:
Php soap client multiple node
I tried this approach before asking here, but it still dont work for me. I'm guessing, it has something to do with the eBay wsdl, but I cant figure out what exactly
Missing capital Letters at $list->name and $list->value is the answer. hope that helps anyone else sometime. grrr
Data returned over SOAP is returned as objects within an array as shown below.
Array (
[LastPage] => true
[ListOfContact] => stdClass Object (
[Contact] => stdClass Object (
[ContactId] => contactID
[Description] =>
[ContactEmail] => emailAddress
)
)
)
How do i ensure that data is returned as an array only without objects? I am using the SoapClient with the NO WSDL option.
$objectArray = YOUR_OBJECT;
foreach ($objectArray['ListOfContact'] AS $contactArray)
{
$email = $contactArray['ContactEmail'];
etc...
}
Simple example, but should get you on your way!
I want to display the Itinerary details from developer.ean.com API. By passing the customer's Itinerary ID and Email ID I got the details of reservation.
The result is comming in json format so I decoded it and creating array by using :
$array=json_decode($result);
The problem is whatever the result comming from API contain problem like :
For some records it providing array like this:
[Itinerary] => stdClass Object
(
[HotelConfirmation] => Array
(
[0] => stdClass Object
(
[supplierId] => 13
[chainCode] => EP
[arrivalDate] => 07/24/2012
[departureDate] => 07/26/2012
)
[Hotel] => Array
(
[0] => stdClass Object
(
[hotelId] => 394808
[statusCode] => A
[name] => Barkston Youth Hostel
)
)
)
)
In this case the HotelConfirmation and Hotel is Array which contain [0] as object
and for some records it providing array like this:
[Itinerary] => stdClass Object
(
[HotelConfirmation] => stdClass Object
(
[supplierId] => 13
[chainCode] => EP
[arrivalDate] => 07/24/2012
[departureDate] => 07/26/2012
)
[Hotel] => stdClass Object
(
[hotelId] => 394808
[statusCode] => A
[name] => Barkston Youth Hostel
)
)
and In this case the HotelConfirmation and Hotel is itself an object
I providing only few data here actually its big array and I want to provide list of it. But the array containing ambiguity like this. How can I handle this issue. Is there any solution.
Thanks in advance.
Pass true as the second argument to json_decode. This will create an array instead of stdClass
$array=json_decode($result, true);
you can normalize the input like so:
// get objects as arrays
$array = json_decode($result, true);
// remove the sub-level [0], when necessary
foreach ($array as $key => $value) {
if (is_array($value[0])) {
$array[$key] = $value[0];
}
}
Then the result always looks the same:
[Itinerary] => Array
(
[HotelConfirmation] => Array
(
[supplierId] => 13
[chainCode] => EP
[arrivalDate] => 07/24/2012
[departureDate] => 07/26/2012
)
[Hotel] => Array
(
[hotelId] => 394808
[statusCode] => A
[name] => Barkston Youth Hostel
)
)
First do this:
$array = json_decode($result, true);
Which will convert objects into associative arrays
And do adjustment like this:
if (isset($array['HotelItineraryResponse']['Itinerary']['HotelConfirmation'][0])) {
$array['HotelItineraryResponse']['Itinerary']['HotelConfirmation'] = $array['HotelItineraryResponse']['Itinerary']['HotelConfirmation'][0];
}
It will definitly work.
You can use is_array() to check for it:
if (is_array($hotel)) {
$hotel = $hotel[0];
}
just change to this:
$array=json_decode($result,TRUE);
and handle arrays always?
Looks like you may have to account for both possibilities in your model... Checking to see if the hotel node contains and array or an obj and operating accordingly.
you can type case the object inside of an array.
$array = json_decode($result);
$array = (array)$array
or alternatively you can pass true as the second argument in your json_decode();
according to php documentation
When TRUE, returned objects will be converted into associative arrays.
$array = json_decode($result, true);
Check for object or array:
if( is_object($Itinerary -> HotelConfirmation)) {
// do one thing or nothing
} elseif( is_array($Itinerary -> HotelConfirmation)) {
$Itinerary -> HotelConfirmation = array_shift( $Itinerary -> HotelConfirmation );
}