Hi
If your using recursion you could do something like the following (email, AS3,
not tested):
public function createPeople (pNode:XML, pDepth:uint=0):void
{
// lets assume that you might have child nodes that aren't "person" nodes. So
select only the nodes
// of type person. Even if no person nodes exist, this will still return an
XMLList instance with 0 items.
var childList:XMLList = pNode.person;
for each (var personNode:XML in childList)
{
// if there is a chance that @firstName or @lastName is optional then assuming
they are the code below
// will generate a runtime exception. If you are generating your XML against a
schema and thus
// are absolutely certain that the attributes are there then doing the extra
checking would not be worth
// it. The simplest safety valve would be to put a try catch around accessing
those attributes as I've done.
try
{
trace(personno...@firstname+" "+personno...@lastname);
} catch(err:Error) {
//suppress error, trace a warning that includes name of class, function,
message and node with missing attributes
trace("WARN::[" + getQualifiedClassName(this) + "]::createPeople() found person
node with missing attribute:" + personNode.toXMLString());
}
// check to see if the node has any person children, if so, call the function
recursively increment the depth
if (personNode.person.length() > 0)
{
createPeople(personNode, pDepth+1);
}
}
}
Now depth indicates how far into the nest you are. Note, assuming you call this
method from "your root depth" whatever that
is and don't pass in a depth parameter, this will automatically start at 0 and
increment upwards as it finds a child level.
Remember, if you need to see up one level then simply see if the current node
has a parent node.
var parent:XML = pNode.parent();
if (parent != undefined)
{
// do something with parent
}
however, you would have to use recursion again if you wanted to see the depth
as in the example I gave you on Friday where if you needed all the person nodes
you could do:
var people:XMLList = peopleList..*.(name() == "person");
but to get the depth of each node you would need to put in a recursive function
that incremented until the following condition was not met:
((person.parent() == undefined) || (person.parent().name() != "person"))
if you need a list of all person nodes with no depth, I'd go with:
var people:XMLList = peopleList..*.(name() == "person");
if you need need a list that includes depth then I'd go with the recursion
example above that passes a depth.
Sincerely
Mark R. Jonkman
----- Original Message -----
From: "Theodore Lehr" <[email protected]>
To: "Flash Coders List" <[email protected]>
Sent: Monday, March 22, 2010 8:03:02 AM GMT -05:00 US/Canada Eastern
Subject: RE: [Flashcoders] Recursive:Part II
Works great... I am wondering now.... How would I track where I am as I go
through the xml... I would like to know when I am at the "parent" or when I am
at a "child" or when I move into a "grandchild" and so on and son on....
________________________________________
From: [email protected]
[[email protected]] On Behalf Of Merrill, Jason
[[email protected]]
Sent: Friday, March 19, 2010 4:57 PM
To: Flash Coders List
Subject: RE: [Flashcoders] Recursive:Part II
Actually, I got thinking, and this recursive function should work for
you eh? - this traces out all the first and last names of all nodes:
var _xml:XML = new XML(
<people>
<person firstName="Bob" lastName="Smith">
<person firstName="Timmy" lastName="Smith" />
<person firstName="Jenny" lastName="Jones" >
<person firstName="Sal" lastName="Stephens" />
</person>
<person firstName="Marcia" lastName="Marquez">
<person firstName="Julio" lastName="Rogers"/>
</person>
</person>
<person firstName="Tom" lastName="Williams">
<person firstName="Mary" lastName="Jones" />
<person firstName="Albert" lastName="Denniston">
<person firstName="Campo" lastName="Fatigua"/>
<person firstName="Harpo" lastName="Oprah"/>
</person>
</person>
<person firstName="Marcia" lastName="Marquez">
<person firstName="Manny" lastName="Peterson"/>
</person>
</people>);
function createPeople (xml:*):void
{
var xmlList:XMLList = xml.children();
for each (var personNode:* in xmlList)
{
trace(personno...@firstname+" "+personno...@lastname);
if(personNode.children()) createPeople(personNode);
}
}
createPeople(_xml);
And yeah, I prefer doing XML that way, I think avoids XML verbosity,
large file sizes, and confusion in reading.
Jason Merrill
Bank of America Global Learning
Learning & Performance Solutions
Join the Bank of America Flash Platform Community and visit our
Instructional Technology Design Blog
(note: these are for Bank of America employees only)
-----Original Message-----
From: [email protected]
[mailto:[email protected]] On Behalf Of Lehr,
Theodore
Sent: Friday, March 19, 2010 4:48 PM
To: Flash Coders List
Subject: RE: [Flashcoders] Recursive:Part II
thanks - I'll chew on this Monday... fyi - I have changed my xml to how
Jason suggested and find it much easier to work with....
Ted
________________________________________
From: [email protected]
[[email protected]] On Behalf Of
[email protected] [[email protected]]
Sent: Friday, March 19, 2010 4:42 PM
To: Flash Coders List
Subject: Re: [Flashcoders] Recursive:Part II
If what you are doing is looking for nodes with firstnames then you can
do something like this:
Assuming Jason's XML with attributes:
var peopleList:XML = <people>
<person firstName="Bob" lastName="Smith">
<person firstName="Timmy" lastName="Smith" />
<person firstName="Jenny" lastName="Jones" />
<person middleName="Beth" lastName="Jones" />
</person>
<person firstName="Tom" lastName="Williams">
<person firstName="Sa" lastName="Williams" />
</person>
</people>;
var firstNames:XMLList = peopleList..*.(hasOwnProperty("@firstName"));
trace(firstNames);
The ..* automatically selects all nodes that have a firstName attribute
regardless of nesting. Thus you could loop over firstNames with no
recursion and get a list of all firstnames. The list will contain all
the nodes witha firstName attribue, so you will get one node with Bob as
firstName that still has 3 children, but you will also get 2 of those
children in the firstNames list so you would simply ignore the children
inside of Bob. For testing purposes I purposefully added an extra child
node with no firstName to Bob.
This is the result
<person firstName="Bob" lastName="Smith">
<person firstName="Timmy" lastName="Smith"/>
<person firstName="Jenny" lastName="Jones"/>
<person middleName="Beth" lastName="Jones"/>
</person>
<person firstName="Timmy" lastName="Smith"/>
<person firstName="Jenny" lastName="Jones"/>
<person firstName="Tom" lastName="Williams">
<person firstName="Sa" lastName="Williams"/>
</person>
<person firstName="Sa" lastName="Williams"/>
You can do something similar with your structure:
var peopleList:XML = <allPeople>
<person>
<personFirstName>Bob</personFirstName>
<personLastName>Smith</personLastName>
<person>
<personFirstName>Timmy</personFirstName>
<personLastName>Smith</personLastName>
</person>
<person>
<personFirstName>Jenny</personFirstName>
<personLastName>Smith</personLastName>
</person>
</person>
<person>
<personFirstName>Tom</personFirstName>
<personLastName>Williams</personLastName>
<person>
<personFirstName>Sa</personFirstName>
<personLastName>Williams</personLastName>
</person>
</person>
</allPeople>;
var firstNames:XMLList = peopleList..*.personFirstName;
trace(firstNames);
result:
<personFirstName>
Bob
</personFirstName>
<personFirstName>
Timmy
</personFirstName>
<personFirstName>
Jenny
</personFirstName>
<personFirstName>
Tom
</personFirstName>
<personFirstName>
Sa
</personFirstName>
Your structure produces a simpler list, however I favor Jason's
attribute version as it is far more compact, simpler to read, etc.
Personal preference.
But if you don't need to do recursion then don't. Saves many headaches.
Sincerely
Mark R. Jonkman
----- Original Message -----
From: "Theodore Lehr" <[email protected]>
To: "Flash Coders List" <[email protected]>
Sent: Friday, March 19, 2010 4:15:11 PM GMT -05:00 US/Canada Eastern
Subject: RE: [Flashcoders] Recursive:Part II
sorry a couple of typos... the function should be:
function createPeople (_xml:*):void
{
var xmlList:XMLList=_xml.children();
for each (var fn_xml in xmlList) {
createPeople(fn_xml);
trace(item_xml.personFirstName);
}
}
________________________________________
From: [email protected]
[[email protected]] On Behalf Of Merrill, Jason
[[email protected]]
Sent: Friday, March 19, 2010 4:07 PM
To: Flash Coders List
Subject: RE: [Flashcoders] Recursive:Part II
I would write the XML this way instead:
<people>
<person firstName'"Bob" lastName="Smith">
<person firstName="Timmy" lastName="Smith" />
<person firstName="Jenny" lastName="Jones" >
<person firstName="Sal" lastName="Stephens" />
</person>
</person>
<person firstName="Tom" lastName="Williams">
.etc.
Also, recursive functions call themselves - and then break when some
value or condition is reached.... for yours, add to your object, and
then check to see if there are child nodes in the xml below it, if so,
call the function again to add more, if not, break out of the function.
However, this will only get you through the top level nodes and one of
the top level nodes's sub nodes - not the others - I actually can't
think of how to get into the OTHER sub-nodes - though I know there are
people on this list who do. I know what some people do is make the first
pass on the first level, then the second pass on the second, and so on,
adding to the object as they go. Don't ask me to send you an example
though.
Recursive functions are also quite hard to wrap your head around. :)
Jason Merrill
Bank of America Global Learning
Learning & Performance Solutions
Join the Bank of America Flash Platform Community and visit our
Instructional Technology Design Blog
(note: these are for Bank of America employees only)
-----Original Message-----
From: [email protected]
[mailto:[email protected]] On Behalf Of Lehr,
Theodore
Sent: Friday, March 19, 2010 3:54 PM
To: Flash Coders List
Subject: [Flashcoders] Recursive:Part II
So I have this xml:
<allPeople>
<person>
<personFirstName>Bob</personFirstName>
<personLastName>Smith</personLastName>
<person>
<personFirstName>Timmy</personFirstName>
<personLastName>Smith</personLastName>
</person>
<person>
<personFirstName>Jenny</personFirstName>
<personLastName>Smith</personLastName>
</person>
</person>
<person>
<personFirstName>Tom</personFirstName>
<personLastName>Williams</personLastName>
<person>
<personFirstName>Sa</personFirstName>
<personLastName>Williams</personLastName>
</person>
</person>
To start I am just trying to recursively go through this to grab the
first names. I am trying:
createPeople(peopleXML)
function createPeople (_xml:*):void
{
var xmlList:XMLList-_xml.children();
for each (var fn_xml in xmlList) {
createChart(fn_xml);
trace(item_xml);
}
}
I am wondering - am I on the right track? Does the xml look well-formed
for doing what I am trying to do?
Thanks!
_______________________________________________
Flashcoders mailing list
[email protected]
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
_______________________________________________
Flashcoders mailing list
[email protected]
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
_______________________________________________
Flashcoders mailing list
[email protected]
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
_______________________________________________
Flashcoders mailing list
[email protected]
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
_______________________________________________
Flashcoders mailing list
[email protected]
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
_______________________________________________
Flashcoders mailing list
[email protected]
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
_______________________________________________
Flashcoders mailing list
[email protected]
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
_______________________________________________
Flashcoders mailing list
[email protected]
http://chattyfig.figleaf.com/mailman/listinfo/flashcoders