Scripting in AS2 is a hassle for sorting and node ordering because of it's limit of 256 loop branches or jumps per 'frame' of 'video' (fps). So, to get around that I just wrote a callback that freezes after counting how many branchings happened. I modulated the number until it always worked and it isn't perfect or incredibly fast like a compiled code module would be in C++ but it works, and you can see the inner workings of XML to an Object Model Node.
http://www.supercala.net/tuts/xml_oop/gallery.zip
Here is the code for now:
loadXML2.as
XML Loader function
Code: Select all
//loadXML2.as by kristoffe brodeur
//v2.0 01-11-2007
//----------
function loadXML(lX_targetObj)
{
trace("[loadXML]("+lX_targetObj.filename+")");
lX_targetObj.onLoad=function(success)
{
//success is a binary function; positive on a good load
if(success)
{
tF_debug.text+="XML loaded.";
//this refers to the onLoad parent, dataXML, which is the actual XML data
//therefore, onLoad is just an attribute and fucntion of the main object dataXML
//tF_debug.text+=newline+"data:"+lX_targetObj;
lX_targetObj.loadAction();
}//if
}//f()
lX_targetObj.ignoreWhite=true;
lX_targetObj.load(lX_targetObj.filename);
}//f()
Code: Select all
#include "../../../createMovieClip2.as"
#include "../../../loadXML2.as"
#include "../../../deepClone3.as"
#include "../../../DispTree.as"
//#include "../arrayFunctions.as" removed to get rid of unnecessary array functions
//-----
//09-15-2008 parse xml v2 by Kristoffe Brodeur. ©2008 All Rights Reserved.
//10-27-2008 adding object->xml for output back to normal xml parsing and php output
//10-30-2008 added T1.AP['cn'] to list the child node XML nodes that a parent object would have, saves wasted looping later in conversion
//03-01-2009 making the output very clear, clean, and a Class
//03-04-2009 rewrote entire Back2XMl for proper branch searching and optimal speed
//-----
Back2XML.prototype.stackChk=function()
{
//trace("stackChk>");
len=this.nodeStack.length;
tgt=this.nodeStack[len-1];
tgt.pos++;
//loop
if(tgt.pos<tgt.cnt)
{
//trace("cnt "+tgt.cnt+" | "+tgt.pos);
//array of node names
if(tgt.bNode.cn!=undefined)
{
//trace("cn=true");
nN=tgt.bNode.cn[tgt.pos];
this.AP=tgt.bNode[nN];
//
if(tgt.pos>0)
{
nN_prev=tgt.bNode.cn[tgt.pos-1];
this.xmlStr+="</"+nN_prev+">";
}
this.stackAdd();
}
//array of object nodes
else
{
tgt2=this.nodeStack[len-2];
this.AP=tgt.bNode[tgt.pos];
nN=tgt2.bNode.cn[tgt2.pos];
//
if(tgt.pos>0)
{
this.xmlStr+="</"+nN+">";
}
//trace("cn=false");
this.xmlStr+="<"+nN+">";
//trace("**"+this.xmlStr);
this.stackAdd();
}
}
//pop stack or add text string
else
{
//trace("end of loop.");
//
if(tgt.cnt!=undefined)
{
//
if(tgt.bNode.cn!=undefined)
{
nN=tgt.bNode.cn[tgt.pos-1];
//trace("CN!");
this.xmlStr+="</"+nN+">";
//trace(this.xmlStr);
}
//
else
{
//this.xmlStr+="</#>";
}
this.nodeStack.pop();
}
//
else
{
//trace("textual node.");
this.xmlStr+=this.AP.DATA
//this.xmlStr+="</"+this.AP.ID+">";
//trace(this.xmlStr+newline);
this.nodeStack.pop();
}
//
if(this.nodeStack.length>0)
{
this.stackChk();
}
//
else
{
//trace("END.");
trace(this.xmlStr);
this._caller.outputAction(this.xmlStr);
}
}
}
//-----
Back2XML.prototype.stackAdd=function()
{
//trace("stackAdd>");
len=this.nodeStack.length;
//
if(this.AP.cn!=undefined)
{
tgt=this.nodeStack[len]=new Object();
tgt.cnt=this.AP.cn.length;
tgt.pos=-1;
tgt.bNode=this.AP;
//trace("nN["+len+"]---->"+"cn[A]("+this.AP.cn+") cnt "+tgt.cnt+" | pos "+tgt.pos);
this.stackChk();
}
//
else
{
tgt=this.nodeStack[len]=new Object();
tgt.cnt=this.AP.length;
tgt.pos=-1;
tgt.bNode=this.AP;
//trace("nN["+len+"]---->obj[A] cnt "+tgt.cnt+" | pos "+tgt.pos);
this.stackChk();
}
}
//-----
Back2XML.prototype.init=function()
{
//trace("init>");
this.AP=_XML;//array pointer
this.recursion=0;
clearArray(this.nodeStack);
this.AP=_XML;//defined outside as an Object that the XML file is OOP parsed into
this.xmlStr="";
this.stackAdd();
}
//-----
//same as arrayFunctions2.as clearArray
function clearArray(sArr)
{
lenSA=sArr.length;
//
for(clrA=0;clrA<lenSA;clrA++)
{
sArr.pop();
}
}
//-----
function Back2XML(sCaller)
{
this._caller=sCaller;
//trace("Back2XML>");
this.nodeStack=new Array();
this.init();
}
//-----
function done_sort()
{
trace("done_sort>");
trace("--------------------");
this.parseAction();
/*
T1.tmp1=new DeepClone();
//pushCopy(base array,node to copy,new node to copy to,should new text nodes be clear?)
T1.tmp1.pushCopy(_XML.db[0].branch,0,null,null);
T1.tmp1.cloneAction=function()
{
trace("cloning complete!");
//E1=new DispTree(_XML);
test1=new Back2XML();
}
T1.tmp1.go();
//show_videos();
//T1.test=new Back2XML();
trace("--------------------");
//Btest=new DispTree(_XML);
*/
}
//-----
function coolDown()
{
T1.recursion=-1;
T1.recPause=new TimerA(T1.root,11);
T1.recPause.timerAction=function()
{
//trace("DONE!");
incr_stack1();
}
}
//-----
function check_recursion()
{
//trace("check_recursion>");
T1.recursion++;
//
if(T1.recursion>25)
{
//trace("cooling down");
coolDown();
}
else{incr_stack1();}
}
//-----
function node_pop()
{
//remove selected node
//trace("node_pop>");
}
//-----
function node_push(sBase,sNode)
{
//duplicate selected node
//trace("node_push>");
//trace(sBase);
//trace(sNode);
T1.cloned=new DeepClone(sBase,sNode,null,"push");
T1.cloned._par=T1.root;
T1.cloned.cloneAction=function()
{
//trace("finished node_push.");
this._par.cloneAction();
}
T1.cloned.go();
}
//-----
function Node(sName,sData)
{
this.ID=sName;
this.DATA=sData;
}
//-----
function addObjNode()
{
cnt=T1.nodeStack.length;
nName=T1.nodeStack[cnt-1];//0 counts in an array, so cnt-1 is the position of the end node
nExist=false;
//
if(T1.AP[nName]==undefined)
{
T1.AP[nName]=new Array();
}
//
else
{
nExist=true;
}
if(T1.AP['cn']==undefined){T1.AP['cn']=new Array();}//holds xml node names in parent
cnt=T1.AP[nName].length;
T1.AP[nName][cnt]=new Node(nName,"");
//T1.AP['cn'].push(nName);
//
if(nExist==false)
{
T1.AP['cn'].push(nName);
}
//
//only the first node parent doesnt have an ID or DATA
begN="<"+nName+">";
//trace(begN);
T1.stringXML+=begN;
T1.AP.chi_pnt=T1.AP[nName][cnt];
parPtr=T1.AP;
T1.AP=T1.AP[nName][cnt];
T1.AP.par_pnt=parPtr;
}
//-----
function addTextNode()
{
tgt=T1.xPtr.childNodes[T1.xPtr.pos];
text1=tgt.nodeValue;
//trace(text1);
text1fix="";
tl=text1.length;
for(i=0;i<tl;i++)
{
c1=text1.substr(i,1);
//
if(c1=="&")
{
text1fix+="&";
}
else
{
text1fix+=c1;
}
}
cnt=T1.nodeStack.length;
nName=T1.nodeStack[cnt-1];
//T1.AP already points to the new node in the dynamic array one step previous when called and made in addObjNode
cnt=T1.AP[nName].length;
T1.AP.DATA=text1fix;
T1.stringXML+=text1fix;
}
//-----
function decr_stack1()
{
//trace("decr_stack1>");
//
if(T1.nodeStack.length>0)
{
endX="</"+T1.nodeStack[T1.nodeStack.length-1]+">";
//trace(endX);
T1.stringXML+=endX;
}
T1.nodeStack.pop();
T1.xPtr=T1.xPtr.par_pnt;
T1.AP=T1.AP.par_pnt;
incr_stack1();
}
//-----
function change_pointer()
{
//trace("change_pointer>");
//
if(T1.xPtr.pos<T1.xPtr.cnt)
{
//trace("changing...");
par1=T1.xPtr;
T1.xPtr=T1.xPtr.childNodes[T1.xPtr.pos];
T1.xPtr.par_pnt=par1;
check_recursion();
}
}
//-----
function incr_stack2()
{
//trace("incr_stack2>");
cnt=T1.xPtr.childNodes.length;
//trace(cnt);
//
if(T1.xPtr.pos==undefined)
{
T1.xPtr.pos=-1;//start at -1 so it will roll to 0 with ++
T1.xPtr.cnt=cnt;//how many children are there?
}
T1.xPtr.pos++;
//
if(T1.xPtr.pos<T1.xPtr.cnt)
{
//trace(T1.xPtr.pos);
pos=T1.xPtr.pos;
nName=T1.xPtr.childNodes[pos].nodeName;
//
if(nName!=null)
{
//trace("?"+nName);
T1.nodeStack.push(nName);
addObjNode();
//trace("added");
change_pointer();
}
else
{
addTextNode();
decr_stack1();
}
}
else{decr_stack1();}
}
//-----
function incr_stack1()
{
//trace("incr_stack1>");
len=T1.xPtr.childNodes.length;
//
if(len>0){incr_stack2();}
//
else{
stackPos=T1.nodeStack.length;
//
if(stackPos>0){decr_stack1();}
//
else{done_sort();}
}
}
//-----
function parse_XML()
{
trace("f(parse_XML)");
T1.stringXML="";
T1.recursion=0;
T1.nodeStack=new Array();
T1.xPtr=T1.e_XML;
incr_stack1(T1.xPtr);
}
//-----
function l_XML()
{
trace("f(l_XML)");
T1.e_XML=new XML();
T1.e_XML.filename=T1.filename;
T1.e_XML.loadAction=function(){parse_XML();}
loadXML(T1.e_XML);
}
//-----
function main(sFilename)
{
T1.filename=sFilename;
tF_debug.text="main>"+sFilename;
//trace("main>"+sFilename);
T1.XML_ok=false;
delete T1.AP;
delete T1.root._XML;
T1.root._XML=new Object();
T1.AP=_XML;
l_XML();
}
//-----
var T1=new Object();
T1.root=this;
//trace("parser ready. send the *.xml filename to main(*); to begin.");
//main("ev1.xml");
//main("branchtest.xml");