Groups | Blog | Home
all groups > flash actionscript > january 2007 >

flash actionscript : I have one little question about associative arrays...


mloncaric
1/4/2007 8:50:28 PM
HI!

I'm creating one simple custom class, which will get data from xml...

The idea is to create fully dinamical class which will get data from xml file
and named every part of array with the attributes, and fill it with its
content...
...hope that make sense...

For example:
part of xml file:
title="sample 1"

part of class code:
for (var j in nodes[i].attributes)
{
content.push({j:nodes[i].attributes[j]});
}
...variable "j" gets the name from the current attribute, inside the current
item(nodes[i].attributes) in the xml file...so I'm using it as a identifier of
the current part of array...
I get the value from the current attributes value(nodes[i].attributes[j])...

At the end I'm adding them to the content
array(content.push({j:nodes[i].attributes[j]}))...

I really hope you understand, what am I trying to say...

...But when I trace the content(I've tried adding the identifiers to its
end('...].title' or something similar))...
I allways get [object Object] or unidentified...

If you have any idea how to do that, please tel me...
...or if it's even possible...

Thanks in advance...

This is my code so far:


import mx.utils.Delegate;

class com.mloncaric.LoaderXML
{

public var onError:Function;

private var xml:XML;
private var numOfItems:Number;
private var container:Array;

public function LoaderXML()
{

}

public function loadXML(targetXML:String):Void
{
this.xml = new XML();
this.container = new Array();
this.xml.ignoreWhite = true;
this.xml.onLoad = Delegate.create(this, onLoadXML);
this.xml.load(targetXML);
}

private function onLoadXML(success:Boolean):Void
{
if (success)
{
var nodes:Array = xml.firstChild.childNodes;
numOfItems = nodes.length;

var content:Object = new Object();

for (var i:Number = 0; i<numOfItems; i++)
{
for (var j in nodes[i].attributes)
{
trace(j+":"+nodes[i].attributes[j]);
content.push({j:nodes[i].attributes[j]});
}

id.shift();
value.shift();
}
}
else
{
onError("Error on loading XML file!");
}
}
}


And in main movie:
Code:

import com.mloncaric.*;

var lxml:LoaderXML = new LoaderXML();

lxml.loadXML("LoaderXML.xml");

lxml.onError = function(error:String):Void
{
trace(error);
}


The sample xml code:
Code:

<?xml version="1.0" encoding="UTF-8"?>

<items>
<item
title="sample 1"
content="sample content 1"
source="sample1.jpg"
/>

<item
title="sample 2"
content="sample content 2"
source="sample2.jpg"
/>
</items>
LuigiL
1/5/2007 3:01:15 PM
var content:Object = new Object();
should be:
var content:Array = new Array();
because you can't use push() on an Object.
Then you can trace with:
trace(content[0].j);//traces 1
and you are just pushing every single attribute as an object in the array. Not
very usefull.

To start you off:
To parse xml you might want to use XMLObject.as by Alessandro Crugnola (I've
attached the class). Using that class you can create an object of your xml.
I've written an example for you.
In the example I use LoadXML to load the xml file and then use XMLObject to
create an object of the xml. In your xml I've wrapped the items in a data tag
so you can add other nodes (like <config></config> that can contain information
about your setup) to the xml. See the parsing routine in LoadXML where I use a
switch to parse different nodes in the xml.
Once the xml has loaded and is parsed, the class broadcasts an event to
subscribed objects - in the example the class SlideShow.as which is a wrapper
class that instructs LoadXML to load the xml, receives the event and then
starts loading the images (not implemented, it just traces a message at this
point). The example should give you a good picture how you do this. Hope this
helps.



/**
* LoadXML, Version 1
* Class to load and parse a xml file.
* The content of the xml file is saved to
* an object.
* Uses EventDispatcher to signal other
* objects the xml has fully loaded.
*
* Dependencies: XMLObject.as
*
* @author: Peter Lorent, 2006
* @version 1.0.0
*/

//import packages
import mx.events.EventDispatcher;
import com.mloncaric.XMLObject;

