tags:

views:

765

answers:

2

Is it possible to sort an XMLList? All the examples I can find on it create a new XMLListCollection like this:

MyXMLListCol = new XMLListCollection(MyXMLList);

I don't think the XMLListCollection in this case has any reference to the XMLList so sorting it would leave my XMLList unsorted, is this correct?

How can I sort the XMLList directly?

Thanks ~Mike

A: 

While there is no native equivalent to the Array.sortOn function, it is trivial enough to implement your own sorting algorithm:

// Bubble sort.

// always initialize variables -- it save memory.
var ordered:Boolean = false;
var l:int = xmlList.length();
var i:int = 0;
var curr:XML = null;
var plus:XML = null;
while( !ordered )
{
 // Assume that the order is correct
 ordered = true;
 for( i = 0; i < l; i++ )
 {
  curr = xmlList[ i ];
  plus = xmlList[ i + 1 ]; 

  // If the order is incorrect, swap and set ordered to false.
  if( Number( curr.@order ) < Number( plus.@order ) )
  {
   xmlList[ i ]   = plus;
   xmlList[ i + 1 ] = curr;
   ordered = false;
  }
 }
}

but, realistically, it is far easier and less buggy to use XMLListCollection. Further, if someone else is reading your code, they will find it easier to understand. Please do yourself a favor and avoid re-inventing the wheel on this.

Christopher W. Allen-Poole
This is a great code snippet. Simple and to the point. Thank you.
invertedSpear
After a few attempts I gave up on getting this code to work, it seems to be going into an infinate (or at least a very very long loop)
invertedSpear
Admittedly, with XMLLists, if length is excessive, this code won't work terribly efficiently. But, you might be able to look into the SDK directly and see how XMLListCollection implements sort.
Christopher W. Allen-Poole
A: 

So I finally got my search terms altered enough I actually churned up an answer to this. Using the technique I got from here: http://freerpad.blogspot.com/2007/07/more-hierarchical-sorting-e4x-xml-for.html

I was able to come up with this:

public function sortXMLListByAttribute(parentNode:XML,xList:XMLList,attr:String):void{
//attr values must be ints
var xListItems:int = xList.length();
if(xListItems !=0){
 var sortingArray:Array = new Array();
 var sortAttr:Number = new Number();
 for each (var item:XML in xList){
  sortAttr = Number(item.attribute(attr));
  if(sortingArray.indexOf(sortAttr)==-1){
   sortingArray.push(sortAttr);
  }
  //piggy back the removal, just have to remove all of one localName without touching items of other localNames
  delete parentNode.child(item.localName())[0];
 }
 if( sortingArray.length > 1 ) {
  sortingArray.sort(Array.NUMERIC);
 }

 var sortedList:XMLList = new XMLList();
 for each(var sortedAttr:Number in sortingArray){
  for each (var item2:XML in xList){
   var tempVar:Number = Number(item2.attribute(attr));
   if(tempVar == sortedAttr){
    sortedList += item2
   }
  }
 }
 for each(var item3:XML in sortedList){
  parentNode.appendChild(item3);
 }
}
}

Works pretty fast and keeps my original XML variable updated. I know I may be reinventing the wheel just to not use an XMLListCollection, but I think the ability to sort XML and XMLLists can be pretty important

invertedSpear