After looking around I couldn't really find a good solution or maybe people weren't explaining themselves correctly, or I wasn't googling correctly. So I decided just to write my own small utility class.
When I thought about it. Arrays provide a superb sortOn() function, and it's relatively easy to leverage that.
code
I created a sortXMLByAttribute() public static function in my XMLUtils Class
public static function sortXMLByAttribute
(
$xml : XML,
$attribute : String,
$options : Object = null,
$copy : Boolean = false
)
:XML
{
//store in array to sort on
var xmlArray:Array = new Array();
var item:XML;
for each(item in $xml.children())
{
var object:Object = {
data : item,
order : item.attribute($attribute)
};
xmlArray.push(object);
}
//sort using the power of Array.sortOn()
xmlArray.sortOn('order',$options);
//create a new XMLList with sorted XML
var sortedXmlList:XMLList = new XMLList();
var xmlObject:Object;
for each(xmlObject in xmlArray )
{
sortedXmlList += xmlObject.data;
}
if($copy)
{
//don't modify original
return $xml.copy().setChildren(sortedXmlList);
}
else
{
//original modified
return $xml.setChildren(sortedXmlList);
}
}say what?
- Store XML in an array of objects, where one key is the "order" attribute we want to sort on.
- Next we just call the Array.sortOn, with whatever options were passed
- We then loop over sorted array and create a new XMLList
- We then replace the children of original with sorted children
how to use
$xml : The XML that needs to be sorted
$attribute : The attribute string to sort on
$options : The sorting options, see sortOn()
$copy : If false, original XML is modified.
Here is an example, note this is in a package called XMLUtils
var xml:XML =
<body id="someId">
<p displayOrder="15">Hello</p>
<p displayOrder="7">World</p>
<p displayOrder="3">Is</p>
<p displayOrder="9">This</p>
<p displayOrder="25">Thing</p>
<p displayOrder="13">Working</p>
</body>
// original XML object
trace("BEFORE:" + xml);
XMLUtils.sortXMLByAttribute(
xml,
'displayOrder'
);
trace("After:" + xml);
XMLUtils.sortXMLByAttribute(
xml,
'displayOrder',
Array.NUMERIC
);
trace("Array.NUMERIC:" + xml");
//multiple options not don't modify orginal
var reverseXML:XML = XMLUtils.sortXMLByAttribute(
xml,
'displayOrder',
Array.NUMERIC | Array.DESCENDING,
true
);
trace("Array.NUMERIC | Array.DESCENDING:" + reverseXML);source
Source code (in package+ + example) xmlutil.zip