ActionScript RSS Title issue - actionscript-3

The below AS# RSS reader code pull the titles from the RSS items but seem to include the XML markup as well. How does one not include the XML markup without using Regex or string replace?
import flash.text.TextField;
import flash.text.TextFormat;
import flash.net.URLLoader;
import flash.events.IOErrorEvent;
//Read RSS feeds
var RSS_xmlData: XML = new XML();
var xmlLoader: URLLoader = new URLLoader();
xmlLoader.addEventListener(Event.COMPLETE, LoadXML);
xmlLoader.load(new URLRequest("http://www.oshawa.ca/news_rss.asp"));
function LoadXML(e:Event):void {
dtext.text="Loading...";
RSS_xmlData = new XML(e.target.data);
pullFeed(RSS_xmlData);
}
function pullFeed(rss: XML):void {
var str: String="";
str = rss.channel.item.title;
str = str.replace(/\s*\n/g," | ");
//str = str.replace(/'/g,"\"");
//// shows specific entry
var items: Array = new Array();
items = str.split("|");
var tf: TextField = dtext;
var i:Number=0;
var myTimer:Timer = new Timer(4000,1000);
myTimer.addEventListener(TimerEvent.TIMER, timerListener);
function timerListener (e:TimerEvent):void{
tf.text = items[i].toString();
scaleTextToFitInTextField(tf);
i = i < items.length - 1 ? i + 1 : 0;
}
myTimer.start();
}
function scaleTextToFitInTextField(txt: TextField):void {
var f: TextFormat = txt.getTextFormat();
f.size = (txt.width > txt.height) ? txt.width : txt.height;
txt.setTextFormat(f);
while (txt.textWidth > txt.width - 4 || txt.textHeight > txt.height - 6) {
f.size = int(f.size) - 1;
txt.setTextFormat(f);
}
}
function onIOError(e:IOErrorEvent):void
{
trace(e.toString());
dtext.text="Finding Feed...";
}
Thanks for any help with this.

The reason you're getting the XML markup in there is because the value returned by rss.channel.item.title is of type XMLList, corresponding to all the <title> nodes matched by that selection - rather than just the text content of those nodes. As you've noted, it's rather backwards to convert that to a String and then strip out the extraneous mark-up manually.
I would iterate over all the <item> nodes and add their <title> content to the array as you go along. The new pullFeed method would then look like:
function pullFeed(rss: XML):void {
var items:Array = new Array(); //Declare Array of titles
var numItems:int = rss.channel.item.length(); //Capture number of <item> nodes
for (var i:int = 0; i < numItems; i++) {
items.push(String(rss.channel.item[i].title)); //Add each <item>'s <title> to the Array
}
var tf: TextField = dtext;
var i:Number=0;
var myTimer:Timer = new Timer(4000,1000);
myTimer.addEventListener(TimerEvent.TIMER, timerListener);
function timerListener (e:TimerEvent):void{
tf.text = items[i];
scaleTextToFitInTextField(tf);
i = i < items.length - 1 ? i + 1 : 0;
}
myTimer.start();
}
One other benefit of iterating through the XML nodes this way is that you could easily capture the <description> or <pubDate> content of each <item> on the same pass through the XML, if you planned to make use of that later.

Related

RSS gallery as3

