I need to insert maximum number of commands in to the one cycle, while working with XML tree.
I will use E4X filters to work with XML and to process its nodes.
For the next examples I will use test XML tree:
private
var
xml:XML
=
<root>
<node
name="
Alan
"
age="
26
"
><address>
<![CDATA[1 Fake
address]]>
</address></node>
<node
name="
Mike
"
age="
31
"
><address>
<![CDATA[2 Fake
address]]>
</address></node>
<node
name="
Greg
"
age="
28
"
><address>
<![CDATA[3 Fake
address]]>
</address></node>
<node
name="
Bret
"
age="
21
"
><address>
<![CDATA[4 Fake
address]]>
</address></node>
<node
name="
Mike
"
age="
32
"
><address>
<![CDATA[2 Fake
address]]>
</address></node>
<node
name="
Greg
"
age="
22
"
><address>
<![CDATA[3 Fake
address]]>
</address></node>
<node
name="
Alan
"
age="
26
"
><address>
<![CDATA[1 Fake
address]]>
</address></node>
<node
name="
Mike
"
age="
34
"
><address>
<![CDATA[2 Fake
address]]>
</address></node>
</root>
;
And
simple value object class:
class
User
extends
Object{
public
var
name:String
=
''
;
public
var
age:uint
= 0;
public
var
address:String
=
''
;
function
User(name:String,
age:uint):
void
{
super
();
this
.name
= name;
this
.age
= age;
}
public
function
toString():String{
return
'[User(name="'
+
this
.name+
'",
age="'
+
this
.age+
'", address="'
+
this
.address+
'")]'
;
}
}
Any E4X
filter should be located inside the round brackets and inside
this brackets you can execute any commands separated by commas.
First example will use filter to convert XML nodes into value
objects:
private
function
simpleFilter():
void
{
var
items:Array = [];
xml.node.(items.push(
new
User(@name,
uint(@age))));
trace
(items.join(
'\n'
));
}
/* trace output
[User(name="Alan", age="26", address="")]
[User(name="Mike", age="31", address="")]
[User(name="Greg", age="28", address="")]
[User(name="Brett", age="21", address="")]
[User(name="Mike", age="32", address="")]
[User(name="Greg", age="22", address="")]
[User(name="Alan", age="26", address="")]
[User(name="Mike", age="34", address="")]
*/
As you can see, all objects created inside E4X filter's body.
This example can be rewritten without E4X syntax using cycle:
private
function
simpleXMLCycle():
void
{
var
items:Array = [];
var
xlist:XMLList = xml.node;
var
length:int = xlist.length();
for
(
var
i:int=0; i<length; i++){
var
node:XML =
xlist[i];
with
(node){
items.push(
new
User(@name,
uint(@age))
);
}
}
trace
(items.join(
'\n'
));
}
This example will return the same result as previous. But
this example do not display all power of E4X filters. Next example
will show you how to use couple expressions inside one filter:
private
function
separatedFilter():
void
{
var
items:Array = [];
var
item:User;
xml.node.(
items.push(item =
new
User(@name,
uint(@age))),
item.address = address[0].toString()
);
trace
(items.join(
'\n'
));
}
/* trace output
[User(name="Alan", age="26", address="1 Fake
address")]
[User(name="Mike", age="31", address="2 Fake
address")]
[User(name="Greg", age="28", address="3 Fake
address")]
[User(name="Brett", age="21", address="4 Fake
address")]
[User(name="Mike", age="32", address="2 Fake
address")]
[User(name="Greg", age="22", address="3 Fake
address")]
[User(name="Alan", age="26", address="1 Fake
address")]
[User(name="Mike", age="34", address="2 Fake
address")]
*/
Next example contains two filters, one of them - just
condition, usual for E4X:
private
function
multipleFilter():
void
{
trace
(
'multipleFilter'
);
var
items:Array = [];
var
item:User;
xml.node.(int(@age)>30).(
items.push(item =
new
User(@name,
uint(@age))),
item.address = address[0].toString()
);
trace
(items.join(
'\n'
));
}
/* trace output
[User(name="Mike", age="31", address="2 Fake
address")]
[User(name="Mike", age="32", address="2 Fake
address")]
[User(name="Mike", age="34", address="2 Fake
address")]
*/
In this example, filters have shared responsibilities - the
first filters the data, and the second converts passed data. But
the two filters are equal to two cycles, which perform common tasks
and the second depends on the outputs of the first cycle. So I
'll rewrite this example using a single filter
:
xml.node.(
// ?: condition
int(@age)>30 ?
(
// if condition equals
TRUE actions, separated by commas
item =
new
User(@name,
uint(@age)),
items.push(item),
item.address = address[0].toString()
) :
false
// if
condition equals FALSE actions
);