json_encode creates useless zero keys - php

I am writing an API to output an adress book, which I get the output as a XML. The output is JSON.
What's my problem?
I looping through the entries, which I get from an XML file and store it in an array. That means, that every entry includes an contact:
$xml = new SimpleXMLElement("adressbook.xml"); // <-- Only an example URL
$totalResults = $xml->children('openSearch', true)->totalResults;
$contacts=array();
foreach($xml->entry as $contact){
$tel = $contact->children('tel', true);
$entry = array(
"type"=>$tel->type,
"name"=>$tel->name,
"firstname"=>$tel->firstname,
"street"=>$tel->street,
"streetno"=>$tel->streetno,
"zip"=>$tel->zip,
"city"=>$tel->city,
"canton"=>$tel->canton,
"country"=>$tel->country,
"phone"=>$tel->phone
);
array_push($contacts,$entry);
}
After this I want to echo the array in json. I do this with json_encode.
But there is the problem. Instead of giving the results directly, it shows me following results:
The zero's which are red marked should not exist.
What I tried
I researched in the internet and found in the docs and in a few posts on Stack Overflow the JSON_FORCE_OBJECT attribute for json_encode.
http://php.net/manual/en/function.json-encode.php
Now my function looks like this:
echo json_encode($contacts,JSON_FORCE_OBJECT);
But I still get the zero's.
Here is also a small example of my XML:
<entry>
<updated>2017-04-11T02:00:00Z</updated>
<published>2017-04-11T02:00:00Z</published>
<title type="text">Mustermann, Max</title>
<tel:type>Person</tel:type>
<tel:name>Mustermann</tel:name>
<tel:firstname>Max</tel:firstname>
<tel:street>Musterstrasse</tel:street>
<tel:streetno>17</tel:streetno>
<tel:zip>8000</tel:zip>
<tel:city>Zürich</tel:city>
<tel:canton>ZH</tel:canton>
<tel:country>ch</tel:country>
<tel:phone>+123456789</tel:phone>
</entry>
What is going wrong?
UPDATE:
Here is the var_dump:
object(SimpleXMLElement)#6 (15) { ["type"]=> string(12) "Organisation" ["name"]=> string(28) "*******" ["occupation"]=> string(57) "*******" ["street"]=> string(11) "Musterstrasse" ["streetno"]=> string(1) "17" ["zip"]=> string(4) "8000" ["city"]=> string(5) "Zürich" ["canton"]=> string(2) "ZH" ["country"]=> string(2) "ch" ["phone"]=> string(12) "+123456789" }

One approach is to use strval to convert each object to a string
$xml = new SimpleXMLElement("adressbook.xml"); // <-- Only an example URL
$totalResults = $xml->children('openSearch', true)->totalResults;
$contacts=array();
foreach($xml->entry as $contact){
$tel = $contact->children('tel', true);
$entry = array(
"type"=>strval($tel->type),
"name"=>strval($tel->name),
"firstname"=>strval($tel->firstname,)
"street"=>strval($tel->street),
"streetno"=>strval($tel->streetno),
"zip"=>strval($tel->zip),
"city"=>strval($tel->city),
"canton"=>strval($tel->canton),
"country"=>strval($tel->country),
"phone"=>strval($tel->phone)
);
array_push($contacts,$entry);
}

Related

Extract Last Data Tag from Last XML element using PHP

