0

I am attempting to sort a list of nodes alphabetically, before echoing them out in SimpleXML. I am using a usort function similar to the one referenced here:

Sorting Results returned by SimpleXML, and Xpath in PHP

Here is my code:

$xQuery = $xml->comiclist->comic;

function cmp ($a, $b) {
     return strcmp(
         $a->mainsection->series->sortname, 
         $b->mainsection->series->sortname
     ); 
}

usort($xQuery, "cmp");

foreach ($xQuery as $comic) :

The issue is that it only seems to be partially working. Most of the items are grouped together correctly but, some are completely out of place. As you can see from the function, each $comic node is being sorted by its child "mainsection->series->sortname".

Here's an example of some of the order it's generating:

<sortname>New Avengers: Illuminati, Vol. 2</sortname>
<sortname>New Avengers: Illuminati, Vol. 2</sortname>
<sortname>Nova</sortname>
<sortname>New X-Men</sortname>
<sortname>Nation X</sortname>
<sortname>Namor, The Sub-Mariner Annual</sortname>

As you can see, they are not in alphabetical order. Am I missing something? Any help is appreciated.

Community
  • 1
  • 1
Batfan
  • 7,966
  • 6
  • 33
  • 53

1 Answers1

3

From quickly looking at your question, it looks like that you're using usort on an object of type SimpleXMLElement. However the function is intended to be used for an array.

Probably converting the object (or more precisely the iterator it offers) to an array first should solve your issue.

Explanation: In the example you've linked, the xpath function is used which already returns an array, here in your example that is not the case.

A function to turn the offered iterator to an array is iterator_to_array:

$array = iterator_to_array($xQuery, false);

usort($array, "cmp");

foreach ($array as $comic) ...
hakre
  • 193,403
  • 52
  • 435
  • 836
  • 1
    Note: The *$use_keys* parameter needs to be set to `false` otherwise the array will only have one entry. I was missing that. – hakre Sep 30 '12 at 22:37
  • One more thing, I'm using an xpath query right before I echo the data to grab some data from the previous & next nodes. This works fine except it doesn't appear to be picking up this new sort order. You can see the code here http://db.tt/J1ZOLeKN Any thoughts? – Batfan Sep 30 '12 at 22:58
  • 1
    Only the array is sorted, the XML is not sorted. `usort` is for sorting arrays, not for sorting SimpleXML elements. However, you could remove all the elements and then add them in order again. However this is crossing the border where using `DomDocument` makes more sense (you can convert between `SimpleXML` and `DomDocument`, so no fear). You might just want to re-generate some XML string mabye instead? – hakre Sep 30 '12 at 23:06
  • Hmm, okay. Is it possible for me to run an xpath query on the array to grab this info? – Batfan Sep 30 '12 at 23:16
  • 1
    You could look based on the array index for the previous and next node. That would spare you the xpath completely and work with the sorted array (the array is zero-based indexed, `count($array)` will tell you the number of elements). Is that what you're looking for (sorry didn't understood why you then had xpath again)? – hakre Oct 01 '12 at 00:06
  • I'm basically just trying to grab a certain value from the previous and next nodes, each time. I can get it to count all the $comic nodes but, how do I get it to dynamically figure out which one is the current one? I'm assuming I can then just -1 for the prev and +1 for the next. – Batfan Oct 01 '12 at 00:20
  • Yeah, been toying around with it and not having any luck. – Batfan Oct 01 '12 at 01:42
  • you're looking to sort and then this display? http://stackoverflow.com/q/12659004/367456 – hakre Oct 01 '12 at 06:56
  • Yes, that's ideally what I'd like to do. In the meantime, I've come up with a jquery solution but, ultimately, I'd prefer it be done server-side. – Batfan Oct 01 '12 at 20:11
  • Is there any way to make this account for numerical sorting too? For example, current order: New X-Men1, New X-Men10, New X-Men2. Desired order: New X-Men1, New X-Men2, New X-Men10 – Batfan Oct 03 '12 at 00:37
  • natsort, look for natural sort order. – hakre Oct 03 '12 at 10:17