My approach was to convert the SimpleXMLElement objects into arrays:
$doc = new SimpleXMLElement($xml);
$states = get_object_vars($doc->prop->children());
$states = $states["state"];
usort($states, function($t1, $t2) { return strcmp($t1['statename'], $t2['statename']); });
array_walk($states,
function (&$state) {
$state = get_object_vars($state);
array_walk($state["info"],
function (&$el) {
$el = get_object_vars($el);
}
);
usort($state["info"],
function($a, $b) { return strcmp($a["location"], $b["location"]); }
);
}
);
You want to sort a list of SimpleXMLElement
s based on some attribute or element value. You normally do this by turning the list into an array and then apply the sorting on that array.
A function helpful for that in PHP is iterator_to_array. It does the job to turn something that is so magic in simplexml into a more "fixed" array.
Let's say your tour elements in $result->tour
. By default simplexml returns an iterator here, something you can not sort out of the box. Let's convert it into an array:
$tours = iterator_to_array($result->tour, false);
Now the $tours
variable is an array containing each <tour>
element as a SimplXMLElement
. You can now sort that array with an array function. Those array sorting functions are outlined in the PHP manual and I normally suggest How do I sort a multidimensional array in php as a good starting point:
$tourDates = array_map(
function($tour) {return trim($tour->next_bookable_date); },
$tours
);
// sort $tours array by dates, highest to lowest
$success = array_multisort($tourDates, SORT_DESC, $tours);
And that's already it. The whole code at a glance:
$tours = iterator_to_array($result->tour, false);
$tourDates = array_map(
function($tour) {return trim($tour->next_bookable_date); },
$tours
);
// sort $tours array by dates, highest to lowest
$success = array_multisort($tourDates, SORT_DESC, $tours);
foreach ($tours as $tour) {
...
}
changing this
foreach ($prop->children() as $stateattr)
to this
foreach ($sortedStates as $stateattr)
did it.
could have sworn I tried that already.