generating XML ?
[1/4] from: jason::cunliffe::verizon::net at: 14-Jun-2002 12:14
I need to generate XML from REBOL...
What do you suggest for writing XML from REBOL, in particular exporting REBOL
blocks and nested blocks as XML? I can only seem to find some cool tools for
import [parsing]..
I must be missing something somewhere
thanks
./Jason
[2/4] from: al:bri:xtra at: 15-Jun-2002 14:20
Jason wrote:
> What do you suggest for writing XML from REBOL, in particular exporting
REBOL blocks and nested blocks as XML?
I'd suggest using my ML and Build-Tag functions.
Here's an example of their use (XHTML):
Dialect: [
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
DTD/xhtml1-transitional.dtd
html [
head [
title (Title)
link/rel/type/href "stylesheet" "text/css" (Location %Stylesheet.css)
]
(Body-Attributes) [
table [
tr [
td/width (Margin) " "
td/width (Width) [
(eText-Dialect)
hr
a/href (Valley/Core/File) "To the Core."
]
td " "
]
]
]
]
]
Here's another example from my Wiki:
print ML compose/deep [
html [
head [
title (Heading)
link/rel/type/href "stylesheet" "text/css" %/Stylesheet.css
]
body [
(eText/Wiki/Base read Directory/:File join Action #"?")
hr
table/width "100%" [
tr [
td/align "left" [
form/method/action "GET" (Action) [
input/type/value "submit" "Wiki Index"
]
]
td/align "center" [
form/method/action "GET" (Action) [
label [
"Search: " input/type/name/value "text" (
first Search_Rule
) ""
]
input/type/value "submit" "Search"
]
]
td/align "right" [
form/method/action "GET" (Action) [
input/type/value "submit" "Edit"
input/type/name/value "hidden" (first Edit_Rule) (Title)
]
]
]
]
]
]
]
I hope that helps!
Andrew Martin
ICQ: 26227169 http://valley.150m.com/
-><-
Watch out for line breaks!
[
Rebol [
Name: 'ML
Title: "ML"
File: %ML.r
Author: "Andrew Martin"
eMail: [Al--Bri--xtra--co--nz]
Date: 8/June/2002
Comments: {
ML generates XML-like markup language from words, paths and blocks.
ML can generate HTML, XHTML, XML, WML and SVG markup.
}
]
ML: function [Dialect [block!]] [String Values_Rule Values Value Tag] [
String: make string! 40000
Values_Rule: [
; Caution! The 'none word below is replaced in the 'parse rule
below!
none [
set Value any-type! (
Tag: next next Tag
insert Tag Value
Value: none
)
]
; Caution! The 'opt word below is replaced in the 'parse rule below!
opt [
set Value [
decimal! | file! | block! | string! | char!
| money! | time! | issue! | tuple! | date!
| email! | pair! | logic! | integer! | url!
]
]
]
Values: make block! 10
parse Dialect [
any [
[
set Tag tag! (
Values_Rule/1: 0 ; Replace 'none word in 'Values_Rule
above.
if #"/" = last Tag [Values_Rule/3: 0] ; Replace 'opt
word...
)
| set Tag [path! | word!] (
Tag: to-block get 'Tag
Values_Rule/1: -1 + length? Tag ; Replace 'none word
in 'Values_Rule above.
Values_Rule/3: 'opt ; Replace 'opt word...
)
] (Value: none) Values_Rule (
Tag: head Tag
either none? Value [
if not tag? Tag [
Tag: build-tag Tag
]
if #"/" <> last Tag [
append Tag " /"
]
append String Tag
append String newline
] [
repend String [
either block? Value [newline] [""]
either tag? Tag [Tag] [Build-Tag Tag]
either block? Value [ML Value] [Value]
to-tag join #"/" first either tag? Tag [to-block
Tag] [Tag]
]
]
Values_Rule/1: none
)
| set Value any-type! (append String Value)
]
end
]
String
]
]
[
Rebol [
Name: 'Build-Tag
Title: "Build-Tag"
File: %Build-Tag.r
Author: "Andrew Martin"
eMail: [Al--Bri--xtra--co--nz]
Date: 7/June/2002
Comments: {
Build-Tag is a replacement Build-Tag that handles XML attributes.
}
]
Build-Tag: function [
"Generates a tag from a composed block."
Values [block!] "Block of parens to evaluate and other data."
] [
Tag Value_Rule XML? Name Attribute Value
] [
Tag: make string! 7 * length? Values
Value_Rule: [
set Value issue! (Value: mold Value)
| set Value file! (Value: replace/all copy Value #" " " ")
| set Value any-type!
]
XML?: false
parse compose Values [
[
set Name ['?xml (XML?: true) | word!] (
append Tag Name
)
any [
set Attribute [word! | url!] Value_Rule (
Tag: rejoin [
Tag #" " Attribute {="} Value {"}
]
)
| Value_Rule (
Tag: reform [Tag Value]
)
]
end (
if XML? [
append Tag #"?"
]
)
]
| [
set Name refinement! any any-type! end (
Tag: mold Name
)
]
]
to tag! Tag
]
]
-- Attached file included as plaintext by Listar --
-- File: ML.r
[
Rebol [
Name: 'ML
Title: "ML"
File: %ML.r
Author: "Andrew Martin"
eMail: [Al--Bri--xtra--co--nz]
Date: 8/June/2002
Comments: {
ML generates XML-like markup language from words, paths and blocks.
ML can generate HTML, XHTML, XML, WML and SVG markup.
}
]
ML: function [Dialect [block!]] [String Values_Rule Values Value Tag] [
String: make string! 40000
Values_Rule: [
; Caution! The 'none word below is replaced in the 'parse rule below!
none [
set Value any-type! (
Tag: next next Tag
insert Tag Value
Value: none
)
]
; Caution! The 'opt word below is replaced in the 'parse rule below!
opt [
set Value [
decimal! | file! | block! | string! | char!
| money! | time! | issue! | tuple! | date!
| email! | pair! | logic! | integer! | url!
]
]
]
Values: make block! 10
parse Dialect [
any [
[
set Tag tag! (
Values_Rule/1: 0 ; Replace 'none word in 'Values_Rule above.
if #"/" = last Tag [Values_Rule/3: 0] ; Replace 'opt word...
)
| set Tag [path! | word!] (
Tag: to-block get 'Tag
Values_Rule/1: -1 + length? Tag ; Replace 'none word in 'Values_Rule above.
Values_Rule/3: 'opt ; Replace 'opt word...
)
] (Value: none) Values_Rule (
Tag: head Tag
either none? Value [
if not tag? Tag [
Tag: build-tag Tag
]
if #"/" <> last Tag [
append Tag " /"
]
append String Tag
append String newline
] [
repend String [
either block? Value [newline] [""]
either tag? Tag [Tag] [Build-Tag Tag]
either block? Value [ML Value] [Value]
to-tag join #"/" first either tag? Tag [to-block Tag] [Tag]
]
]
Values_Rule/1: none
)
| set Value any-type! (append String Value)
]
end
]
String
]
]
-- Attached file included as plaintext by Listar --
-- File: Build-Tag.r
[
Rebol [
Name: 'Build-Tag
Title: "Build-Tag"
File: %Build-Tag.r
Author: "Andrew Martin"
eMail: [Al--Bri--xtra--co--nz]
Date: 7/June/2002
Comments: {
Build-Tag is a replacement Build-Tag that handles XML attributes.
}
]
Build-Tag: function [
"Generates a tag from a composed block."
Values [block!] "Block of parens to evaluate and other data."
] [
Tag Value_Rule XML? Name Attribute Value
] [
Tag: make string! 7 * length? Values
Value_Rule: [
set Value issue! (Value: mold Value)
| set Value file! (Value: replace/all copy Value #" " " ")
| set Value any-type!
]
XML?: false
parse compose Values [
[
set Name ['?xml (XML?: true) | word!] (
append Tag Name
)
any [
set Attribute [word! | url!] Value_Rule (
Tag: rejoin [
Tag #" " Attribute {="} Value {"}
]
)
| Value_Rule (
Tag: reform [Tag Value]
)
]
end (
if XML? [
append Tag #"?"
]
)
]
| [
set Name refinement! any any-type! end (
Tag: mold Name
)
]
]
to tag! Tag
]
]
[3/4] from: cybarite:sympatico:ca at: 15-Jun-2002 8:12
In the rebol script library
http://www.reboltech.com/library/library.html pick the table entry "HTML/XML
Related"
there is an entry XMLGEN.r dated 4-Jun-1999 which takes a REBOL block
structure like
example: [
movie [
title "Star Trek: Insurrection"
star "Patrick Stewart" "Brent Spiner"
theater [
theater-name "MonoPlex 2000"
showtime 14:15 16:30 18:45 21:00
price [
adult $8.50
child $5.00
]
]
theater [
theater-name "Bigscreen 1"
showtime 19:30
price $6.00
]
]
]
and generates XML from it
<movie>
<title>Star Trek: Insurrection</title>
<star>Patrick Stewart</star>
<star>Brent Spiner</star>
<theater>
<theater-name>MonoPlex 2000</theater-name>
<showtime>14:15</showtime>
<showtime>16:30</showtime>
<showtime>18:45</showtime>
<showtime>21:00</showtime>
<price>
<adult>$8.50</adult>
<child>$5.00</child>
</price>
</theater>
<theater>
<theater-name>Bigscreen 1</theater-name>
<showtime>19:30</showtime>
<price>$6.00</price>
</theater>
</movie>
which you may find adequate. I don't think it will compete with what Andrew
is offering but might be a gentle start on what you need to accomplish. I
used it when I needed just to get some sample XML structures out for
discussion and was able to change the REBOL structure more easily then the
XML. It is just freeing you from the <start long tag>....</end long tag>
tedium ... but that may be what you are after.
No reply is needed either way.
[4/4] 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 ]