Solved

Display one XML item at a time using AS3

Posted on 2011-03-03
7
623 Views
Last Modified: 2013-11-11
Hi I am working on displaying XML data in Flash using AS3.

 I have the code working correctly: it pulls data from the external file, displays the items from the XML tag 'abstract' like I want, and creates a movie clip in which to display each of the 'abstract' items.

What I am trying to do is change my for loop to display one of the 'abstract' items sequentially. I think I could figure it out if someone would help me to display the first item by itself. If I change the [ i ] to [ 0 ] in the abstractText variable below, I get the first entry, but it is displayed as many times as there are 'abstract' entries (due to my not knowing how to edit the loop statement of numberOfAbstracts variable.

Any help would be greatly appreciated.

	     var numberOfAbstracts = xmlData.results.news_item.abstract.length();
for(var i:Number = 0;i<numberOfAbstracts;i++){

	             var abstractString:String = xmlData.results.news_item.abstract.toString();
				 var abstractText:String = xmlData.results.news_item[i].abstract.text();

	             var myText1:TextField = new TextField();
	             myText1.text = abstractText;

		                     var clip_mc = new MovieClip();
							 // Add the rectangle graphic
		                     clip_mc.addChild(rect);
							 // Add the text fields
		                     clip_mc.addChild(myText1);
		                     addChild(clip_mc);		
}
}

Open in new window

0
Comment
Question by:Dojay
  • 4
  • 3
7 Comments
 
LVL 10

Expert Comment

by:Carnou
ID: 35033707
I think you're getting the number of abstracts wrong.
Try changing your first line to:

var numberOfAbstracts = xmlData.results.news_item.length();

If that doesn't solve everything, post a sample of your xml, and we can walk you through getting the data correctly.
0
 

Author Comment

by:Dojay
ID: 35033789
That gives me the same results. I've posted some of the XML below.

There's no problem getting the data - I would just like to load each instance of 'abstract' one at a time.
Right now I get a list of all instances, or if I change the abstractText to call a specific instance, I get duplicates of that one instance.


<results>
-
<news_item>
<section>Sports</section>
-
<title>
Greg Goossen, Baseball Player Who Broke Mold, Dies at 65
</title>
-
<abstract>
The young prospect never lived up to expectations, but he still figured in some memorable moments in baseball history.
</abstract>

Open in new window

0
 
LVL 10

Expert Comment

by:Carnou
ID: 35033821
The way your code was originally written, getting length() of xml_data.results.news_item.abstract would return the number of abstracts per news item.  However, in line 5, you're iterating through each news_item instead of each abstract.  Which do you want?

Do you have the ability to see trace statements?  It will help you get what you want from the XML properly.
If you can trace, try adding the following after line 5:
trace( abstractString );
trace( abstractText );
trace( xml_data.results.new_item[i].abstract.toString() );
trace( xml_data.results.new_item[i].abstract[0].toString() );
trace();

Open in new window


This should print out 5 lines per item that you're iterating through.  One of the five might be what you want.  If not, post all the trace information and tell me what you're not seeing but you do want.
0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 

Author Comment

by:Dojay
ID: 35040780
If I use something like this I can isolate what I want, a single entry:

trace( xmlData.results.news_item[0].abstract[0].toString() );

Open in new window


but because I have this in a for loop it first counts all the 'abstract' entries, then renders the first entry for all of them. In this case, the same entry 20 times.

There must be code, possibly a for each statement, that would allow me to render each entry, complete the function of creating the movie clip, THEN move onto the next entry. I want to display them one at a time.

I think I have the hierarchy in the code wrong, or maybe I don't need a loop that iterates through all the entries. Do I need to create a variable for each entry? Then apply a function to each? Sorry  I'm not versed in the AS3 order of things.
0
 
LVL 10

Expert Comment

by:Carnou
ID: 35040883
This is why I've been asking you to post a sample of your xml.  I needed to know how many abstracts you were expecting per news item.  If you give me an xml, I can easily make a loop for you.  At the worst, you need a nested loop.

I'm going away for the weekend, but this should be enough to get you going.

If you only have one abstract per news item, your loop should look like this:

This will loop through each news_item and give you the first (only) abstract.  You need the two sets of brackets because each . in an xml extraction returns an XmlList.  By putting a 0, you get the first item.  If it's the only item, you're fine.

