[REBOL] Re: generating XML ?
From: joel:neely:fedex at: 15-Jun-2002 8:15
Hi, Jason,
Jason Cunliffe wrote:
> I need to generate XML from REBOL...
>
Do you mean from arbitrary REBOL block structures, or from block
similar in structure to the output of PARSE-XML?
If the latter, here is some work-in-progress that might be of
interest:
8<--------------------------------------------------
xml-lib: make object! [
q1: to-char 39 ; single quote
q2: to-char 34 ; double quote
_xentities: reduce [
"&" "&"
"<" "<"
">" ">"
q2 """
]
_xescape: func [s [string!] /local r] [
r: copy s
foreach [chr ent] _xentities [replace/all r chr ent]
r
]
_xenquote: func [s [string!] /local q] [
rejoin [
q: either find s q2 [
either find s q1 [ s: _xescape s q2 ][ q1 ]
][
q2
]
s q
]
]
_xformattrs: func [a [block! none!] /local r] [
r: copy ""
foreach [name value] any [a []] [
repend r [" " name {=} _xenquote value]
]
r
]
_xform: func [b [block!] pre [string!] /local r c d] [
r: copy ""
append r rejoin [pre "<" first b _xformattrs second b]
either none? c: third b [
append r rejoin [" />" newline]
][
append r ">"
either all [
1 = length? c
string? d: first c
60 >= length? d
newline <> last d
][
append r rejoin [
_xescape d "</" first b ">"
newline
]
][
append r newline
foreach item c [
append r either string? item [
rejoin [item newline]
][
_xform item join " " pre
]
]
append r rejoin [pre "</" first b ">" newline]
]
]
r
]
xform: func [b [block!]] [
_xform either word? first b [first third b] [b] ""
]
xtrim: func [b [block!] /local b3 b31] [
if found? b3: third b [
while [not empty? b3] [
either string? b31: first b3 [
either empty? trim/head/tail b31 [
remove b3
][
b3: next b3
]
][
xtrim b31
b3: next b3
]
]
if empty? head b3 [
b/3: none
]
]
b
]
]
8<--------------------------------------------------
XML-LIB/XTRIM removes the ignorable whitespace from the content
of an XML-derived block structure, as in this case:
>> foo: {
{ <drill model="DB-375">
{ <motor rating="0.25h" />
{ <chuck size="0.375" />
{ <description>
{ A wonderful Father's Day gift idea! On sale now!
{ </description>
{ <price wholesale="27.45" retail="49.95" />
{ </drill>
{ }
== {
<drill model="DB-375">
<motor rating="0.25h" />
<chuck size="0.375" />
<description>
A wonderful Father's Day gift idea! On s...
>> bletch: parse-xml foo
after which BLETCH has the following structure (reformatted for
email):
[document none [
["drill" ["model" "DB-375"] [
"^/"
["motor" ["rating" "0.25h"] none]
"^/"
["chuck" ["size" "0.375"] none]
"^/"
["description" none [
{^/A wonderful Father's Day gift idea! On sale now!^/}
]]
"^/"
["price" ["wholesale" "27.45" "retail" "49.95"] none]
"^/"
]]
]]
where the extra newlines (for example) are not relevant to the "data-
oriented" content. We can say
xml-lib/xtrim bletch
to tidy up the content of BLETCH as follows:
[document none [
["drill" ["model" "DB-375"] [
["motor" ["rating" "0.25h"] none]
["chuck" ["size" "0.375"] none]
["description" none [
"A wonderful Father's Day gift idea! On sale now!"
]]
["price" ["wholesale" "27.45" "retail" "49.95"] none]
]]
]]
Since this is still in the canonical XML-as-blocks form, we can say
>> print xml-lib/xform bletch
<drill model="DB-375">
<motor rating="0.25h" />
<chuck size="0.375" />
<description>A wonderful Father's Day gift idea! On sale
now!</description>
<price wholesale="27.45" retail="49.95" />
</drill>
(note that the description wrapped, the max length is tweakable).
OTOH, we can start with a block structure of the same scheme:
glorp: [
"computer"
["owner" "dilbert"]
[ [
"cpu"
["model" "athlon" "speed" "4.5GHz"]
[]
]
[
"ram"
["type" "ddr" "size" "4096Mb"]
[]
]
[
"disk"
["size" "512Gb" "speed" "10500rpm"]
["just for home use"]
]
]
]
which can be rendered in XML by
>> print xml-lib/xform glorp
<computer owner="dilbert">
<cpu model="athlon" speed="4.5GHz">
</cpu>
<ram type="ddr" size="4096Mb">
</ram>
<disk size="512Gb" speed="10500rpm">just for home use</disk>
</computer>
HTH!
-jn-
--
; Joel Neely joeldotneelyatfedexdotcom
REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip
do function [s] [t] [ t: "" foreach [a b] s [repend t [b a]] t ] {
| e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]