class com.mloncaric.LoadXML {

//class definition
//save the content
private var content_obj:Object;
//path to the xml file
private var xmlpath_string:String;

private var dispatchEvent:Function;
public var addEventListener:Function;
public var removeEventListener:Function;

//class body
//constructor
/**
* Initializes the new instance and inits EventDispatcher.
*
*/
public function LoadXML(){
EventDispatcher.initialize(this);
}

//public methods
/**
* Sets the path to the xml file and inits the load.
*
* @param xmlpath String. The path to the xml file.
*/
public function main(xmlpath:String):Void{
if(xmlpath==undefined){
//set a default path
xmlpath_string="config.xml";
} else {
xmlpath_string=xmlpath;
}
//init the content_obj
content_obj=new Object();
//load the xml
loadContent();
}

/**
* Get all content. Returns the content_obj
*
*/
public function getContent():Object{
return content_obj;
}

//private methods
/**
* Loads the xml file. Once the xml file has fully loaded
* the function calls a function to parse the xml.
*
*/
private function loadContent():Void{
var thisObj:LoadXML=this;
var content_xml:XML=new XML();
content_xml.ignoreWhite=true;
content_xml.onLoad=function(success:Boolean){
if(success){
if ((this.firstChild.nodeName=="data")){
for(var i=0;i<this.firstChild.childNodes.length;i++){
switch(this.firstChild.childNodes[i].nodeName){
case "items":
trace("Items found");
thisObj.parseItems(this.firstChild.childNodes[i]);
break;
}
}
}
} else {
trace("Error parsing the items.");
}
}
//trigger the load
//local
content_xml.load(xmlpath_string);
//live (prevent getting the content from the cache of the browser)
//content_xml.load(xmlpath_string+"?ck="+new Date().getTime());
}

/**
* Parses the xml file. Once the xml is parsed
* the function sends a message to subscribed objects.
*
*/
private function parseItems(node:XML):Void{
//use XMLObject to parse the xml
var xml_loader:XMLObject=new XMLObject();
content_obj=xml_loader.parseXML(node);
//our event object
var contentEvent:Object={target:this,type:'contentLoaded',param:content_obj};
//dispatch the event
dispatchEvent(contentEvent);
}

}

//XMLObject.as

/**
* @author Alessandro Crugnola
* @version 1.1
*/
class com.mloncaric.XMLObject extends XML {

private var oResult:Object;
private var oXML:XML;

/**
* Parse an XML string into a flash object. If allarray param is passed,
everything
* will be pushed into array, even if an XMLNode contains only 1 node.
Otherwise 1 node elements
* will be parsed into single object, and multiple nodes into arrays.
* @usage xmlobj.parseXML( xmlstring, true );
* @param xmlinput XML string
* @param allArray if set to true will put all nodes into an array, even if
a single childNode
* @return Object representing the XML
*/
public function parseXML( xmlinput:XML, allArray:Boolean):Object
{
if(allArray == undefined){
allArray = false;
}
this.oResult = new Object();
this.oXML = xmlinput;
this.oResult = this.translateXML(null,null,null,null,allArray);
return this.oResult;
}

/**
* Transform a Flash Object into An XML
* @usage new XMLObject().parseObject( object, 'root_name')
* @param obj object to be parsed
* @param name name of the first root element
* @return xml
*/
public function parseObject( obj:Object, name:String ):XML
{
var tempXML:XML = new XML("<?xml version=\"1.0\"?>");
var rootNode:XMLNode = tempXML.createElement(name);
var returnedNode = this.translateObject( obj, tempXML, rootNode)
rootNode.appendChild(returnedNode);
tempXML.appendChild(rootNode);
return tempXML;
}

private function translateObject( obj:Object, tempXML:XML, parentNode:XMLNode
)
{
var node:XMLNode
switch(obj.__proto__){
case Array.prototype:
var firstVal = obj.shift()
this.translateObject(firstVal, tempXML, parentNode);
for(var a in obj){
node = parentNode.cloneNode(false)
parentNode.parentNode.appendChild(node)
this.translateObject(obj[a], tempXML, node);
}
break
case Object.prototype:
for(var a in obj){
if(a == "attributes"){
this.parseAttributes(obj[a], parentNode)
} else {
node = tempXML.createElement(a)
parentNode.appendChild(node)
this.translateObject(obj[a], tempXML, node);
}
}
break
case String.prototype:
case Boolean.prototype:
case Number.prototype:
case Date.prototype:
default:
var textNode = tempXML.createTextNode( obj.toString() );
parentNode.appendChild(textNode);
break
}
return parentNode
}

private function parseAttributes(obj:Object,parentNode:XMLNode){
for(var a in obj){
parentNode.attributes[a] = obj[a]
}
}

/**
*
* @usage
mloncaric
1/5/2007 4:12:45 PM
mloncaric
1/5/2007 4:43:24 PM
....Hm...

mloncaric
1/5/2007 4:46:01 PM
Ok sorry, my bad...

I didn't replaced my existing xml code with yours...

Now it works!

LuigiL
1/5/2007 4:58:55 PM
AddThis Social Bookmark Button