var numberOfItems = xmlData.results.news_item.length();
for(var i:Number = 0;i<numberOfItems;i++)
{
  var abstractString:String = xmlData.results.news_item[i].abstract[0].toString();
  var myText1:TextField = new TextField();
  myText1.text = abstractString;

  var clip_mc = new MovieClip();
  clip_mc.addChild(rect);
  clip_mc.addChild(myText1);
  addChild(clip_mc);		
}

Open in new window


If you have multiple abstracts per news_item, you would want to loop through each abstract for each item:
var numberOfItems = xmlData.results.news_item.length();
for(var i:Number = 0;i<numberOfItems;i++)
{
  var numberOfAbstracts = xmlData.results.news_items[i].abstract.length();
  for(var j:Number = 0;j<numberOfAbstracts;j++)
  {
    var abstractString:String = xmlData.results.news_item[i].abstract[j].toString();
    var myText1:TextField = new TextField();
    myText1.text = abstractString;

    var clip_mc = new MovieClip();
    clip_mc.addChild(rect);
    clip_mc.addChild(myText1);
    addChild(clip_mc);		
  }
}

Open in new window

0
 

Author Comment

by:Dojay
ID: 35061394

In the XML, there is only one abstract per news item.

I was able to display a single entry  using the following

for(var i:Number = 0;i<1;i++){

 var abstractOne:String = xmlData.results.news_item[0].abstract[0].text();

	             var myText1:TextField = new TextField();
	             myText1.text = abstractOne.toUpperCase();

Open in new window


then rendering that into a movie clip. However, in order to cycle through each abstract and display them one at a time, I may have to use a nested loop similar to your second code entry above. What would be your suggestion? I'm basically trying to loop through all of them, display one item, then move on to the next. The function should include all of the text formatting and rendering into a movie clip
0
 
LVL 10

Accepted Solution

by:
Carnou earned 125 total points
ID: 35061625
You do realize that you don't need a for loop for what you did, right?  By counting from 0 to 1, you'll only go through it once.

The nested loop I showed you will only get you through each abstract of each news item.

Next question for you next problem - what do you mean by "display one item, then move on to the next"?  Do you want to move on after a certain amount of time, or do you want the user to click a next button?  Either way, you need some event listening - whether to a timer event or to a mouse click event.  The basic structure is the same:

Instead of declaring your variable in the for loop, declare it in global scope.  You're going to need to track your counter variable
Put your display code in an event listener, and call this event on initial xmlfile load and every time the event fires.

Here's the basic look:
// this variable keeps track of what news_item you're displaying
var results_index:int = 0;

// ...

// This function should be called any time you want to display the next news_item
// It can accept an Event, which lets it be an event handler, but setting it to null tells AS3 it's not required.
function showNewItem( var e:Event = null ):void
{
  var abstractOne:String = xmlData.results.news_item[results_index].abstract[0].text();
  ++results_index;
  // Here, if you're hitting the last news item, I'm looping around to the first.  You could also just 
  // put a "return;" inside this if so it will stop on the last
  if (++results_index >= xmlData.results.new_item.length())
  {
    results_index = 0;
  }
  var myText1:TextField = new TextField();
  myText1.text = abstractOne.toUpperCase();
  // ... whatever else you have your code doing.  Boy it's so much easier to help when I can actually see all of it!
}

Open in new window


I would make a "next" button in your movie clip.  You could add an event listener to a button named NextButton in myMovieClip like this:
myMovieClip.NextButton.addEventListener( MouseEvent.CLICK, showNewItem );

Open in new window

Then, anytime the user clicks on the button, the function I wrote above will run.

Once you have your xml file loaded and saved into xmlData, you'll also want to call this function to display things:
showNewItem();

Open in new window


Good luck!
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Sometimes you know that one object has a specific child in it, but you can't find the child. This happened to me when I was trying to code some actionScript to make a toolbar work with its embedded buttons.  My partner had created the toolbar usi…
This article describes a solution to a problem of subloading one movie into another when they have different SWF versions. Sometime back, I was working on an ActionScript project while I came across an interesting fact which I would like to share…
In this tutorial viewers will learn how to create a basic motion tween animation in Flash Open a new document in Flash: Draw/import an image: Press CTRL + F8 to convert it into a graphic symbol: Select a frame (how long you want the tween to last): …
The goal of the tutorial is to teach the user how to use the auto adjust feature and what the different options do. When your video is not working right you can choose the auto adjust feature to help choose your settings.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now