Сортировка AS3 XMLList в порядке документа

В ActionScript 3 есть способ отсортировать узлы (экземпляры типа XML) в XMLList в порядке документа (как определено в спецификация XDM;« Неформально, порядок документов - это порядок, в котором узлы появляются в XML-сериализации документа »)? В качестве альтернативы, есть ли способ сравнить положение двух узлов в документе?

Вот небольшой пример того, что я имею в виду. В реальном случае список создается гораздо более сложным процессом и может состоять из сотен узлов.

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);

Я не уверен, что у меня здесь много надежд, поскольку кажется, что ECMA-357 (E4X) действительно не имеет концепции документа, не говоря уже о порядке документа.


person Steven Ourada    schedule 22.09.2011    source источник
comment
Вы когда-нибудь использовали XMLListCollection? В него встроены функции сортировки и фильтрации.   -  person The_asMan    schedule 22.09.2011
comment
Спасибо за предложение. Я не смотрел на это, так как это не вещь с графическим интерфейсом. Я только взглянул и не вижу способа отсортировать документы по порядку.   -  person Steven Ourada    schedule 23.09.2011
comment
Что вы подразумеваете под сортировкой по порядку документов?   -  person The_asMan    schedule 23.09.2011
comment
Я добавил небольшое пояснение по этому поводу в вопрос.   -  person Steven Ourada    schedule 24.09.2011


Ответы (1)


Вот набросок ответа, который я придумал. Это еще не так много проверялось, но я подумал, что запишу, пока не забыл.

Идея состоит в том, чтобы реализовать функцию для генерации строки для узла, чтобы порядок строк был таким же, как порядок узлов.

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;
}
person Steven Ourada    schedule 28.09.2011