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

[REBOL] parse-xml cannot be reversed Re:

From: joel:neely:fedex at: 31-Jul-2000 15:49

[bhandley--zip--com--au] wrote:
> I attempted to write a function that would take the structure that parse-xml > generates and export it back into a valid xml file. > But, I found that it cannot be reliably done. >
Beg pardon, but it can be done.
> Here's an example. > >> parse-xml {<a>teststring<b/><c/></a>} > == [document none [["a" none ["teststring" ["b" none none] ["c" none > none]]]]] > > Just looking at the structure would lead you (or your program) to conclude > that "b" was an attribute of an element "teststring", until you realise that > attribute lists should not have an odd number of elements. >
No. Looking at that structure tells me that <a> has no attributes, but has three pieces of content: a string, a <b> element, and a <c> element. teststring is a string and not the name of an element. We know this because an XML element is always represented by a block with three parts: 1) name: a string 2) attributes: either none or a block of name/value pairs 3) contents: either none or a block of content items, *each of which must be either a string or an element block* Since "teststring" occurrs AS A TOP-LEVEL MEMBER of the content of <a>, it must be a string. If "teststring" were the name of an element nested inside <a>, it would have to be the first element of its own block, something like: [document none [["a" none [["teststring" #1 #2] ["b" none none] #3]]]] where #1 is the attribute list of <teststring> (or none) #2 is the content of <teststring> (or none) #3 is the rest of the content of <a>, after <teststring> and <b> The code below should do what you want (except for the placement of ignorable-whitespace values, but that is left as an exercise for the reader ;-) -jn- _xdump: func [ b [block!] {xml structure} p [string!] /local tag pp was-string ][ tag: trim to-string first b prin join copy p [join copy "<" tag] if found? second b [ foreach [n v] second b [ prin join copy " " [trim n "=" mold v] ] ] either none? third b [ print join copy "><" [tag "/>"] ][ print ">" pp: join copy p " " was-string: false foreach x third b [ was-string: not any-block? x either was-string [ if 0 < length? trim x [ prin join copy pp x ] ][ _xdump x pp ] ] if was-string [print ""] print [join copy p [copy "</" trim tag ">"]] ] ] xdump: func [ b [block!] {the xml structure from parse-xml} ][ _xdump first third b copy "" print "" ]