views:

274

answers:

2

So I'm having a slightly tricky issue...

I'm generating an XML file within a class I'm writing. Let's say this was the starting XML:

<base>
    <container id="0">
        <element type="Image" x="0" y"0" />
        <element type="Image" x="100" y"0" />
    <container/>
</base>

I want to add additional <element>'s. The first order of sorting is by "type", then "x", then "y". So if I add a new "type" of <element>, let's say type "Text", I want Text to be inserted after any "Image" <element>'s.

For example:

<base>
    <container id="0">
        <element type="Image" x="0" y"0" />
        <element type="Image" x="100" y"0" />
        <element type="Text" x="200" y"100" />
    <container/>
</base>

The basic idea is to keep the list sorted as I add more <element>'s to each <container>... The numeric sorting is simple enough, but I can't figure out a clean way to sort alphabetically.

Suggestions are appreciated.

The only thing I can think of is to get the types into an Array. Add the "new type", sort and call indexOf()... the number SHOULD be the current position I should insert before? Feels kludgy.

A: 

I would suggest reading all the existing XML elements into an array, adding your new elements, sorting the array, then writing every element back out. This might be easier than trying to figure out which index each new element should be inserted at. This may not be very efficient, though, depending on your situation.

For doing the sorting, I would try something like this (untested):

array.sort(function (a:XML, b:XML) {
    if (a.@type < b.@type) return -1;
    if (a.@type > b.@type) return +1;
    if (Number(a.@x) != Number(b.@x)) return Number(a.@x) - Number(b.@x);
    return Number(a.@y) - Number(b.@y);
});

EDIT: Added casts in the sort compare function.

Cameron
A: 

Can you change the XML structure? You could wrap all Image elements in an <images> node, Text elements in a <texts> node and so forth, and this way adding elements to the right place would be easy.

You could still get all the <element> nodes by accessing base.container.*.element.

Niko Nyman