JamesG JamesG - 5 days ago 5
JSON Question

Issues building JSON from XML using SimpleXML

I am trying to get a list of books, which I am parsing from XML and I would like the output as JSON.

I would like the format of the JSON to be:

[
"1" : {
"Title": "Sidemen: The Book",
"ISBN": "1473648165",
"Rating": "4.5"
},
...
]


However, the result is coming out like this:

[
{
"title":{
"0":"Sidemen: The Book"
},
"ISBN":{
"0":"1473648165"
}
},
{
"title":{
"0":"DanTDM: Trayaurus and the Enchanted Crystal"
},
"ISBN":{
"0":"1409168395"
}
},
{
"title":{
"0":"Pok\u00e9mon Sun & Pok\u00e9mon Moon: The Official Strategy Guide"
},
"ISBN":{
"0":"1911015109"
}
},
{
"title":{
"0":"Guinness World Records 2017 Gamer's Edition"
},
"ISBN":{
"0":"1910561398"
}
},
{
"title":{
"0":"Minecraft: Blockopedia: An Official Minecraft Book from Mojang"
},
"ISBN":{
"0":"1405273534"
}
},
{
"title":{
"0":"Final Fantasy XV - The Complete Official Guide - Collector's Edition"
},
"ISBN":{
"0":"1911015001"
}
},
{
"title":{
"0":"Harry Potter: Collectible Quidditch Set"
},
"ISBN":{
"0":"076245945X"
}
},
{
"title":{
"0":"Pok\u00e9mon Go The Unofficial Field Guide: Tips, tricks and hacks that will help you catch them all!"
},
"ISBN":{
"0":"1783707712"
}
},
{
"title":{
"0":"Minecraft 2017 Annual (by GamesMaster) (2017 Annuals)"
},
"ISBN":{
"0":"0995495025"
}
},
{
"title":{
"0":"World of Warcraft The Official Cookbook"
},
"ISBN":{
"0":"1785654349"
}
}
]


I can't seem to figure out why this is not doing what I want (probs because i'm a noob). This is generated with PHP like so:

$bookList = array();
$id = 0;
foreach ($parsed_xml->Items->Item as $item) {
$response = file_get_contents($GoodReadsProductLink);
$parsed_xml = simplexml_load_string($response);

$currentBook = array(
"title" => $item->ItemAttributes->Title,
"ISBN" => $item->ItemAttributes->ISBN,
"Rating" => $item->ItemAttributes->Rating
);

$bookList[$id] = $currentBook;

$id++;
}

$jsonOutput = json_encode($bookList);


var_dump($jsonOutput);


Can anyone see the issue, and help me to format the JSON output correctly?

Answer

Cast the SimpleXmlElement objects to string, and use the JSON_FORCE_OBJECT option.

Example.

$xml = <<<'XML'
<Items>
  <Item Title="Book Title 1" ISBN="ISBN 1" Rating="4.5"/>
  <Item Title="Book Title 2" ISBN="ISBN 2" Rating="5.0"/>
</Items>
XML;
$doc = simplexml_load_string($xml);

$id = 0;
$books = [];
foreach ($doc as $item) {
  if (! $attr = $item->attributes()) {
    continue;
  }

  if (empty($attr['Title']) || empty($attr['ISBN']) || empty($attr['Rating'])) {
    continue;
  }

  $books[++$id] = [
    'title'  => (string)$attr['Title'],
    'ISBN'   => (string)$attr['ISBN'],
    'Rating' => (string)$attr['Rating'],
  ];
}

echo $json = json_encode($books, JSON_FORCE_OBJECT | JSON_PRETTY_PRINT);

Output

{
    "1": {
        "title": "Book Title 1",
        "ISBN": "ISBN 1",
        "Rating": "4.5"
    },
    "2": {
        "title": "Book Title 2",
        "ISBN": "ISBN 2",
        "Rating": "5.0"
    }
}
Comments