' /* 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