[EMAIL PROTECTED] 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 ""
    ]

Reply via email to