' /* This is simple demonstration of how to use expat. This program
' reads an XML document from standard input and writes a line with the
' name of each element to standard output indenting child elements by
' one tab stop more than their parent element. */
$NOMAIN
' ENUM
' TYPE_ELEMENT = 0
' TYPE_ATTRIBUTE
' END ENUM
' Type XmlData
' idx
' key$
' value$
' End Type
' GLOBAL UD as XmlData
'GLOBAL DYNAMIC FileName$[10]
' search for text files - find the first file
' A$ = FINDFIRST$(APPEXEPATH$ + mask$)
' WHILE A$ > ""
' tmpYear$ = TRIM$(LEFT$(A$, 4)) 'get year from filename
' IF tmpYear$ = Year$ THEN 'make sure it's the correct year file
' tmpVar$ = RIGHT$(A$, LEN(A$)-4) 'remove the year from the string
' FileName$[count] = tmpVar$ 'add filename to array
' IF cnt = 0 THEN REDIM PRESERVE FileName$[count+10] : cnt = 0
' count++ : cnt++
' END IF
' find the rest
' A$ = FINDNEXT$
' WEND
' FREE DYNAMIC FileName$
#INCLUDE "C:\Program Files\Expat 2.0.1\Source\lib\expat.h"
$LIBRARY "libexpat.lib"
CONST BUFFSIZE = 8192
GLOBAL parser AS XML_Parser
GLOBAL MaxEleArray
GLOBAL TmpEleArray
'GLOBAL MaxAtrArray
'GLOBAL TmpAtrArray
GLOBAL ElementCnt
GLOBAL AttributeCnt
FUNCTION main(ARGC, ARGV AS char PTR PTR)
DIM RAW Buff[BUFFSIZE] AS char
DIM TimerStart, TimerEnd, TotalTime
DIM fname$
GLOBAL DYNAMIC EArray$[1]
'GLOBAL DYNAMIC AArray$[1]
GLOBAL EleText$ * 2048
GLOBAL AtrText$ * 2048
ElementCnt = 0 'keep a count of the elements. eg. element
AttributeCnt = 0 'keep a count of the attributes. eg.
TmpEleArray = 0
'TmpAtrArray = 0
MaxEleArray = 256
REDIM EArray$[MaxEleArray+1]
fname$ = GETFILENAME$("Load XML File","XML Files (*.xml)|*.xml")
IF NOT *fname$ THEN
PRINT "Unable to open xml file"
END = 1
END IF
OPEN BCXSPLITPATH$(fname$, FNAME|FEXT) FOR INPUT AS FP1
TimerStart = TIMER
'create a parser
parser = CreateParser()
'set a pointer to the SciStyle TYPE
'as the first parameter to startElement
'and endElement (userData AS void PTR)
' XML_SetUserData (parser, &UD)
'call the expat parser to do the work
IF NOT Parse(parser, FP1) THEN
Print "Parsing failed"
END = 1
END IF
CLOSE FP1
TimerEnd = TIMER
TotalTime = TimerEnd - TimerStart
PRINT "Total Number of Elements (keys) = " + STR$(ElementCnt--)
PRINT "Total Number of Attributes = " + STR$(AttributeCnt--)
PRINT "Total Time for parse = " + STR$(TotalTime)
'just what it says...
XML_ParserFree (parser)
FUNCTION = 0
END FUNCTION
SUB PushElement(element$)
ElementCnt++
TmpEleArray++
IF TmpEleArray >= MaxEleArray THEN
MaxEleArray = MaxEleArray + 256 'Increase array size in increments of 256
REDIM PRESERVE EArray$[MaxEleArray+1]
END IF
'print ""
print "MaxEleArray = " + STR$(MaxEleArray)
IF *element$ THEN
EArray$[TmpEleArray] = element$
'IF *EArray$[TmpEleArray] THEN print "Array out = " + EArray$[TmpEleArray]
END IF
print "TmpEleArray index = " + STR$(TmpEleArray)
IF parser THEN print "Current line number: " + STR$(XML_GetCurrentLineNumber(parser))
print ""
END SUB
FUNCTION PopElement$()
IF *EArray$[TmpEleArray] THEN FUNCTION = EArray$[TmpEleArray]
FUNCTION = ""
END FUNCTION
'SUB PushAttribute(element$)
' AttributeCnt++
' TmpAtrArray++
' IF TmpAtrArray >= MaxAtrArray THEN
' MaxAtrArray = MaxAtrArray + 256 'Increase array size in increments of 256
' REDIM PRESERVE AArray$[MaxAtrArray+1]
' END IF
' AArray$[MaxAtrArray] = element$
'END SUB
'FUNCTION PopAttribute$()
'DIM s$
's$ = "Attribute: " + AArray$[MaxAtrArray]
' s$ = AArray$[MaxAtrArray]
' IF *AArray$[MaxAtrArray] THEN
'AIndex--
'IF AIndex < 0 THEN AIndex = 0
' FUNCTION = s$
' END IF
' FUNCTION = ""
'END FUNCTION
SUB startElement (userData AS void PTR, aname AS LPCCH, atts AS const char PTR PTR)
DIM numAttr, i
DIM s$
REDIM AtrText$ * LEN((CHAR*)aname$) + 1
AtrText$ = aname$
IF *AtrText$ THEN PushElement(AtrText$)
IF *AtrText$ THEN FREE AtrText$
'find out if there are any attributes
numAttr = XML_GetSpecifiedAttributeCount(parser)
IF numAttr > 0 THEN 'send to the attribute handler function
FOR i = 0 TO numAttr - 1 STEP 2
IF *atts$[i] THEN
's$ = atts$[i] + " = " + atts$[i+1]
'PushAttribute(s$)
END IF
'PRINT PopAttribute$()
NEXT i
END IF
END SUB
SUB charData(userData AS void PTR, s AS const XML_Char PTR, length)
REDIM EleText$ * length + 1
strncpy(EleText, s, length)
IF *EleText$ THEN
IF LEN(PopElement$()) THEN
'PRINT PopElement$() + " = " + TRIM$(EleText$)
END IF
END IF
IF *EleText$ THEN FREE EleText$
END SUB
SUB endElement (userData AS void PTR, aname AS LPCCH)
'PopElement()
END SUB
FUNCTION CreateParser() AS XML_Parser
DIM RAW p AS XML_Parser
p = XML_ParserCreate(NULL)
IF NOT p THEN
PRINT "Couldn't allocate memory for parser"
EXIT FUNCTION
ELSE
XML_SetElementHandler(p, startElement, endElement)
XML_SetCharacterDataHandler(p, charData)
FUNCTION = p
END IF
FUNCTION = 0
END FUNCTION
FUNCTION Parse(p AS XML_Parser, FP AS FILE) AS BOOL
DIM Buff[BUFFSIZE] AS CHAR
DO
DIM RAW done
DIM RAW length
length = (int)fread(Buff, 1, BUFFSIZE, FP)
done = CBOOL(length < BUFFSIZE)
IF XML_Parse(p, Buff, length, done) = XML_STATUS_ERROR THEN
PRINT "Parse error at line " , XML_GetCurrentLineNumber(p), _
" Error code: ", XML_ErrorString$(XML_GetErrorCode(p))
FUNCTION = FALSE
END IF
LOOP WHILE NOT done
FUNCTION = TRUE
END FUNCTION