XML

XML in Flash CS mbv. actionscript v3.0 laden

We gebruiken in deze les een XML-bestand om een Flashmovie van data te voorzien. Je zou deze XML ook kunnen genereren d.m.v. een PHP pagina, die de data uit een SQL database haalt. Dit valt dit jaar buiten de scope van de lessen.

Een XML-bestand lezen in Flash

Wanneer we een XML bestand willen inlezen zijn er een aantal stappen nodig. Als eerste moeten we een XML bestand laden. Eigenlijk moeten we weten wanneer het XML bestand helemaal geladen is, want je kan niks met half ingelanden data. Dit lijkt ingewikkeld, maar de ingebouwde classes helpen aardig.

Kijk eerst even naar de code die nodig is om een XMLbestand in te lezen. Dit lijkt erg veel op het inladen van een gewoon tekstbestand:

var xmlLoader:URLLoader = new URLLoader(); 
var xmlData:XML = new XML(); 
  
xmlLoader.addEventListener(Event.COMPLETE, LoadXML); 
  
xmlLoader.load(new URLRequest("sampleXML.xml")); 
  
function LoadXML(e:Event):void { 
	xmlData = new XML(e.target.data); 
	trace(xmlData);
}

Als je de bovenstaande code in je ActionScript scherm plakt op frame 1 kun je de Movie testen middels Ctrl + Enter. Als het goed is zie je dan de inhoud van het XMLbestand in je Output venster. Je moet dan natuurlijk wel een XML bestand hebben, wat in dezelfde map is opgeslagen als waar je FLA file staat. Zorg er dus ook voor dat aan deze voorwaarden is voldaan.

Nu je weet dat het werkt kunnen we de code nader gaan bekijken en begrijpen hoe het XMLbestand in het geheugen word geladen:

var xmlLoader:URLLoader = new URLLoader(); 
var xmlData:XML = new XML();

In deze twee regels declareer je twee variable genaamd xmlLoader en xmlData. De xmlLoader variable is van het type URLLoader, deze class helpt je om data te laden van een exterene bron zoals een URL. de xmlData variable is van het type XML en de XML class biedt een hoop mogelijkheden om XML data te raadplegen en te manipuleren.

xmlLoader.addEventListener(Event.COMPLETE, LoadXML); 

Met deze regel koppelen we een eventListener aan ons xmlLoader object. Het event (Event.COMPLETE), roept de functie LoadXML aan. Omdat er gewacht word voor het COMPLETE event zorgen we ervoor dat er pas met de data gewerkt kan worden als de totale data geladen is.

xmlLoader.load(new URLRequest("sampleXML.xml")); 

Je kunt een XML document hier ophalen om mee te testen, je kunt deze ook zelf maken.
De load method wordt alleen voorzien van een URLRequest object als argument. Omdat je data download van het internet gebeurt dit stukje voor stukje als stream. De URLRequest class zorgt ervoor dat alle data in z'n geheel geladen word, zodat alle XML data in een keer binnen komt.

function LoadXML(e:Event):void { 
	xmlData = new XML(e.target.data); 
	trace(xmlData);
}

De LoadXML functie wordt alleen aangeroepen als de xmlLoader het sein COMPLETE krijgt. En dat gebeurt alleen als de data via de load method helemaal geladen is.

De LoadXML functie heeft een argument van het type Event genaamd e, dit argument bevat data die gerelateerd is aan het event van het URLLoader object.
Je kunt de data ophalen via e.target.data

Als laatste word alle data opgeslagen in ons XML object xmlData.
Alle XML data word zo bewaard in je geheugen.


XML in Flash direct uitlezen

Voor de verdere stappen is onderstaande XML gebruikt.

 

Vervang de bestaande LoadXML functie met het volgende:

function LoadXML(e:Event):void {
	xmlData = new XML(e.target.data);
	ParseBooks(xmlData);
}
 
function ParseBooks(bookInput:XML):void {
	trace("XML Output");
	trace("------------------------");
	trace(bookInput);
}

De functie ParseBooks is nieuw en heeft een XML object als argument. De LoadXML functie is aangepast en roept nu de functie ParseBooks aan en heeft het xmlData object als argument.

Door nu een woord toe te voegen aan de trace(bookInput) regel kunnen we de diverse tags uitlezen b.v:

trace(bookInput.Book);

of

trace(bookInput.Book.author);

Om alleen de inhoud te krijgen van de XML elementen kunnen we de functie text() toevoegen.

trace(bookInput.Book.author.text());

Alle namen komen zo achter elkaar zonder ruimte er tussen. Als je dit anders wil kun je werken met index posities zoals hier:

trace(bookInput.Book.author.text()[0]);

XML in Flash indirect uitlezen

