The following code reads in XML and puts it into a binary array based tree.
The main problem is that I cant determine whether the attributes & values should be where they are, and the fact that searching for anything is inefficient.
Both generally work on their own, but storing the XML data needs to be better
// --------------------------------- //
// Project: TestXML
// Start: Thursday, September 23, 2010
// IDE Version: 8.085
// FREE-VERSION:
// Need Premium for Features:
// 3D Graphics
// Network Commands
// INLINE C/C+++ code
// SETCURRENTDIR("Media") // seperate media and binaries?
TYPE txmlNode
Name$
AttributeCount%
AttributeName$[]
AttributeValue$[]
Contents$
Parent%
Level%
ChildCount%
ENDTYPE
TYPE TXML
opened%
xml_ItemType%
nodes[] AS txmlNode
MAX_SIZE% = 8192
FUNCTION xmlLoad%:FileName$
LOCAL attribute$[]; DIM attribute$[64]
LOCAL value$[]; DIM value$[64]
LOCAL handle%,stacklevel%,length%,i%,attr%,parent%,index%
LOCAL tag$,name$
LOCAL tree AS TTree
LOCAL node AS txmlNode
LOCAL NumNodesUsed%
//LOCAL currentNode AS t
// LOCAL nodestack[PARSER_RECURSE]
// LOCAL rootnode
// DebugLog "Loading XML file: " + FileName
// xml_ClearErrors()
// begintime = MilliSecs()
// Open the file
DIM self.nodes[self.MAX_SIZE%]
FOR i%=0 TO self.MAX_SIZE%-1
self.nodes[i%].Level%=-1
NEXT
self.opened%=FALSE
NumNodesUsed%=0
handle%=GENFILE()
IF handle%<0
DEBUG "Unable to retrieve a file handle"
RETURN FALSE
ENDIF
IF OPENFILE(handle%,FileName$,1)=FALSE
DEBUG "Unable to open file"
CLOSEFILE handle%
RETURN FALSE
ENDIF
stacklevel%=0
tag$=self.xml_NextItem$(handle%)
WHILE ENDOFFILE(handle%)=FALSE
IF tag$ <> ""
IF self.xml_ItemType% = 2
// Node contents
DEBUG "Allocate!"
//KEYWAIT
//xmlNodeDataSet(nodestack[stacklevel - 1], Trim(Trim(xmlNodeDataGet(nodestack[stacklevel - 1])) + " " + Trim(tag)))#
ELSE
IF LEFT$(tag$,1) = "/"
// Closing tag
DEC stacklevel%
//tmp.xmlNode = Object.xmlNode(nodestack[stacklevel])
//IF tag$ <> "/" + tmp\Name THEN xml_AddError("Unclosed tag (found <"+tag+">, expected </"+tmp\Name+">", FilePos(file))
ELSE
// Get the name AND attributes from the tag
FOR i%=0 TO 63
attribute$[i%]=""
value$[i%]=""
NEXT
self.opened%=FALSE
attr%=0
name$=""
length%=LEN(tag$)
FOR i%=0 TO length%-1
LOCAL ch$
ch$=MID$(tag$,i%,1)
IF attr%=0 AND ch$=" " THEN INC attr%
DEBUG tag$+" "+attr%+"\n"
IF ch$="=" THEN attr%=0-attr%
IF ch$=CHR$(34)
IF attr%>0 THEN DEBUG "Expecting equal symbol (=)"
IF self.opened%
self.opened%=FALSE
ELSE
self.opened%=TRUE
ENDIF
IF self.opened%=FALSE
attr%=ABS(attr%)
INC attr%
ENDIF
ENDIF
IF ch$<>CHR$(34) AND attr%<0 AND self.opened%
value$[ABS(attr%)]=value$[ABS(attr%)]+ch$
ENDIF
IF attr%=0
name$=name$+ch$
ELSE
IF attr%>0 AND ch$<>CHR$(34) AND ch$<>" "
attribute$[attr%]=attribute$[attr%]+ch$
ENDIF
ENDIF
NEXT
//DEBUG "Name : "+name$+"\n"
// Create a New node
IF stacklevel% > 0
parent%=stacklevel%-1
ELSE
parent%=0
ENDIF
// Traverse through the tree to find the end
index%=0
WHILE index%<self.MAX_SIZE% AND self.nodes[index%].Level%<>-1
IF stacklevel%>self.nodes[index%].Level%
index%=(index%*2)+2
ELSE
index%=(index%*2)+1
ENDIF
WEND
IF index%<self.MAX_SIZE%
DEBUG "Name : "+name$+" Attributes : "+attr%+"\n"
self.nodes[index%].Name$=name$
self.nodes[index%].AttributeCount%=attr%
self.nodes[index%].Parent%=parent%
self.nodes[index%].Level%=stacklevel%
DIM self.nodes[index%].AttributeName$[attr%]
DIM self.nodes[index%].AttributeValue$[attr%]
FOR i%=0 TO attr%-1
self.nodes[index%].AttributeName$[i%]=attribute$[i%]
self.nodes[index%].AttributeValue$[i%]=value$[i%]
DEBUG self.nodes[index%].AttributeName$[i%]+"\n"
NEXT
ELSE
DEBUG "Out of array space for tree list\n"
ENDIF
INC NumNodesUsed%
KEYWAIT
IF RIGHT$(tag$,1) = "/"
// Stand-alone tag
ELSE
// Opening tag
INC stacklevel%
ENDIF
ENDIF
ENDIF
ENDIF
tag$=self.xml_NextItem$(handle%)
WEND
CLOSEFILE handle%
ENDFUNCTION
FUNCTION xml_NextItem$:file%
LOCAL tag$,txt$
LOCAL ch%
txt$=""
tag$=""
WHILE ENDOFFILE(file%)=FALSE
READBYTE file%,ch%
IF txt$<>"" AND (ch%=60 OR ch%=13)
self.xml_ItemType%=2
FILESEEK file%,FILEPOSITION(file%)-1,0
RETURN txt$
ENDIF
IF ch%<>13 AND ch%<>15 AND ch%<>10 THEN txt$=txt$+CHR$(ch%)
IF ch%=13 AND txt$<>"" THEN txt$=txt$+" "
IF ch%=60
IF self.opened%=TRUE THEN DEBUG "Expecting closing bracket (>)"
self.opened%=TRUE
ENDIF
IF ch%=62
txt$=""
IF self.opened%=FALSE THEN DEBUG "Expecting opening bracket (<)"
self.opened%=FALSE
IF LEFT$(tag$,4)="<!--" OR LEFT$(tag$,2)="<?"
IF LEFT$(tag$,4)="<!-_" AND RIGHT$(tag$,2)<>"--" THEN DEBUG "Expecting correct comment closure (-->)"
IF LEFT$(tag$,4)="<?" AND RIGHT$(tag$,2)<>"?>" THEN DEBUG "Expecting correct header closure (?>)"
tag$=""
ELSE
self.xml_ItemType%=1
RETURN RIGHT$(tag$,LEN(tag$)-1)
ENDIF
ENDIF
IF self.opened% THEN tag$=tag$+CHR$(ch%)
WEND
RETURN ""
ENDFUNCTION
FUNCTION xml_GetValue$:name$,attribute$
LOCAL loop%,loop2%
FOR loop%=0 TO self.MAX_SIZE%-1
IF self.nodes[loop%].Level%>=0
DEBUG "1:"+self.nodes[loop%].Name$+" "+name$+"\n"
IF self.nodes[loop%].Name$=name$
FOR loop2%=0 TO self.nodes[loop%].AttributeCount%-1
DEBUG "2:("+self.nodes[loop%].AttributeName$[loop2%]+") ("+attribute$+")\n"
IF self.nodes[loop%].AttributeName$[loop2%]=attribute$
RETURN self.nodes[loop%].AttributeValue$[loop2%]
ENDIF
NEXT
ENDIF
ENDIF
NEXT
RETURN ""
ENDFUNCTION
ENDTYPE