REBOL [
Title: "RebXML to XML Converter"
Date: 02-Mar-2009
Version: 1.3.1
File: %rebxml2xml.r
Author: "John Niclasen"
Rights: {Copyright © John Niclasen, NicomSoft 2005}
Purpose: {Converts a RebXML block structure to XML.}
History: [
1.3.1 [02-Mar-2009 "JN" {Fixed potential bug in EmptyElemTag.}]
1.3.0 [08-Nov-2005 "JN" {Fixed bug with value in Attribute.
Added Comment.}]
1.2.0 [26-Feb-2005 "JN" {Added support for utf-8.}]
1.1.1 [24-Feb-2005 "JN" {Changed EmptyElemTag from # to a slash: /}]
1.1.0 [23-Feb-2005 "JN" {Added improved build-tag.
Added support for namespace-tags.
Changed EmptyElemTag from "" to a number sign: #}]
1.0.1 [31-Jan-2005 "JN" {Added replacements for #"&", #"<" and #">".}]
1.0.0 [25-Jan-2005 "JN" {Created.}]
]
library: [
level: 'intermediate
platform: 'all
type: 'tool
domain: [markup parse xml]
tested-under: none
support: none
license: 'BSD
see-also: "xml2rebxml.r"
]
]
; An improved build-tag is here, because the original build-tag within REBOL can't cope with some types of tags.
build-tag: func [
"Generates a tag from a composed block."
values [block!] "Block of parens to evaluate and other data."
/local 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! | url!] (append tag name)
any [
set attribute [word! | url!] value-rule (
repend tag [#" " attribute {="} value {"}]
)
| value-rule (repend tag [#" " value])
]
end (if xml? [append tag #"?"])
]
|
[set name refinement! to end (tag: mold name)]
]
to tag! tag
]
context [
lit-slash: to-lit-word "/"
mark: none
convert2utf-8: off
tag: []
stack: []
name:
att:
value: none
output: make string! 16384
iso2utf-8: func [
data [string!]
/local c2chars c3chars iso8859 mark
][
c2chars: charset [#"^(A0)" - #"^(BF)"]
c3chars: charset [#"^(C0)" - #"^(FF)"]
iso8859: [any [
mark: c2chars (mark: insert mark #"^(C2)") :mark skip |
mark: c3chars (
change mark to-char mark/1 - #"^(40)"
mark: insert mark #"^(C3)"
) :mark skip |
skip
]]
parse/all data iso8859
data
]
document: [prolog element]
prolog: [
(either convert2utf-8 [
insert output {^/}
][
insert output {^/}
])
;any Comment
any CharData
]
element: [
EmptyElemTag
| STag [CharData | into content] ETag
]
STag: [
set name [word! | url!] (clear tag insert tag name) any Attribute (
insert tail output build-tag tag
insert tail stack name
)
]
Attribute: [
mark: lit-slash :mark break
| set att [word! | url!] set value string! (
value: copy value
replace/all value #"&" "&"
replace/all value #"<" "<"
replace/all value #">" ">"
replace/all value #"'" "'"
replace/all value #"^"" """
insert tail tag reduce [att value]
)
]
ETag: [
(insert tail output to tag! rejoin [#"/" last stack]
remove back tail stack)
]
EmptyElemTag: [
set name [word! | url!] (clear tag insert tag name)
[lit-slash | any Attribute lit-slash] (
insert tail tag #"/"
insert tail output build-tag tag
)
]
content: [
;opt CharData any [Comment | element opt CharData]
any [CharData | element]
]
CharData: [
set value string! (
either (copy/part value 4) = "