In Actionscript 3, is there a way to sort the nodes (instances of type XML开发者_开发技巧) in an XMLList in document order (as defined in the XDM spec; "Informally, document order is the order in which nodes appear in the XML serialization of a document")? Alternately, is there a way to compare the document position of two nodes?
Here's a little example of what I mean. In the real case, the list is constructed by a much more complicated process and might have hundreds of nodes.
var x:XML = <a><b/><b/></a>;
var b0:XML = x.b[0];
var b1:XML = x.b[1];
var l:XMLList = new XMLList();
l += b1;
l += b0;
var sl:XMLList = documentSortFunction(l);
assertTrue(sl[0] === b0);
I'm not sure I have a lot of hope here, since it seems that ECMA-357 (E4X) doesn't really have a concept of document, much less document order.
Well, here's a sketch of the answer I came up with. This hasn't been tested much yet, but I thought I'd record it before I forget to.
The idea is to implement a function to generate a string for a node, such that the order of the strings is the same as the order of the nodes.
protected function generateSortID(n:XML):String
{
var ret:String = '';
while (n != null && n.childIndex() > -1)
{
var s:String = '' + n.childIndex();
ret = '0000000'.substring(s.length) + s + '!' + ret;
n = n.parent();
}
return ret;
}
protected function compareNodePair(a:Array, b:Array):int
{
var ai:String = a[0];
var bi:String = b[0];
if (ai < bi)
return -1;
else if (ai > bi)
return 1;
else
return 0;
}
// all nodes in input list must be part of the same document.
protected function documentSortFunction(l:XMLList):XMLList
{
var augArr:Array = [];
for (var il:String in l)
augArr.push([generateSortID(l[il]), l[il]]);
augArr.sort(compareNodePair);
var ret:XMLList = new XMLList();
for (var ia:String in augArr)
ret += augArr[ia][1];
return ret;
}
精彩评论