LaurenceBoyd
Mar 19, 2014
=XML[[toc]] =XML for Data storage={{[[toc]]}}==XML==XML is a flexible, convenient, way of storing data, once you understand how. Programs typically evolve thru several versions. This often results in different data items being stored. This has meant careful tracking of data version vs program versions, as programs could not correctly read data from the wrong data version. XML isaflexible as names are stored with the data. Names which are understood can be read, while others are ignored. The downside is that missing variables may require defaults. XML is a very convenient to use. The rules are quite simple. XML consists of elements: <name> text </name> Every opening <name> is paired with a closing </name). Names can be almost anything but are case sensitive. Elements can be wholly contained within otherelements: <Name1> <xyz> </xyz> </Name1>elements. Elements cannotoverlap:<Name1> <xyz> </Name1> </xyz>overlap. <name1> <XYZ> </XYZ> </name1> legal <name1> <XYZ> </name1> </XYZ> not legalfor more details visit: http://www.w3schools.com/xml/xml_syntax.asp==Saving Data==for more details visit: http://www.w3schools.com/xml/xml_syntax.asp ==Saving Data== The following example shows only the code to open and write a file. [[code format="lb"]] sub FileSaveAs filedialog "Save file", FilePath$+"*.Sudoku", FullName$ call GetFileName$ if FileName$="" then notice "No file chosen!": end call FileSave end sub sub FileSave open FullName$ for output as #File FileOpen = True #File "<XML>" #File "<!-- "; Date$();" "; Time$();" ";FullName$;" -->" 'XML comment #File " <Sudoku>" call SaveOptions call SaveCells #File " </Sudoku>" #File "</XML>" close #File FileOpen = False notice "Puzzle Saved ";chr$(13);_ "File Name ";FileName$;chr$(13);_ "at ";FilePath$ end sub sub SaveCells for row = 1 to 9: for col = 1 to 9 if CellValue(row,col) <> 0 then call SaveOneCell row, col, CellValue(row,col), CellStage(row,col) end if next col: next row end sub sub SaveOneCell row,col,value,stage #File "<Cell>";<Cell> "; #File "<Row> ";row; #File " </Row>"; #File "<Col> ";col; #File " </Col>"; #File "<Value> ";value; #File " </Value>"; if stage <> 1 then #File "<Stage> ";right$(" ";str$(stage),2); #File " </Stage>";else #File " ";end if #File"</Cell>"" </Cell>" end sub sub SaveOptions #File " <Size> ";9;" </Size>" #File " <Diagonal>"; if DiagActive then #File " On "; else #File " Off "; #File "</Diagonal>" #File " <Possible>"; if PossibleShow then #File " On "; else #File " Off "; #File "</Possible>" #File " <Reduce> "; if ReduceActive then #File " On "; else #File " Off "; #File "</Reduce>" end sub sub GetFileName$ for pos = len(FullName$) to 1 step -1 if mid$(FullName$, pos, 1) = "\" then exit for next pos FileName$ = mid$(FullName$,pos+1) FilePath$ = left$(FullName$,pos) end sub [[code]] ==Example data file:==[[code format="xml"]] <XML> <!-- Mar 12, 2014 10:56:25 C:\Data\Sudoku\3.40.88.Sudoku --> <Sudoku> <Size> 9 </Size> <Diagonal> Off </Diagonal> <Possible> Off </Possible> <Reduce> Off </Reduce><Cell><Row><Cell> <Row> 1 </Row><Col> 1 </Col><Value> 7 </Value> </Cell><Cell><Row><Cell> <Row> 1 </Row><Col> 7 </Col><Value> 9 </Value> </Cell><Cell><Row><Cell> <Row> 1 </Row><Col> 8 </Col><Value> 3 </Value> </Cell><Cell><Row><Cell> <Row> 2 </Row><Col> 4 </Col><Value> 6 </Value> </Cell><Cell><Row><Cell> <Row> 2 </Row><Col> 5 </Col><Value> 4 </Value> </Cell><Cell><Row><Cell> <Row> 2 </Row><Col> 6 </Col><Value> 7 </Value><Stage> 2</Stage></Cell> <Cell><Row> 3 </Row><Col> 1 </Col><Value> 1 </Value></Stage> </Cell><Cell><Row><Cell> <Row> 3</Row><Col> 9 </Col><Value> 7 </Value> </Cell> <Cell><Row> 4 </Row><Col> 2 </Col><Value> 6 </Value> </Cell> <Cell><Row> 4 </Row><Col> 3 </Col><Value> 8 </Value> </Cell> <Cell><Row> 4 </Row><Col> 4 </Col><Value> 5 </Value> </Cell> <Cell><Row> 4 </Row><Col> 7 </Col><Value> 7 </Value> </Cell> <Cell><Row> 5 </Row><Col> 4 </Col><Value> 3 </Value> </Cell> <Cell><Row> 5 </Row><Col> 5 </Col><Value> 8 </Value><Stage> 2 </Stage></Cell> <Cell><Row> 5 </Row><Col> 6 </Col><Value> 2 </Value> </Cell> <Cell><Row> 6 </Row><Col> 3 </Col><Value> 2 </Value> </Cell> <Cell><Row> 6 </Row><Col> 6 </Col><Value> 6 </Value> </Cell> <Cell><Row> 6 </Row><Col> 7 </Col><Value> 8 </Value> </Cell> <Cell><Row> 6 </Row><Col> 8 </Col><Value> 5 </Value> </Cell> <Cell><Row> 7</Row><Col> 1</Col><Value> 9 </Value> </Cell> <Cell><Row> 7 </Row><Col> 5 </Col><Value> 6 </Value><Stage> 2 </Stage></Cell> <Cell><Row> 7 </Row><Col> 9</Col><Value> 1 </Value> </Cell><Cell><Row> 8 </Row><Col> 4 </Col><Value> 1 </Value><Stage> 2 </Stage></Cell> <Cell><Row> 8 </Row><Col> 5 </Col><Value> 2 </Value> </Cell> <Cell><Row> 8 </Row><Col> 6 </Col><Value> 3 </Value> </Cell> <Cell><Row><Cell> <Row> 9 </Row><Col> 2 </Col><Value> 4 </Value> </Cell><Cell><Row><Cell> <Row> 9 </Row><Col> 3 </Col><Value> 1 </Value> </Cell> </Sudoku> </XML> [[code]] ==Reading XML==ReadingReading XML data is a little more work thanwrittingwriting it, but still notdificult.difficult. Since you wrote the file, you only need to be able to read what you wrote. For thisexamplecode segment, variable names with initiallettersletter capitalized are assumed to have been declared global. [[code format="lb"]] sub FileLoad filedialog "Load file...", FilePath$+"*.Sudoku", FullName$ call GetFileName$ if FileName$="" then notice "No file chosen!": end open FullName$ for input as #File FileOpen = True call ProcessFile end sub sub GetFileName$ for pos = len(FullName$) to 1 step -1 if mid$(FullName$, pos, 1) = "\" then exit for next pos FileName$ = mid$(FullName$,pos+1) FilePath$ = left$(FullName$,pos) end sub sub ProcessFile do call FindTag select case Tag$ case "<XML>" case "<Sudoku>":call InitCellArrays :call LoadPuzzle case "</XML>" :close #File: FileOpen = False end select loop until FileOpen = False end sub sub LoadPuzzle do call FindTag select case Tag$ case "<Cell>" :call LoadCell case "<Diagonal>" :DiagActive = FindContentLogic() case "</Diagonal>" case "<Possible>" :PossibleShow = FindContentLogic() case "</Possible>" case "<Reduce>" :ReduceActive = FindContentLogic() case "</Reduce>" case "<Size>" :call CheckSize case "</Size>" case "</Sudoku>" :call ShowRefresh: exit sub end select loop until FileOpen = False end sub sub LoadCell stage = 1 do call FindTag select case Tag$ case "<Row>" :row = FindContentValue() case "</Row>" case "<Col>" :col = FindContentValue() case "</Col>" case "<Value>" :val = FindContentValue() case "</Value>" case "<Stage>" :stage = FindContentValue() case "</Stage>" case "</Cell>" :CellValue(row,col) = val: CellStage(row,col) = stage exit sub end select loop until FileOpen = False end sub sub LoadInputBuffer if eof(#File) <> 0 then close #File: FileOpen = False: exit sub do until (len(InputBuffer$) > 0 ) or (eof(#File) <> 0 ) 'skip blank lines line input #File, InputBuffer$ loop end sub sub FindTag if len(InputBuffer$) = 0 then call LoadInputBuffer for i = 1 to len(InputBuffer$) if mid$(InputBuffer$, i, 1) = "<" then exit for next for j=i+1 to len(InputBuffer$) if mid$(InputBuffer$, j, 1) = ">" then exit for next Tag$ = mid$(InputBuffer$, i, j-i+1) InputBuffer$ = mid$(InputBuffer$, j+1) 'remove tag end sub function FindContentString$() for i = 1 to len(InputBuffer$) if mid$(InputBuffer$, i, 1) = "<" then exit for next FindContentString$ = trim$(mid$(InputBuffer$, 1, i-1)) InputBuffer$ = mid$(InputBuffer$, i) 'remove content end function function FindContentValue() for i = 1 to len(InputBuffer$) if mid$(InputBuffer$, i, 1) = "<" then exit for next FindContentValue = val(mid$(InputBuffer$, 1, i-1)) InputBuffer$ = mid$(InputBuffer$, i) 'remove content end function function FindContentLogic() FindContentLogic = False if FindContentString$() = "on" then FindContentLogic = True end function [[code]] 19 Mar 2014 9:14