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

[REBOL] Re: Simple XML

From: doug:vos:eds at: 9-Mar-2004 16:37

I think this does what you want. Purpose: "Library analogous to perl XML::Simple." Only works with simple XML. Does not handle namespaces="values" inside tags. REBOL [ Title: {xml-test13.r} File: %xml-test13.r Date: 21-Oct-2003 Requires: {rebol version 2.5.6 or higher} ] do %/d/xml/xml-simple-v0.1.2.r bklist: XMLin %/d/xml/booklist3.xml probe bklist XMLout %/d/xml/booklist4.xml bklist ;===================================== REBOL [ Title: "XML-Simple (Library)" Date: 20-Oct-2003 Version: 0.1.2 File: %xml-simple.r Author: "Doug Vos" Email: [doug--vvn--net] Purpose: "Library analogous to perl XML::Simple." History: [ 0.1.0 [18-Oct-2003 {Began script.} "DJV"] 0.1.2 [20-Oct-2003 {Added XMLin function, added XMLout.} "DJV"] ] ] ;-------------------------------------------------------------------- end-tag?: func [ {Test for an ending xml or html style tag. eg. </thing>} item [any-type!] {The item to examine} ][ either (tag? item) [ either (find item "/") [true][false] ][ false ] ] ;-------------------------------------------------------------------- begin-tag?: func [ {Test for a begining xml or html style tag. eg. </thing>} item [any-type!] {The item to examine} ][ either (tag? item) [ either (find item "/") [false][true] ][ false ] ] ;-------------------------------------------------------------------- tag-to-string: func [ {Convert a simple html or xml tag to a string.} xtag [tag!] {The tag to convert.} ][ trim/all replace/all to-string xtag "/" "" ] ;------------------------------------------------------------------- simple-tag?: func [ {Test for tag with simple structure like <tag>a few words</tag>} item [any-type!] {The item to examine.} xml [block!] {The whole block we are examining.} /local atag ztag xs ][ either (tag? item) [ atag: to-tag (tag-to-string item) ztag: to-tag rejoin ["/" (tag-to-string item)] xs: find xml atag either ( all [ (tag? pick xs 1) (string? pick xs 2) (ztag = (pick xs 3))] ) [true][false] ][ false ] ] ;------------------------------------------------------------------- multi-tags?: func [ {Test for multiple occurences of tag like <book>...</book> as found in something like <booklist><book>...</book><book>...</book></booklist>} item [any-type!] {The item to examine.} xml [block!] {The whole block we are examining.} /local atag ztag xs ][ either (tag? item) [ atag: to-tag (tag-to-string item) ztag: to-tag rejoin ["/" (tag-to-string item)] xs: find xml ztag either ( all [ (tag? pick xs 1) (atag = (pick xs 2))] ) [true][false] ][ false ] ] ;-------------------------------------------------------------------- XMLin: func [ {Provide a XMLin function analogous to perl XML::Simple XMLin().} xmli [url! file! string!] {The xml url, file or xml-text.} /local xstr xml item ][ xstr: make string! 1000 xml: load/markup xmli ; remove the strings that are only 'newline and empty space remove-each x xml [empty? trim x] ; Ignore the first tag, ; which is always something like <?xml version="1.0"?> xml: copy at xml 2 append xstr "[" foreach item xml [ append xstr " " if (begin-tag? item) [ if (multi-tags? item xml) [append xstr " [ "] append xstr tag-to-string item if (not simple-tag? item xml) [append xstr " [ "] ] if (string? item) [ append xstr mold item ] if (end-tag? item) [ if (not simple-tag? item xml) [append xstr " ]"] if (multi-tags? item xml) [append xstr " ] "] ] ] append xstr "]" load xstr ] ;-------------------------------------------------------------------- XMLout: func [ {Provide a XMLout function analogous to perl XML::Simple XMLout().} xmlf [file!] {The xml file to create.} xblock [block!] {The data to populate xml file.} /local xstr item ][ xstr: make string! 1000 append xstr {<?xml version="1.0"?>^/} XMLout.block xstr xblock print xstr write xmlf xstr ] ;-------------------------------------------------------------- XMLout.block: func [ {Process the block according to rules.} xml.tree [string!] {The xml-tree we are creating.} item [block!] {The pre xml-block.} ][ either (multi-block? item) [ foreach x item [ XMLOut.block xml.tree x ] ][ either (multi-word-pair? item) [ foreach [w v] item [ XMLOut.block xml.tree (reduce [w v]) ] ][ if (simple-word-value-pair? item) [ append xml.tree rejoin ["<" item/1 ">" item/2 "</" item/1 ">" newline] ] if (complex-block-pair? item) [ append xml.tree rejoin [ "<" item/1 ">"] XMLOut.block xml.tree item/2 append xml.tree rejoin [ "</" item/1 ">" newline] ] ] ] ] ;-------------------------------------------------------------------- multi-word-pair?: func [ {Examine block to see if it contains a block with multiple word pairs. Return TRUE if item is pattern [word "value" word "value"] or TRUE if item is pattern [word "value" word [block]] } item [any-type!] {Item to examine.} ][ either block? item [ either ((length? item) >= 4) [ all [(word? item/1) (word? item/3)] ][ false ] ][ false ] ] ;-------------------------------------------------------------------- multi-block?: func [ {Examine block to if it contains 2 or more blocks} item [any-type!] {Examine item and return TRUE if multi-block.} ][ either block? item [ either ((length? item) >= 2) [ all [(block? item/1) (block? item/2)] ][ false ] ][ false ] ] ;-------------------------------------------------------------------- simple-word-value-pair?: func [ {Examine block to see if simple pair like [word! single-value] } item [any-type!] {Examine item and return TRUE if simple pair.} ][ either block? item [ either ((length? item) = 2) [ all [(word? item/1) (not block? item/2)] ][ false ] ][ false ] ] ;-------------------------------------------------------------------- complex-block-pair?: func [ {Examine block to see if complex pair [word! [block]] } item [any-type!] {Examine item and return TRUE if complex pair.} ][ either block? item [ either ((length? item) = 2) [ all [(word? item/1) (block? item/2)] ][ false ] ][ false ] ] ;--------------------------------------------------------------------