Here is my case - I have 10 movie clips on the view and in every movie clip I need to have a loaded picture that RSS. I've managed to get the first one loaded but I need the other 9 as well. Any ideas?
import com.adobe.xml.syndication.generic.FeedFactory;
import com.adobe.xml.syndication.generic.IFeed;
import com.adobe.xml.syndication.generic.IItem;
import flash.display.MovieClip;
import flash.events.MouseEvent;
var rss:XML;
var rss_url:URLRequest = new URLRequest("http://btvnews.bg/lbin/rss.php?section_id=16105?pic_size=300x158");
var rssLoader:URLLoader = new URLLoader(rss_url);
rssLoader.addEventListener(Event.COMPLETE, rssLoaded);
var rssCount;
var rssCounter = 0;
var l = new Loader();
var loaderContext:LoaderContext;
loaderContext= new LoaderContext();
loaderContext.securityDomain=SecurityDomain.currentDomain;
loaderContext.checkPolicyFile = true;
Security.loadPolicyFile('http://img.bg.sof.cmestatic.com/crossdomain.xml');
function rssLoaded(e:Event):void
{
rss = XML(rssLoader.data);
var curImage = rss.channel.item[0].enclosure. # url;
l.load(new URLRequest(curImage));
l.contentLoaderInfo.addEventListener(Event.COMPLETE,doneIt);
function doneIt(e:Event)
{
var bit:Bitmap = e.target.content;
if (bit != null)
{
bit.smoothing = true;
}
}
placer.addChild(l);
After your rss load as you have loaded one images put a for loop for the item
for(var i=0; i < rss.channel.item.length;i++)
{
var img = rss.channel.item[i].enclosure. # url;
//rest of the code to load the image and adding to stage
}

Creating an ActionScript 3 RSS looping feed

I have the following AS3 code so far. What I need to do is have this code continually loop the feed it is consuming. Any solutions?
import flash.text.TextField;
import flash.text.TextFormat;
import flash.net.URLLoader;
import flash.events.IOErrorEvent;
//Read RSS feeds
var RSS_xmlData: XML = new XML();
var xmlLoader: URLLoader = new URLLoader();
xmlLoader.addEventListener(Event.COMPLETE, LoadXML);
xmlLoader.load(new URLRequest("http://www.oshawa.ca/news_rss.asp"));
function LoadXML(e:Event):void {
dtext.text="Loading...";
RSS_xmlData = new XML(e.target.data);
}
function pullFeed(rss: XML):void {
var str: String="";
str = rss.channel.item.title;
str = str.replace(/\s*\n/g," | ");
str = str.replace(/'/g,"\"");
//// shows specific entry
var items: Array = new Array();
items = str.split("|");
var tf: TextField = dtext;
var i:Number=0;
var myTimer:Timer = new Timer(4000,items.length);
myTimer.addEventListener(TimerEvent.TIMER, timerListener);
function timerListener (e:TimerEvent):void{
tf.text = items[i].toString();
scaleTextToFitInTextField(tf);
i++;
}
myTimer.start();
}
function scaleTextToFitInTextField(txt: TextField):void {
var f: TextFormat = txt.getTextFormat();
f.size = (txt.width > txt.height) ? txt.width : txt.height;
txt.setTextFormat(f);
while (txt.textWidth > txt.width - 4 || txt.textHeight > txt.height - 6) {
f.size = int(f.size) - 1;
txt.setTextFormat(f);
}
}
function onIOError(e:IOErrorEvent):void
{
trace(e.toString());
dtext.text="Finding Feed...";
}
I have tried a while loop, a for loop and a timer reset and restart but none appear to enable me to continually loop the feed.
Thanks
Reset your counter when you've finished iterating over your array:
function timerListener (e:TimerEvent):void{
tf.text = items[i].toString();
scaleTextToFitInTextField(tf);
// Reset counter to 0 when we've been all the way through the array
i = i < items.length - 1 ? i + 1 : 0;
}

Match two strings from a text file and user input? (AS3)

I was able to load a text file in a Flash file, but I am unable to match two strings from a text file and the user input.
The purpose of this AS3 code: to match the text file and user input, and if it matches, the score will increase by 1. Else, the score will increase by 0.
Here is my code:
var uScore :Number = 0;
stop();
var textLoader:URLLoader = new URLLoader();
var textURLRequest:URLRequest = new URLRequest("q1.txt");
textLoader.addEventListener(Event.COMPLETE, completeHandler);
function completeHandler(event:Event):void
{
var textData:String = new String(textLoader.data);
dy1.text = textData;
}
textLoader.load(textURLRequest);
function goURL(event:MouseEvent):void {
var textLoader2:URLLoader = new URLLoader();
var textURLRequest2:URLRequest = new URLRequest("answer1.txt");
var textData2:String = new String(textLoader2.data);
var name1 = trace(textData2);
textLoader2.load(textURLRequest2);
var myURL = url1.text;
if(myURL == name1){
uScore += 1;
uScoreURL.text = uScore+"";
nextFrame();
}
else{
uScore+=0;
uScoreURL.text = uScore+"";
nextFrame();
}
}
trace(uScore);
You code has a strange assignment:
var name1 = trace(textData2);
replace it with
var name1 =textData2;
it should work then if there isn't a bug in some other place.
And you don't need to uScore+=0;. Just delete it.
I checked out your code, you were doing a few things out of order - here is the revised code that should get you where you need to be
var uScore :Number = 0;
stop();
var textLoader:URLLoader = new URLLoader();
var textURLRequest:URLRequest = new URLRequest("q1.txt");
textLoader.addEventListener(Event.COMPLETE, completeHandler);
function completeHandler(event:Event):void
{
var textData:String = new String(textLoader.data);
dy1.text = textData;
}
textLoader.load(textURLRequest);
btn.addEventListener(MouseEvent.CLICK,getNumber);
var textLoader2:URLLoader = new URLLoader();
textLoader2.addEventListener(Event.COMPLETE, completeHandler2);
function completeHandler2(event:Event):void
{
var textData2:String = new String(textLoader2.data);
var name1 = textData2;
trace(name1);
var myURL = url1.text;
if(myURL == name1){
uScore += 1;
uScoreURL.text = uScore+"";
nextFrame();
}
else{
uScore+=0;
uScoreURL.text = uScore+"";
nextFrame();
}
}
function getNumber(event:MouseEvent){
var textURLRequest2:URLRequest = new URLRequest("answer1.txt");
textLoader2.load(textURLRequest2);
}
trace(uScore);
The only thing that I really added that you didn't have is a button with the variable name btn to check the answer - you can rework that to however you want to check for the answer.

Error joining AS2 with AS3

I have problems joining two scripts into one.
This is main part of the script: AS3.
And this is already joined script.
And here is part of the code that I need to import (AS2) :
stop();
var banners:Array = new Array();
var imagePaths:Array = new Array();
var links:Array = new Array();
var bodyTexts:Array = new Array();
var imageTime:Number;
var numberOfBanners:Number;
var isRandom:String;
var showHeader:String;
var bannersXML:XML = new XML();
bannersXML.ignoreWhite = true;
bannersXML.load("banners.xml");
bannersXML.onLoad = function(success) {
if (success) {
trace("XML LOADED");
imageTime = parseInt(this.firstChild.firstChild.firstChild)*1000;
numberOfBanners = parseInt(this.firstChild.childNodes[1].firstChild);
isRandom = this.firstChild.attributes["isRandom"];
showHeader = this.firstChild.childNodes[2].attributes["showHeader"];
var bannerSequence:Array = new Array();
if (isRandom == "true") {
//Make a random sequence
while (bannerSequence.length<numberOfBanners) {
newRandomNumber = random(numberOfBanners);
//Make sure that the random one chosen is not already chosen
for (var i = 0; i<=bannerSequence.length; i++) {
if (newRandomNumber != bannerSequence[i]) {
alreadyThere = false;
} else {
alreadyThere = true;
break;
}
}
//Add only random values that aren't in the array
if (!alreadyThere) {
bannerSequence.push(newRandomNumber);
}
}
} else {
for (var i = 0; i<numberOfBanners; i++) {
bannerSequence.push(i);
}
}
}
//Read XML in the Random Order Chosen
for (var i = 0; i<numberOfBanners; i++) {
banners.push(this.firstChild.childNodes[2].childNodes[bannerSequence[i]].firstChild.firstChild.toString());
bodyTexts.push(this.firstChild.childNodes[2].childNodes[bannerSequence[i]].childNodes[1].firstChild.nodeValue);
imagePaths.push(this.firstChild.childNodes[2].childNodes[bannerSequence[i]].childNodes[2].firstChild.nodeValue);
links.push(this.firstChild.childNodes[2].childNodes[bannerSequence[i]].childNodes[3].firstChild.nodeValue);
}
play();
};
//Start the image counter at 0
var imageCounter = 0;
I get erorr in this part of the code
function doRandArray(a:Array):Array {//make random array
var nLen:Number = a.length;
var aRand:Array = a.slice();
var nRand:Number;
var oTemp:Object;
for (var i:Number = 0; i < nLen; i++) {
oTemp = aRand[i];
nRand = i + (random(nLen – i));
aRand[i] = aRand[nRand];
aRand[nRand] = oTemp;
}
return aRand;
}
When I run it, I get an error in this place:
nRand = i + (random(nLen – i));
Scene 1, Layer 'Layer 1', Frame 1, Line 265 1084: Syntax error: expecting rightparen before i.
as2 random(random(nLen – i)); is generate 0,1,...nLen-i-1. not floating only int value.
correct as3 code is int(Math.random()*(nLen-i)); or Math.floor(Math.random()*(nLen-i));
as2: random()
as3: Math.random()
In ActionScript 3 the random function is a little bit different from what it was in as2 code, just change the offending line to:
nRand = i + Math.random()*(nLen-1);
This should fix all errors and work just the same.
EDIT: as #bitmapdata.com indicated, for this to run the same as in as2 the random value must be truncated (stripped of its decimal values). Besides the couple of possibilities he suggested, I would personally just change nRand's type to uint on declaration:
var nRand:uint;
You can also change the iterator type to var i:uint. Less memory usage is always good ;)

AS3 Adobe AIR: Return xml string

I'm working in Flash CS6 with Adobe AIR 3.3 (for iOS) and having trouble returning an XML string to a textField.
It is tracing the proper information, and I've tried a few ways to return the trace but can't seem to quite get it... Here is my most recent try. Any suggestions? Thanks in advance.
var myLoader:URLLoader = new URLLoader();
myLoader.load(new URLRequest("http://www.someURL.php"));
//php file that echos xml
myLoader.addEventListener(Event.COMPLETE, init);
var fadedText:TextField;
var touchList:TouchList;
var textOutput:TextField;
var animateLeft:Tween;
var listArray:Array;
var item:TouchListItemRenderer;
var theXML:XML;
var days:Array = new Array("monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday");
var daySelected;
var businessNameArray:Array = new Array();
var businessLogoArray:Array = new Array();
var businessAddress:Array = new Array();
var distanceArrayDisplay:Array = new Array();
var distanceArrayCount = 0;
function init(e:Event = null):void
{
trace(myLoader.data);
theXML = new XML(e.target.data);
theXML.ignoreWhitespace = true;
myLoader.close();
// add our list and listener
var itemSizeCalculator = stage.stageHeight / 6;
touchList = new TouchList(stage.stageWidth, stage.stageHeight-itemSizeCalculator);
touchList.addEventListener(ListItemEvent.ITEM_SELECTED, handlelistItemSelected);
addChild(touchList);
touchList.x = stage.stageWidth;
// Fill our list with item rendreres that extend ITouchListRenderer.
for(var i:int = 0; i < theXML.food.length(); i++) {
if(theXML.food[i].monday != "un")
{
item = new TouchListItemRenderer();
item.index = i;
item.data = theXML.food[i].business;
item.name = theXML.food[i].business;
item.addEventListener(MouseEvent.CLICK, itemWasClicked);
item.itemHeight = itemSizeCalculator;
businessNameArray[i]= theXML.food[i].business;
businessLogoArray[i]=("http://www.logosURL.com/"+theXML.food[i].logo);
businessAddress[i]= theXML.food[i].address;
var fadedTextFormat:TextFormat = new TextFormat();
fadedTextFormat.bold = true;
fadedTextFormat.color = 0x999999;
fadedTextFormat.size = 14;
fadedTextFormat.font = "Helvetica";
fadedText = new TextField();
fadedText.height = 30;
fadedText.mouseEnabled = false;
fadedText.defaultTextFormat = fadedTextFormat;
item.addChild(fadedText);
fadedText.x = 75;
fadedText.y = 10;
distanceArrayDisplay.push(fadedText);
var distanceLoader:URLLoader = new URLLoader();
distanceLoader.load(new URLRequest("http://maps.googleapis.com&origins=someAddress&destinations="+businessAddress[i]+"&mode=walking&language=en-en&sensor=false"));
distanceLoader.addEventListener(Event.COMPLETE, distanceCalculated);
var logoLoader:Loader = new Loader();
item.addChild(logoLoader);
var logoURL:URLRequest = new URLRequest("http://www.myLogos.com/"+theXML.food[i].logo);
logoLoader.load(logoURL);
logoLoader.scaleX = .4;
logoLoader.scaleY = .4;
logoLoader.y = logoLoader.y + 5;
logoLoader.mouseEnabled = false;
var arrowGraphic:rightArrow = new rightArrow();
item.addChild(arrowGraphic);
arrowGraphic.x = stage.stageWidth - 5;
arrowGraphic.y = item.height/2;
touchList.addListItem(item);
}
}
}
function distanceCalculated(e:Event)
{
// trace(e.currentTarget.data);
var distanceXML:XML = new XML(e.target.data);
distanceXML.ignoreWhitespace = true;
var returnVar:String = (distanceXML.row.element.distance.text);
distanceArrayDisplay[distanceArrayCount].text = returnVar;
trace(returnVar);
distanceArrayCount++;
}
I am guessing that you are correctly reading the first XML, and that XML has a list of URLs that you want to load and then display some info from those on TextFields. Without knowing the structure of that XML I can't suggest you any working code, but I can point you on the right direction. For more info on reading/iterating XML on flash as3, please read: http://www.kirupa.com/developer/flashcs3/using_xml_as3_pg1.htm
//iterator var
var xml_read:uint=0;
//array of textfields for reference
var array_textFields:Array;
//config XML complete
function init(e:Event = null):void
{
array_textFields = new Array();
theXML = new XML(e.target.data);
theXML.ignoreWhitespace = true;
//this depends on the XML structure, please look at the article I linked
//for more info on how to iterate an XML
var i:uint=0;
for(someUrl in theXML..url)
{
var fadedText:TextField = new TextField();
//you should place each Textfield on different coord, otherwise
//they will all stack on top of each other and you will only see one
//for example:
fadedText.y = (fadedText.height+10)*i;
item.addChild(fadedText);
array_textFields.push(fadedText);
var distanceLoader:URLLoader = new URLLoader();
distanceLoader.load(new URLRequest(someUrl));
distanceLoader.addEventListener(Event.COMPLETE, distanceCalculated);
i++;
}
}
function distanceCalculated(e:Event):void
{
var distanceXML:XML = new XML(e.target.data);
distanceXML.ignoreWhitespace = true;
//retrieve information
var returnVar:String = (distanceXML.row.element.distance.text);
//set to textfield
TextField(array_textFields[xml_read]) = returnVar;
//increase iterator
xml_read++;
}
Please bear in mind that in ActionScript3, all network I/O is asynchronous. Usually EventListener functions don't return any value because you don't know when the data is ready. What you do is store a reference to where you want the data to go (in your case, a TextField variable) when the EventListener function is called asynchronously.