Indirekt uitlezen gebeurt via loops. Op deze manier kun je precies de informatie krijgen die je wilt.
Een belangrijke class naast de XML class heet XMLList. Een verzameling XML informatie wordt altijd gegeven als een XMLList. Deze kunnen alleen XML objecten bevatten.

De volgende code is gebruikt om alle author informatie op te halen. Binnen deze ParseBooks functie word gebruik gemaakt van een loop.

function ParseBooks(bookInput:XML):void {
	trace("XML Output");
	trace("------------------------");
	var authorList:XMLList = bookInput.Book.author;

	for (var i:int = 0; i < authorList.length(); i++){
		var authorElement:XML = authorList[i];
		trace(authorElement);
	}
}

Als eerste word het object authorList gemaakt van het type XMLList. het word ook gevuld met alle schrijvers middels; bookInput.Book.author.

Met .length() kunnen we kijken hoeveel elementen de XMLList class bevat.
authorElement is een XML class en word telkens opnieuw voorzien van een author uit de lijst.

Calling all Children()

Als je de namen niet weet van de nodes die je zoekt, kan je de meer generieke children() functie gebruiken. Deze functie geeft alle children van een node weer in de vorm van een XMLList. Als je eenmaal de XMLList hebt kan je de data naar believen gebruiken .

In dit voorbeeld is te zien hoe je middels een loop, de children van een node kunt uitlezen.

function ParseBooks(bookInput:XML):void {
	trace("XML Output");
	trace("------------------------");
	var bookChildren:XMLList = bookInput.Book.children();
	for each (var bookInfo:XML in bookChildren) {
		trace(bookInfo);
	}
}

Je kunt deze informatie ook weer filteren d.m.v. een if constructie toe te voegen.
De loop ziet er dan zo uit:

for each  (var  bookInfo:XML  in bookChildren)  {
	if (bookInfo.name() == "author") {
		trace(bookInfo);
	}
}

De functie .name() geeft dus de naam van de XMLtag.

Attributes lezen

de eerste methode werkt op een soort gelijke manier als children().
Zie hieronder hoe de functie attributes() gebruikt wordt:

function ParseBooks(bookInput:XML):void {
	trace("XML Output");
	trace("------------------------");
	var bookAttributes:XMLList = bookInput.Book.attributes();
	for each (var bookISBN:XML in bookAttributes) {
		if (bookISBN.name() == "ISBN") {
			trace(bookISBN);
		}
	}
}

De tweede methode is om bij het vullen van de XMLList class direkt een specifiek attribute te gebruiken.

function ParseBooks(bookInput:XML):void {
	trace("XML Output");
	trace("------------------------");
	var bookAttributes:XMLList = bookInput.Book.attribute("ISBN");
	for each (var bookISBN:XML in bookAttributes) {
		trace(bookISBN);
	}
}

Hier word de functie attribute() gebruikt, dus zonder s.

 


LESOPDRACHT

Maak een eenvoudige XML parser zoals hierboven voor je in de vorige les gemaakte RSS feed.
Maak hierbij gebruik van de Flash UI compoments:

Werkwijze

Plaats bovenin de stage (700 x 400) de UI TextInput (width: 550) en geef deze de instance naam url

Plaats daarnaast een UI Button (width: 100) en noem deze but. Plaats de tekst go! op de button.

Plaats daar onder 2 andere components naast elkaar.

Links maak je een UI List (260 x 320) met als instance naam li

Rechts daarvan plaats je een UI TextArea (385 x 325) met als instance naam ta

Na invullen van de url van de in te lezen rss feed in de textinput, ga je mbv. de go! button de List vullen. Als de List is gevuld, ga je door klikken op het betreffende listitem de bijbehorende desciption ophalen en plaatsen in de TextArea.

Structuur en tips

  1. vars
    1. maak een globale variabele loader voor het URLLoader object
  2. events
    1. maak een eventlistener op de loader (Event.COMPLETE)
    2. maak een eventlistener op de List (Event.CHANGE)
      Op een List kun je geen CLICK event gebruiken om de TextArea te vullen. Dit doe je mbv. een CHANGE event.
    3. maak een eventlistener op de Button (Event.CLICK)
  3. functions
    1. maak een functie laad voor het laden van het rss document
    2. maak een functie onLoaded voor het lezen van het rss document. Via een for loop kun je hier meteen de List vullen . Het rss document breng je onder in de functie variabele xml:
      var xml = new xml(e.target.data);
      De ListItems breng je onder in de functie variabele il van het type XMLList:
      var il:XMLList = xml.channel.item;
    3. maak een functie itemChange waarbij de TextArea wordt gevuld. Je maakt hierbij de inhoud van de textarea (ta.htmlText) gelijk aan lb.selectedItem.data