How to filter xml nodes by nested children values in ActionScript 3?
Asked Answered
M

3

6

I have a very simple scenario where I have a structure similar to this

<tours>
    <tour>
        <name>Italy 1</name>
        <destinations>
            <destination>Rome</destination>
            <destination>Milan</destination>
        <destinations>
    </tour>
    <tour>
        <name>Italy 2</name>
        <destinations>
            <destination>Rome</destination>
            <destination>Venice</destination>
        <destinations>
    </tour>
</tours>

Now I want to query all the tours that go to Milan.

Below is the logical format that I can think of based on EX4 style

XmlData.tour.(destinations.destination.(name == "Milan"))

But of course this doesn't work.

What is the correct way of pulling this data without using any extra logic?

Mascle answered 17/12, 2012 at 12:38 Comment(0)
S
3

XmlData.tour.destinations.destination is XMLList. It contains XMLs, which looks like <destination>Milan</destination> Each these XML have name = destination, so you get nothing as result.

Try this:

XmlData.tour.(destinations.destination.children().contains("Milan"));
Secern answered 17/12, 2012 at 15:5 Comment(1)
Interesting, that works like a charm, seems a bit weird when compared against the E4X-documentation on how it should work though? And to OP: I found senocular.com/flash/tutorials/as3withflashcs3/?page=4 which might give you pretty detailed information on working with xml in AS3.Cephalothorax
C
1

1)Badly formatted xml. (missing '/' on closing destinations)

2)You seem to have run into some kind of bug in AS3 E4X-finder. This was really weird, here's a workaround though...

var foo:XMLList = data.tour.destinations.(destination == "Milan");
trace("direct check:  " + foo); //fails - 0 matches
trace("------");
for each(var child:XML in data.tour.destinations.destination) {
    if (child == "Milan") {
        trace("found match in foreach Milan");
    }
}

Further investigating, it seems like the E4X-engine screws up since you have multiple children inside a tag with the same identifier (<destination>).

typing following makes the "filter function" behave as expected:

<destinations>
<destination2>Rome</destination2>
<destination>Milan</destination>
</destinations>

.... that's really weird... Anyone who can elaborate on this? Because according to the xml-standards of E4X it should be possible to do it as done in the question.

Cephalothorax answered 17/12, 2012 at 14:7 Comment(1)
commented to soon. As @Secern showed, I had lost my mind :)Maxima
S
0

This script will help you to create a new xml from your XmlData, but only with tours including destination to Milan :

var DESTINATION_TO_CHECK:String = "Milan";
var i:int;
var j:int;
var numberOfTours:int = XmlData.tour.length();
var numberOfDestinations:int;
var tours:String = "<tours to='" + DESTINATION_TO_CHECK + "'>";

for (i = 0; i < numberOfTours; i++)
{
    numberOfDestinations = XmlData.tour[i].destinations.destination.length();

    for (j = 0; j < numberOfDestinations; j++)
    {
        if (XmlData.tour[i].destinations.destination[j] == DESTINATION_TO_CHECK)
        {
            tours += XmlData.tour[i];
        }
    }
}

tours += "</tours>";

trace(new XML(tours));
Seton answered 17/12, 2012 at 13:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.