Before I start my question, I want to point out that I have tried bits and pieces of different codes that was posted here, and I was not too successful.
So I am working on a page that loads in project description data from an external XML file. I have used simplexml_load_file function to load in the xml file.
XML file:
<?xml version='1.0' encoding='UTF-8'?>
<items>
<item category="Game">
<year>2015</year>
<projectName>Some Game</projectName>
<clientName>Some Company</clientName>
<imagePath>some_imagefile.png</imagePath>
<types>
<type>Work A</type>
<type>Work B</type>
</types>
<languages>
<language>Language X</language>
<language>Language Y</language>
<language>Language Z</language>
</languages>
<platforms>
<platform>Device 1</platform>
</platforms>
<visible>false</visible>
</item>
</items>
The above XML file is loaded in my PHP like:
<?php
$xml = simplexml_load_file("myXMLfile.xml") or die("Error: cannot create object");
?>
I am able to successfully load the XML data and use the retrieved data exactly how I want, except for the fact that it is not ordered.
So I poked around here and there and found out that I can sort my SimpleXMLElement after I transfer the value over to an Array and use usort().
So this is what I did:
function sortByYearDesc($a, $b) {
if ($a->year == $b->year) {
return 0;
}
return $a->year > $b->year ? -1 : 1;
}
function sortByProjectNameAsc($a, $b) {
return strcmp($a->projectName, $b->projectName);
}
$xmlArray = array();
foreach ($xml->item as $iTemp) {
$xmlArray[] = iTemp;
}
usort($xmlArray, "sortByProjectNameAsc");
usort($xmlArray, "sortByYearDesc");
I used two different sorting functions to sort the projects by projectName (ascending) and also by year (descending). So that I have the project displayed by the release year of the game while titles released in the same year are displayed by ascending order of its title.
Backtracking to what I originally had in my code before I added the sort functions, I have been using the loaded SimpleXMLElement by doing something like this:
<?php
foreach ($xml->item as items) {
// get_bool is a function that I made to switch a boolean to a String
if (get_bool($items->visible)) {
// echo stuff
// by stuff I mean any xml data to display
}
}
?>
I assumed that I can simply substitute the SimpleXMLElement to an array:
<?php
foreach ($xmlArray->item as items) {
// I changed $xml to $xmlArray
if (get_bool($items->visible)) {
// echo stuff
// by stuff I mean any xml data to display
}
}
?>
And I get a message "Warning: Invalid argument supplied for foreach()".
Any suggestions? What am I missing?
***** added *****
First of all, thanks to splash58 for pointing out missing $ in my code. Other than that, I did find a solution myself like below:
function sortByYearDesc($a, $b) {
// I noticed that the value was compared in String value, not as an integer
// so I casted each value to int
if ((int)$a->year == (int)$b->year) {
return 0;
}
return (int)$a->year > (int)$b->year ? -1 : 1;
}
function sortByProjectNameAsc($a, $b) {
return strcmp($a->projectName, $b->projectName);
}
$xmlArray = array();
foreach ($xml->item as $iTemp) {
$xmlArray[] = $iTemp; // changed "iTemp" to "$iTemp"
}
usort($xmlArray, "sortByProjectNameAsc");
usort($xmlArray, "sortByYearDesc");
I was also missing $ in my echo part of the PHP, which I had in my actual code but not in the code that I posted here:
<?php
// original post:
// foreach ($xmlArray->item as items) {
// xmlArray already is an array of "item" so does not need to go to the "item" node
// and the obvious change from "items" to "$items"
foreach ($xmlArray as $items) {
// I changed $xml to $xmlArray
if (get_bool($items->visible)) {
// echo stuff
// by stuff I mean any xml data to display
}
}
?>