I have an XML file which I have used xpath to extract the last Element.
So at the moment this line of code below:
//Get The file from directory
$xml=simplexml_load_file("docs/03-24-2014.xml");
//Get last Element
$last = $xml->xpath("/DocumentElement/Datas[last()]");
Output
array(1) { [0]=> object(SimpleXMLElement)#4 (6) { ["Name"]=> string(12) "COM3-Screen1" ["AdjustMode"]=> string(10) "AutoAdjust" ["Time"]=> string(19) "03-24-2014 11:59:27" ["ScreenBrightnessValues_x0028_0-255_x0029_"]=> string(1) "2" ["AmbientBrightness_x0028_lux_x0029_"]=> string(1) "0" ["BrightnessPercentage"]=> string(2) "0%" } }
Goal
What am trying to achieve is extract the last data tag called "BrightnessPercentage and store it in a string"
I tried echo $last->BrightnessPercentage .; but it didnt work!
Any help you be kindly appreciated
To get that attribute directly from xpath as string, do:
$brightness = (string)$xml->xpath("/DocumentElement/Datas[last()]/#BrightnessPercentage")[0];
requires PHP >= 5.4. If you are on a lower version, do:
$brightness = $xml->xpath("/DocumentElement/Datas[last()]/#BrightnessPercentage");
$brightness = (string)$brightness[0];

How do I convert the following XML data into an array (JSON or otherwise)

Whilst there are plenty of options for converting "normal" XML into an array I'd dearly love to find a way of converting this data into an array that I can process with PHP (it's currently designed to be processed by JQuery)
<?xml version="1.0" encoding="ISO-8859-15"?><root><data><![CDATA[ [{title_id: "284270",
track_id: "1548617",
artist: [[20670, 1, "Matthias Vogt", "matthias-vogt"]],
title: "The Wobble Track",
title_url: "/title/284270/the-wobble-track",
track_url: "/track/1548617/the-wobble-track",
label: [88, "Large Music", "large-music"],
genre: "Deep House",
genre_url: "/genre/13/deep-house",
catnumber: "LAR181",
promo: false,
duration: "5:54",
r_date: "2014-02-17",
price: {hbr: 1.99, wav: 2.74},
bought: false,
image: "http://static.traxsource.com/files/images/271306_large.jpg",
thumb: "http://static.traxsource.com/scripts/image.php/44x44/271306.jpg",
mp3: "http://preview.traxsource.com/files/previews/88/1324290-p.mp3",
waveform: "http://static.traxsource.com/files/wf/1324290-wf.png",
bpm: "120",
keysig: "Bmin"}
] ]]></data></root>
There are about another 99 objects in this xml string so i've only included 1 for simplicity
I want to convert, what appears to be, an array into an JSON or PHP array - thanks :)
Don't. Just use Xpath on the DOM to fetch the parts, in your case the JSON structure in the CDATA section.
The structure is not really JSON but Javascript, the quotes around the property names are missing. Here is a nice regex in a user comment of the PHP Manual that repairs it.
$xml = <<<'XML'
<?xml version="1.0" encoding="ISO-8859-15"?><root><data><![CDATA[ [{title_id: "284270",
track_id: "1548617",
artist: [[20670, 1, "Matthias Vogt", "matthias-vogt"]],
title: "The Wobble Track",
title_url: "/title/284270/the-wobble-track",
track_url: "/track/1548617/the-wobble-track",
label: [88, "Large Music", "large-music"],
genre: "Deep House",
genre_url: "/genre/13/deep-house",
catnumber: "LAR181",
promo: false,
duration: "5:54",
r_date: "2014-02-17",
price: {hbr: 1.99, wav: 2.74},
bought: false,
image: "http://static.traxsource.com/files/images/271306_large.jpg",
thumb: "http://static.traxsource.com/scripts/image.php/44x44/271306.jpg",
mp3: "http://preview.traxsource.com/files/previews/88/1324290-p.mp3",
waveform: "http://static.traxsource.com/files/wf/1324290-wf.png",
bpm: "120",
keysig: "Bmin"}
] ]]></data></root>
XML;
function javascript_decode($json, $assoc = FALSE){
$json = str_replace(array("\n","\r"),"",$json);
$json = preg_replace('(([{,]+)(\s*)([^"]+?)\s*:)','$1"$3":',$json);
return json_decode($json,$assoc);
}
$dom = new DOMDocument();
//$dom->load($xmlFile);
$dom->loadXml($xml);
$xpath = new DOMXpath($dom);
$json = javascript_decode($xpath->evaluate('string(/root/data)'));
var_dump($json);
Output https://eval.in/105256
array(1) {
[0]=>
object(stdClass)#3 (21) {
["title_id"]=>
string(6) "284270"
["track_id"]=>
string(7) "1548617"
["artist"]=>
array(1) {
[0]=>
array(4) {
[0]=>
int(20670)
[1]=>
int(1)
[2]=>
string(13) "Matthias Vogt"
[3]=>
string(13) "matthias-vogt"
}
}
["title"]=>
string(16) "The Wobble Track"
["title_url"]=>
string(30) "/title/284270/the-wobble-track"
["track_url"]=>
string(31) "/track/1548617/the-wobble-track"
["label"]=>
array(3) {
[0]=>
int(88)
[1]=>
string(11) "Large Music"
[2]=>
string(11) "large-music"
}
["genre"]=>
string(10) "Deep House"
["genre_url"]=>
string(20) "/genre/13/deep-house"
["catnumber"]=>
string(6) "LAR181"
["promo"]=>
bool(false)
["duration"]=>
string(4) "5:54"
["r_date"]=>
string(10) "2014-02-17"
["price"]=>
object(stdClass)#4 (2) {
["hbr"]=>
float(1.99)
["wav"]=>
float(2.74)
}
["bought"]=>
bool(false)
["image"]=>
string(58) "http://static.traxsource.com/files/images/271306_large.jpg"
["thumb"]=>
string(63) "http://static.traxsource.com/scripts/image.php/44x44/271306.jpg"
["mp3"]=>
string(61) "http://preview.traxsource.com/files/previews/88/1324290-p.mp3"
["waveform"]=>
string(52) "http://static.traxsource.com/files/wf/1324290-wf.png"
["bpm"]=>
string(3) "120"
["keysig"]=>
string(4) "Bmin"
}
}
Given that I couldn't solve the issue with any of the solutions I kept digging and did some tests. My solution is not pretty but is certainly functional.
I removed all the XML data and left myself with fairly raw JSON. The issue, in this case, with the JSON data is that the strings are not wrapped in "" so I did an str_replace to fix this and it all worked.
$content= str_replace('','',str_replace("\'","'",$content)));
$keys = array("title_id:",
"track_id:",
"artist:",
"title:",
"title_url:",
"track_url:",
"label:",
"genre:",
"genre_url:",
"catnumber:",
"promo:",
"duration:",
"r_date:",
"price:",
"hbr:",
"wav:",
"bought:",
"false",
"image:",
"thumb:",
"mp3:",
"waveform:",
"bpm:",
"keysig:"
);
$newkeys = array("\"title_id\":",
"\"track_id\":",
"\"artist\":",
"\"title\":",
"\"title_url\":",
"\"track_url\":",
"\"label\":",
"\"genre\":",
"\"genre_url\":",
"\"catnumber\":",
"\"promo\":",
"\"duration\":",
"\"r_date\":",
"\"price\":",
"\"hbr\":",
"\"wav\":",
"\"bought\":",
"\"false\"",
"\"image\":",
"\"thumb\":",
"\"mp3\":",
"\"waveform\":",
"\"bpm\":",
"\"keysig\":"
);
$content= str_replace($keys, $newkeys, $content);
$json = json_decode($content, true);
I was then able to loop through this and process normally.

