Author Topic: XML & Binary Tree routine  (Read 1450 times)

MrTAToad

  • Guest
XML & Binary Tree routine
« on: 2010-Sep-24 »
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

Code: (glbasic) [Select]
// --------------------------------- //
// 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