Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Re: Control Functions and Functionals in Rebol

From: joel:neely:fedex at: 17-May-2001 19:19

Hi, Charlie, Charles Wardell wrote:
> Does anyone have an example on how to open an xml file and > iterate through the elements using parse-xml or something. > > Thanks, > Charlie >
Here's a sample xml file: 8<------------------------------------------------------------ <test date="17-May-2001" author="Joel Neely"> <desktop color="brown"> <computer mfg="HP" model="Vectra" /> <computer mfg="Compaq" mode="Presario" /> <coffeecup level="0.5" /> </desktop> <floor color="green"> <chair fabric="blue" rolling="yes"> <myself name="Joel" /> </chair> <filingcabinet drawers="4" /> <trashcan liner="yes"> <stickynote color="pink"> somebody else's unreadable handwritten scribbled message... </stickynote> </trashcan> </floor> </test> 8<------------------------------------------------------------ Note: the goofy spacing is *NOT* recommended XML style! I just put it in to demonstrate that the functions below are working correctly. PARSE-XML translates each XML element into a block of length 3. The first item is the element's (tag's) name as a string. The second is a block of attribute data (name/value pairs) or NONE if there were no attributes. The third is a block holding all of the element's content or NONE if the element was an empty element. All content strings (including whitespace between tags!) are shown in the content block of the appropriate element. The entire document is represented by a similar block; the name is replaced with the word! DOCUMENT , there are no attributes, and the content has a single element block for the root element of the document. The DUMP-XML-BLOCK function produces a structured display of the "raw" internal format, with attribute blocks as blocks and all the ignorable-whitespace intact. The DUMP-XML function re-renders the internal format as XML, cleaned up and consistently indented. The TRIM-XML function cleans up an internal block structure, deleting ignorable-whitespace content and eliminating empty content blocks if nothing but ignorable-whitespace was there. A console transcript illustrates DUMP-XML-BLOCK and DUMP-XML at work, using the above xml document. 8<------------------------------------------------------------
>> doc: parse-xml read %test.xml
== [document none [["test" ["date" "17-May-2001" "author" Joel Neely ] ["^/ " ["desktop" ["color" "brown"] ["^/ " ["computer" ...
>> xu: do %xml-utils.r >> xu/dump-xml-block doc
document none [ "test" ["date" "17-May-2001" "author" "Joel Neely"] [ "^/ " "desktop" ["color" "brown"] [ "^/ " "computer" ["mfg" "HP" "model" "Vectra"] none "^/ " "computer" ["mfg" "Compaq" "mode" "Presario"] none "^/ " "coffeecup" ["level" "0.5"] none "^/ " ] "^/ " "floor" ["color" "green"] [ "^/ " "chair" ["fabric" "blue" "rolling" "yes"] [ "^/ " "myself" ["name" "Joel"] none "^/ " ] "^/ " "filingcabinet" ["drawers" "4"] none "^/ " "trashcan" ["liner" "yes"] [ "^/ " "stickynote" ["color" "pink"] [ { somebody else's unreadable handwritten scribbled message... } ] "^/ " ] "^/ " ] "^/" ] ]
>> xu/dump-xml doc
<test date="17-May-2001" author="Joel Neely"> <desktop color="brown"> <computer mfg="HP" model="Vectra"/> <computer mfg="Compaq" mode="Presario"/> <coffeecup level="0.5"/> </desktop> <floor color="green"> <chair fabric="blue" rolling="yes"> <myself name="Joel"/> </chair> <filingcabinet drawers="4"/> <trashcan liner="yes"> <stickynote color="pink"> somebody else's unreadable handwritten scribbled message... </stickynote> </trashcan> </floor> </test>
>>
8<------------------------------------------------------------ The functions described above are contained in a single file which is organized for use with the UHURU unit management system under development (hint, hint, hint...). 8<------------------------------------------------------------ REBOL [ title: {xml-utils} file: %xml-utils.r author: {Joel Neely} version: 1.0.0 comments: {to be added Real Soon Now...} ] make object! [ trim-xml: func [xml-blk [block!] /local content item] [ if found? content: third xml-blk [ while [not tail? content] [ either block? item: first content [ trim-xml item content: next content ][ either 0 = length? trim item [ remove content ][ content: next content ] ] ] if 0 = length? head content [xml-blk/3: none] ] xml-blk ] attr-text: func [attribs [block! none!] /local str] [ str: copy "" if block? attribs [ foreach [attr val] attribs [ append str rejoin [" " attr "=" mold val] ] ] str ] open-tag: func [xml-blk [block!]] [ rejoin ["<" to-string xml-blk/1 attr-text xml-blk/2 ">"] ] empty-tag: func [xml-blk [block!]] [ rejoin ["<" to-string xml-blk/1 attr-text xml-blk/2 "/>"] ] close-tag: func [xml-blk [block!]] [ rejoin ["</" to-string xml-blk/1 ">"] ] dump-xml-block: func [xml-blk [block!] /local dump1 pref indent] [ pref: copy "" indent: " " dump1: func [xml-blk [block!]] [ print join pref mold xml-blk/1 print join pref mold xml-blk/2 either none? xml-blk/3 [ print join pref mold xml-blk/3 ][ print join pref "[" append pref indent foreach cont xml-blk/3 [ either block? cont [ dump1 cont ][ print join pref mold cont ] ] print join remove/part pref length? indent "]" ] ] dump1 xml-blk ] dump-xml: func [xml-blk [block!] /local dump1 pref indent] [ pref: copy "" indent: " " dump1: func [xml-blk [block!]][ either none? xml-blk/3 [ print join pref empty-tag xml-blk ][ print join pref open-tag xml-blk append pref indent foreach cont xml-blk/3 [ either block? cont [ dump1 cont ][ foreach item parse/all cont "^/" [ print join pref item ] ] ] print join remove/part pref length? indent close-tag xml-blk ] ] dump1 first third trim-xml copy/deep xml-blk ] ] 8<------------------------------------------------------------ Hope this helps! -jn-