How to access elements in a JSON decoded associative array PHP

I'm new to php, and I'm wording how to return an associative array of JSON data type? So here's my php code:
$JSON = file_get_contents($url);
// echo the JSON (you can echo this to JavaScript to use it there)
//echo $JSON;
// You can decode it to process it in PHP
$data = json_decode($JSON,true);
var_dump($data);
Here's a snippet of what the data looks like when I dump it to the screen:
array(2) {
["product"] => array(1) {
[0]=> array(7) {
["styles"]=> array(13) {
[0]=> array(7) {
["price"]=> string(6) "$64.95"
["productUrl"]=> string(46) "http://www.zappos.com/product/7515478/color/25"
["percentOff"]=> string(2) "0%"
["styleId"]=> string(7) "1788226"
["imageUrl"]=> string(65) "http://www.zappos.com/images/z/1/7/8/8/2/2/1788226-p-DETAILED.jpg"
["color"]=> string(6) "Almond"
["originalPrice"]=> string(6) "$64.95"
}
Now how would I go about accessing the first array element?
I've tried:
echo $data[0][0]['orignalPrice'];
and it does not work. Could someone please help? Also is there a decent debugger for php on a mac? Appreciate any help.
Try that $data['product'][0]['styles'][0]['originalPrice']
Would also recommend you to have a look on a documentation, to learn more about arrays.

Getting Data from PHP Array

I have this array that i used json_decode to create. This is my code:
$obj = json_decode($json);
$results = $obj->{"results"}; // This selects the results section
echo $results[artistName];
$results is the array
The array looks like this:
array(1) {
[0]=> object(stdClass)#5 (8) {
["wrapperType"]=> string(6) "artist"
["artistType"]=> string(6) "Artist"
["artistName"]=> string(5) "Human"
["artistLinkUrl"]=> string(56) "https://itunes.apple.com/us/artist/human/id35761368?uo=4"
["artistId"]=> int(35761368)
["amgArtistId"]=> int(1173165)
["primaryGenreName"]=> string(3) "Pop"
["primaryGenreId"]=> int(14)
}
}
But it does not echo anything. Please help.
It's still an object, so you need to access the key like this.
echo $results[0]->artistName;
echo $results[0]->artistName
Notice, u have array of stdClasses

PHP - Simple XML attributes problem

I use PHP and Simple XML.
I use a loop that does not work like expected:
foreach($item->Image->attributes()->source as $key => $value)
{
echo $value;
}
In the foreach I try to tell that I want to get the "source" of the image which is listed in the attributes.
$item above is created with a loop around my code above foreach($xml_content->Section->Item as $item {}, (if you need to know where it came from)
My object looks like this:
object(SimpleXMLElement)#36 (4) {
["Text"]=>
string(15) "Vinbergs socken"
["Description"]=>
string(73) "Vinbergs socken ingick i Faurås härad och ligger i Falkenbergs kommun.
"
["Url"]=>
string(44) "http://sv.wikipedia.org/wiki/Vinbergs_socken"
["Image"]=>
object(SimpleXMLElement)#38 (1) {
["#attributes"]=>
array(3) {
["source"]=>
string(113) "http://upload.wikimedia.org/wikipedia/commons/thumb/2/25/Faur%C3%A5s_Vinberg.svg/50px-Faur%C3%A5s_Vinberg.svg.png"
["width"]=>
string(2) "50"
["height"]=>
string(2) "41"
}
}
}
What is wrong with my loop in the beginning of my post?
Your are trying to iterate a string, not an array
$item->Image->attributes()->source
To iterate all the attributes of the Image element, use
foreach ($item->Image->attributes() as $attributeName => $attributeValue) {
If you just want to output the value of the source attribute, do not iterate but use the shorthand
echo $item->Image['source']
See this demo and the SimpleXml Basic Usage Examples in the PHP Manual

Categories