PDA

View Full Version : Optimization advice for an XML parsing class


indivision
01-23-2005, 12:31 AM
I recently put together my first AS2.0 class system. It loads an XML file and parses it into a multi-dimensional array. It works well as-is but, given my inexperience with classes, I was hoping people could check it out and let me know if there's anything I could do to optimize it, make it more generic/useable, improve error checking, etc. Any recomendations would be greatly appreciated.

It consists of two classes (download files here: http://www.indivision.net/box/XMLKit_AS2_BETA.zip):

XMLObject.as:

/**
* XMLObject, Version 0.5 BETA
* A recursive method for converting XML into a multi-dimensional Array.
* Updates at: http://www.indivision.net
*
* @author: Joseph Miller
* Based on work by: Max Ziebell & J. Milkins
* @version: 0.5.0
*/
class XMLObject {
// The extension used to clip root of XML from return Object
private var rootVal:String = "firstChild";
//
public function XMLObject() {
}
//
//*
//* Getter for stripRoot value
//* returns true if set to strip root XML level
//*
public function get stripRoot():Boolean {
if (rootVal eq "firstChild") {
return true;
} else {
return false;
}
}
//
//*
//* Setter for stripRoot value
//*
//* @param z true or false determining whether or not root level is stripped from return Object
//* true = strip root XML level from return Object
//* false = leave return Object with root
//*
public function set stripRoot(z:Boolean):Void {
if (z eq true) {
rootVal = "firstChild";
} else {
rootVal = undefined;
}
}
//
//*
//* Checks for valid type of input Object, parses and returns Object on successful type
//*
//* @param input XML Object or String with XML formatting
//*
public function build(input:Object):Object {
var pXML:XML;
var pObj:Object = {};
if (typeof (input) eq "string") {
pXML = new XML(String(input));
} else if (input instanceof XML) {
pXML = XML(input);
} else {
trace("**Error** XMLKit.as(makeObject): Invalid or non-existent 'input' type.");
return;
}
pObj = _mxp(pXML[rootVal], {});
return pObj;
}
//
//*
//* Function resolved to if node is referred to as any Object other than an Array. Returns appropriate Array value.
//*
//* @param f Name representation of an XML node
//*
private function _mxr(f:Object) {
return this[0][f];
}
//
//*
//* Recursive method that spiders through an XML and returns a same-structured multi-dimensional Array.
//*
//* @param xObj XMLNode Object / current location in XML
//* @param obj Multi-Dimensional Array Object / current position of return Object as it is built
//*
private function _mxp(xObj:XMLNode, obj:Object):Object {
var c:Number, nName:String, nType:Number, cNode:XMLNode;
// Attributes:
// add '.attributes' to obj to extend attributes into their own Object
var oa = obj;
var xa = xObj.attributes;
for (c in xa) {
oa[c] = xa[c];
}
// Child Nodes:
for (c in xObj.childNodes) {
cNode = xObj.childNodes[c];
nName = cNode.nodeName;
nType = cNode.nodeType;
if (nType == 3) {
obj._value = cNode.nodeValue;
} else if (nType == 1 && nName != null) {
if (!(obj[nName] instanceof Array)) {
obj[nName] = new Array();
obj[nName].__resolve = _mxr;
}
var sObj:Object = _mxp(cNode, {});
obj[nName].unshift(sObj);
}
}
return obj;
}
}


XMLKit.as:

/**
* XMLKit, Version 0.5 BETA
* A loader extension for XMLObject.as. Loads an XML file into an Object and runs a callBack Function.
* Updates at: http://www.indivision.net
*
* @author: Joseph Miller
* @version: 0.5.0
*/
class XMLKit extends XMLObject {
// Constructor
public function XMLKit() {
super();
}
//
//*
//* Loads XML file, parses XML into Array Object into target Object, runs callBack Function on completion.
//*
//* @param file path to XML file or script returning XML data
//* @param target String name of Object to load parsed data into
//* @param callBack Function to run once data is loaded and parsed into target
//* @param o Object to run callBack Function on
//* @param p Array of paremeters to include with callBack Function
//*
public function load(file:String, target:String, callBack:Function, o:Object, p:Array) {
var XMLKitObj:XMLKit = this;
var myXML:XML = new XML();
myXML.ignoreWhite = true;
myXML.load(file);
myXML.onLoad = function() {
set(target, XMLKitObj.build(myXML));
callBack.apply(o, p);
};
}
}


Sample XML (test.xml):


<portfolio>
<web>
<job month="01" year="2002">
<href>http://www.nike.com</href>
<desc>this was a job for nike</desc>
</job>
<job month="04" year="2002">
<href>http://www.audi.com</href>
<desc>this job was made with Flash</desc>
</job>
</web>
<print>
<job id="test_id_feature" month="14" year="2003">
<desc>A flyer</desc>
</job>
</print>
</portfolio>


And code from the fla to test:


//
xmlString = '<portfolio attr="test"><web><job month="01" year="2002"><href>http://www.nike.com</href><desc>this was a job for nike</desc></job><job month="04" year="2002"><href>http://www.audi.com</href><desc>this job was made with Flash</desc></job></web><print><job id="test_id_feature" month="14" year="2003"><desc>A flyer</desc></job></print></portfolio>';
//
//portfolio = new XMLObject().build(xmlString);
new XMLKit().load("test.xml", "portfolio", testXML);
//
//testXML();
//
function testXML() {
trace("XMLNode.makeXMLSA EXAMPLES\n");
trace("direct access on values:");
trace("\tportfolio.web.job.href._value = "+portfolio.web.job.href._value);
trace("\tportfolio.web.job[0].href._value = "+portfolio.web.job[0].href._value);
trace("\tportfolio.web.job[1].href._value = "+portfolio.web.job[1].href._value);
trace("\nnow in a loop over jobs in web:");
for (var c = 0; c<portfolio.web.job.length; c++) {
trace("\tportfolio.web.job["+c+"].href._value = "+portfolio.web.job[c].href._value);
}
trace("\ndirect access on attriubtes:");
trace("\tportfolio.web.job.year = "+portfolio.web.job.year);
}

bmilesp
02-26-2007, 12:28 AM
Indivision, thank you for creating this simple and easy to understand example for an XML parser class. I spent a long time searching the web for a classes that i can easily understand, especially example wise, and yours was the only one that i could copy and paste and start working with immediately. Big (BIG!) ups and thanks again.