Hello list,
looking thru the hundreds of read and unread posts to this list, XML and
REBOL's inbuild XML 'support' is mentioned at least every some days.
Someone - wasn't it Andrew? - wanted to convert XML's DTDs to REBOL's parse
rules. I must have overseen the :) which followed this idea ...
Okay. Instead of preparing for an exam, I played with XML and read about
it on w3.org. The grammar specified there inspired me to convert it to a
parse dialect, which isn't that hard as I first thought. In it's current
state it's far from being complete - but it does some cute little things
which give a hint to what it can do some day in far future.
>> xml-data: {<?xml version="1.0" standalone="yes"?>
<!DOCTYPE test [
<!ENTITY ME "Christian Ensel">
<!ELEMENT che:money ANY>
<!ATTLIST che:money che:currency CDATA "USD"
che:amount CDATA #REQUIRED
>
]>
<space:name>
This is some text typed by &ME;.
<che:money xmlns:che = "http://www.foo.bar"
che:amount = "0.02"
che:currency = "USD"
>
My two cents someday?!?
<element attribute="<1>" />
</che:money>
</space:name>}
>> xml/process xml-data
This results in the following object tree, far from beeing complete,
but IMHO some very cute things work already (e.g. declaring Entities,
see the marker ^^^^^^):
>> probe xml/the-Document
make object! [
name: none
attrs: []
content: [
make object! [
name: "space:name"
attrs: []
content: [
"^/ This is some text typed by "
"Christian Ensel"
^^^^^^^^^^^^^^^^^
".^/ "
make object! [
name: "che:money"
attrs: [
make object! [
name: "xmlns:che"
value: "http://www.foo.bar"
]
make object! [
name: "che:amount"
value: "0.02"
]
make object! [
name: "che:currency"
value: "USD"
]
]
content: [
"^/ My two cents?!?^/ "
make object! [
name: "element"
attrs: [
make object! [
name: "attribute"
value: "<1>"
^^^^^
]
]
content: []
]
"^/ "
]
]
"^/"
]
]
]
]
It's fun working with PARSE , even though I'm strongly missing some
features which would help a lot, e.g. a NOT keyword or the possibility
to parse a string TO ["<" | "&" | "]]>"]. Things like that ...
The processor recognizes tags which aren't nested correctly, but is very
strict in this - it simply stops execution.
I'm very busy these days, so I'll make only little steps in next days,
but I will appreciate any comments on the idea to parse. Because
I'm a little bit uncertain on some design decisions :) I'm not even sure
if processing XML is a task where REBOL is well suited for (thinking
about things like UNICODE etc.).
As I already said, comments, please ;)
Attached you find the most recent version. I guess in it's current state
it does some 2 or 3 % of what a XML processor should do, and the code
looks (and is, I guess) very ugly :(
Hint: calling XML/PROCESS with the refinement /APPLY-RULES and the name
of one of the rules in the XML object (simple the word, no lit-word, no path)
allows for testing single rules.
As in
>> xml/process/apply-rule {<?xml?>} Prolog
== true
But you'll probably end up with
== false
more often ...
As I already said, comments, please ;)
Regards
Christian
[EMAIL PROTECTED]
-- Attached file included as plaintext by Listar --
-- File: xml-processor.r
;######################################################## REBOL XML-Processor ##
;
ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
REBOL [
title: "XML-Processor"
author: "Christian 'CHE' Ensel"
email: [EMAIL PROTECTED]
date: 16-Nov-2000
version: 0.0.4
]
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx XML xx
; ŻŻŻ
XML: make object! [
;=============================================================== SETTINGS ==
; ŻŻŻŻŻŻŻŻ
comments?: no
validate?: [ yes | no ]
the-application-wants-comments: true
the-application-wants-no-comments: false
;======================================================= HELPER-FUNCTIONS ==
; ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
MAKE-TAG: does [ make object! [ name: none attrs: make block! 0
content: make block! 0 ] ]
MAKE-NAMESPACE: function [ the-NSPrefix [string!] the-NSTarget [string!] ]
[] [ repend the-Namespaces [ the-NSPrefix the-NSTarget make block! 0 ] ]
QNAME-PREFIX: function [ a-QName [string!] ] [ the-Namespace ] [ if
equal? 2 length? the-Namespace: parse a-QName ":" [first the-Namespace] ]
QNAME-LOCALPART: function [ a-QName [string!] ] [ the-Namespace ] [ either
equal? 2 length? the-Namespace: parse a-QName ":" [second the-Namespace] [first
the-Namespace] ]
SAME-NAME?: function [ a-QName b-QName ] [ a-NSTarget b-NSTarget
a-NSName b-NSName ] [ a-NSTarget: select the-Namespaces qname-prefix a-QName
b-NSTarget: select the-Namespaces qname-prefix b-QName a-NSName: qname-localpart
a-QName b-NSName: qname-localpart b-QName (equal? a-NSName b-NSName) and (equal?
a-NSTarget b-NSTarget) ]
;======================================================== DATA-CONTAINERS ==
; ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
the-Document: none
the-Tags: none
the-Tag: none
the-EntityRefs: [ "&" ("&") | "<" ("<") | ">" (">") | """
({"}) | "'" ("'") ]
the-PEReferences: [ "%DEBUG;" ("DEBUG") ]
the-Namespaces: ["xml" "http://www.w3.org/XML/1998/namespace" [] "che"
"http://www.che.de" ["book" "title" "isbn" "author" "price"] "ensel"
"http://www.che.de" ["book" "title" "isbn" "author" "price"] "w3c" "http://www.w3.org"
["book" "title" "isbn" "author" "price"] ]
;======================================================= PROCESS xml-data ==
; ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
PROCESS: function [data [string!] /APPLY-RULE 'rule [word!] ] []
[
the-Tag: the-Document: make-tag
append the-Tags: make block! [] the-Tag
either apply-rule
[
parse/all/case data get in self rule
][
parse/all/case data Document
]
]
;---------------------------------------------------------------------------
;====================================================== GENERIC DTD RULES ==
; ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
; Rules like these will be generated automatically some day. Or some
; other approach will be choosen.
the-Amount-AttRule: [ "amount" Eq AttValue ]
the-Currency-AttRule: [ "currency" Eq [ "'" [ "DEM" | "OES" | "SFR" ] "'" | {"}
[ "DEM" | "OES" | "SFR" ] {"} ] ]
the-Money-ElemRule: [ "<money" S the-Amount-AttRule S the-Currency-AttRule Opt
S "/>" ]
;================================================================ GRAMMAR ==
{ ŻŻŻŻŻŻŻ
[Nş] ---------- http://www.w3.org/???
|
| Conventions:
| ŻŻŻŻŻŻŻŻŻŻŻŻ
| · A number in format x.y denotes a rules added by me
| wich acts as a helper to the rule x
|
| · Rules which are "terminal" rules in some sense are
| specifying nothing but charsets. In opposition to the
| official XML grammar these rules' names end with
| an exclamation mark - so I can use them as if they
| were REBOL datatypes.
|
| · Results of a rule name 'FooBar usually are to be
| kept in a word named 'the-FooBar .
|
| [Nş] - http://www.w3.org/TR/1999/REC-xml-names-19990114
| |
| |
| }
[01] Document:
[
Prolog
Element
any Misc
]
[03] S:
[
copy the-S some WhiteSpace!
]
[03.1] WhiteSpace!: charset [ " ^-^/^M" ]
[04] [05] NCNameChar!:
[
Letter!
|
Digit!
|
#"."
|
#"-"
|
#"_"
|
CombiningChar!
|
Extender!
]
[04] NameChar!:
[
Letter!
|
Digit!
|
#"."
|
#"-"
|
#"_"
|
#":"
|
CombiningChar!
|
Extender!
]
[05] [04] NCName:
[
copy the-NCName
[
[
Letter!
|
#"_"
]
any NCNameChar!
]
]
[05] [06] QName:
[
copy the-QName
[
opt
[
Prefix
":"
]
LocalPart
]
]
[05] Name:
[
copy the-Name
[
[
Letter!
|
#"_"
|
#":"
]
any NameChar!
]
]
[07] Nmtoken:
[
copy the-Nmtoken some NameChar!
]
[09.1] EntityValueChar!: complement charset {%&"}
[09] EntityValue:
[
(
the-EntityValue: make string! 0
)
[
{"}
any
[
Reference
(
append the-EntityValue the-Reference
)
|
PEReference
(
append the-EntityValue the-PEReference
)
|
copy the-EntityValueChar EntityValueChar!
(
append the-EntityValue the-EntityValueChar
)
]
{"}
|
"'"
any
[
Reference
(
append the-EntityValue the-Reference
)
|
PEReference
(
append the-EntityValue the-PEReference
)
|
copy the-EntityValueChar EntityValueChar!
(
append the-EntityValue the-EntityValueChar
)
]
"'"
]
]
[10.1] AttChar!: complement charset {<&"}
[10] AttValue:
[
(
the-AttValue: make string! 0
)
[
{"}
any
[
Reference
(
append the-AttValue the-Reference
)
|
copy the-AttChar AttChar!
(
append the-AttValue the-AttChar
)
]
{"}
|
"'"
any
[
Reference
(
append the-AttValue the-Reference
)
|
copy the-AttChar AttChar!
(
append the-AttValue the-AttChar
)
]
{"}
]
]
[11] SystemLiteral:
[
copy the-SystemLiteral
[
{"}
any SystemChar!
{"}
|
"'"
any SystemChar!
"'"
]
]
[11.1] SystemChar!: complement charset {"}
[12.1] Pubid:
[
"PUBLIC"
S
Public-ID-Lit
]
[12] PubidLiteral:
[
copy the-PubidLiteral
[
{"}
any
[
PubidChar!
|
"'"
]
{"}
|
"'"
any PubidChar!
"'"
]
]
[13] PubidChar!: charset
[
" ^M^/" #"A" - #"Z" #"a" - #"z"
#"0" - #"9" "-()+,./:=?;!*#@$_%"
]
[14] CharData:
[
(
the-CharData: make string! 0
the-BracketCounter: 0
)
[
some
[
"]"
(
append the-CharData #"]"
the-BracketCounter:
add the-BracketCounter 1
)
|
">"
(
append the-CharData #">"
if greater-or-equal? the-BracketCounter 2
[
;-- last 3 chars were "]]>"
; this is not allowed!
prin [
{** XML Error: Forbidden "]]>"}
{encountered in CharData!^/}
]
print {** Where: ???}
halt
]
)
|
copy the-CharDataChar CharDataChar!
(
append the-CharData the-CharDataChar
)
]
]
( probe the-CharData )
]
[14.1] CharDataChar!: complement charset ["<&]>"]
[15] Comment:
[
(
the-Comment: make String! 0
)
"<!--"
any
[
copy the-CommentChar CommentChar!
(
append the-Comment the-CommentChar
)
|
"-"
copy the-CommentChar CommentChar!
(
repend the-Comment [ "-" the-CommentChar ]
)
]
"-->"
]
[15.1] CommentChar!: charset [ "^-^/^M" #" " - #"," #"." - #"˙"]
[16] PI:
[
"<?"
copy the-PI
to "?>"
2 skip
;-- PITarget
;-- opt S
;-- opt PIData
;-- "?>"
]
{Parsing PIs this way will be too greedy!?}
[16.1] PIData:
[
opt S
copy the-PIData
to "?>"
]
[17] PITarget:
[
Name
(
the-PITarget: the-Name
)
]
[18] CDSect: [ CDStart ]
[19] CDStart: [ "<![CDATA[" ]
[20] CData: [ copy the-CData to "]]>" ]
[21] CDEnd: [ "]]>" ]
[22] Prolog:
[
opt XMLDecl
any Misc
opt
[
DoctypeDecl
any Misc
]
]
[23] XMLDecl:
[
"<?xml"
VersionInfo
opt EncodingDecl
opt SDDecl
opt S
"?>"
]
[24] VersionInfo:
[
S
"version"
Eq
[
"'" VersionNum "'"
|
{"} VersionNum {"}
]
]
[25] Eq: [ opt S "=" opt S ]
[26] VersionNum: [
copy the-VersionNum some VersionChar!
]
[26.1] VersionChar!: charset
[
#"A" - #"Z" #"a" - #"z" #"0" - #"9" "_.:-"
]
[27] Misc: [ PI | S | Comment ]
[28 a] DeclSep: [ PEReference | S ]
[28] [13] DoctypeDecl: [
"<!DOCTYPE"
S
Name
(
the-DoctypeDecl-Name: the-Name
)
opt [ S ExternalID ]
opt S
opt [ "[" any [ MarkupDecl | DeclSep ] "]" opt S ]
">"
(
print "okay!"
)
]
[29] MarkupDecl:
[
ElementDecl
|
AttlistDecl
|
EntityDecl
|
NotationDecl
|
PI
|
Comment
]
[32] SDDecl:
[
S
"standalone"
Eq
[
"'" [ "yes" | "no" ] "'"
|
{"} [ "yes" | "no" ] {"}
]
]
[39] Element:
[
EmptyElemTag
(
append the-Tag/content the-EmptyElemTag
)
|
STag
(
append the-Tag/content the-STag
append the-Tags the-STag
the-Tag: the-STag
)
Content
ETag
(
if not equal? the-Tag/name the-ETag-QName
[
prin
[
"** XML Fatal Error: "
"Elements not properly nested.^/"
"** Where: ???^/"
]
halt
]
the-Tags: head remove back tail the-Tags
the-Tag: last the-Tags
)
]
[40] [09] STag:
[
"<"
QName
(
the-STagName: the-QName
)
opt Attributes
opt S
">"
(
the-STag: make-tag
the-STag/name: the-STagName
the-STag/attrs: the-Attributes
)
]
[41.1] Attributes:
[
(
the-Attributes: make block! 0
)
any
[
S
Attribute
(
append the-Attributes the-Attribute
)
]
]
[41] [12] Attribute:
[
[
copy the-AttName
[
NSAttName
|
QName
]
]
Eq
AttValue
(
the-Attribute: make object!
[
name: the-AttName
value: the-AttValue
]
)
]
[41] [03] DefaultAttName:
[
copy the-DefaultAttName "xmlns"
]
[41] [08] LocalPart:
[
copy the-LocalPart NCName
]
[41] [01] NSAttName:
[
[
PrefixedAttName
(
the-NSAttName: the-PrefixedAttName
)
|
DefaultAttName
(
the-NSAttName: the-DefaultAttName
)
]
]
[41] [07] Prefix: [ copy the-Prefix NCName ]
[41] [02] PrefixedAttName:
[
copy the-PrefixedAttName [ "xmlns:" NCName ]
]
[42] [10] ETag: [
"</"
QName
(
the-ETag-QName: the-QName
)
opt S
">"
]
[43] Content:
[
any
[
Element
(
;-- append the-Tag/content the-Element
; is (was already) done in 'Element (see there)
)
|
Reference
(
append the-Tag/content the-Reference
)
|
CDSect
(
append the-Tag/content the-CDSect
)
|
PI
(
repend/only the-Tag/content [ 'PI the-PI ]
)
|
Comment
(
if the-application-wants-comments
[
repend/only the-Tag/content
[
'Comment the-Comment
]
]
)
|
CharData
(
append the-Tag/content the-CharData
)
]
]
[44] [11] EmptyElemTag: [
"<"
QName
(
the-EmptyElemTagName: the-QName
)
opt Attributes
opt S
"/>"
(
the-EmptyElemTag: make-tag
the-EmptyElemTag/name: the-EmptyElemTagName
the-EmptyElemTag/attrs: the-Attributes
)
]
[45] [14] ElementDecl:
[
"<!ELEMENT"
S
QName
(
the-ElementDecl-QName: the-QName
)
S
ContentSpec
(
the-ElementDecl-ContentSpec: the-ContentSpec
)
opt S
">"
(
the-ElementDecl: reduce
[
the-ElementDecl-QName
the-ElementDecl-ContentSpec
]
)
]
[46] ContentSpec:
[
copy the-ContentSpec "EMPTY"
|
copy the-ContentSpec "ANY"
|
Mixed
(
the-ContentSpec: the-Mixed
)
|
Children
(
the-ContentSpec: the-Children
)
]
[47] Children:
[
[
Choice
(
the-Children-Particle: the-Choice
)
|
Seq
(
the-Children-Particle: the-Seq
)
]
(
the-Children-Count: 'one
)
opt
[
"?"
( the-Children-Count: 'opt )
|
"*"
( the-Children-Count: 'any )
|
"+"
( the-Cp-Count: 'some )
]
(
the-Children: either equal?
the-Children-Count 'one
[
the-Children-Particle
][
reduce [
the-Children-Count the-Children-Particle
]
]
)
]
[48] [15] Cp:
[
[ QName ( the-Cp-Particle: the-QName )
| Choice ( the-Cp-Particle: the-Choice )
| Seq ( the-Cp-Particle: the-Seq )
]
( the-Cp-Count: 'one )
opt
[ "?" ( the-Cp-Count: 'opt )
| "*" ( the-Cp-Count: 'any )
| "+" ( the-Cp-Count: 'some )
]
(
the-Cp: either equal?
the-Cp-Count 'one
[
the-Cp-Particle
][
reduce [
the-Cp-Count the-Cp-Particle
]
]
)
]
[49] Choice:
[
( the-Choice: make block! [] )
"("
opt S
Cp
( append the-Choice the-Cp )
some
[
opt S "|" opt S Cp
(
repend the-Choice [ '| the-Cp ]
)
]
opt S
")"
(
the-Choice: reduce [ the-Choice ]
)
]
[50] Seq:
[
(
the-Seq: make block! []
)
"("
opt S
Cp
(
append the-Seq the-Cp
)
any
[
opt S "," opt S Cp
(
append the-Seq the-Cp
)
]
opt S
")"
(
the-Seq: reduce [ the-Seq ]
)
]
[51] [16] Mixed:
[
"(" opt S "#PCDATA"
any
[
opt S "|" opt S QName
]
opt S ")*"
|
"(" opt S "#PCDATA" opt S ")"
]
[52] [17] AttlistDecl: [
"<!ATTLIST"
( prin "AttlistDecl found " )
S
QName ( the-AttlistDecl-QName: the-QName )
(
print [ {for element "} the-QName {" :} ]
the-AttlistDecl-AttDefs: make block! []
)
any
[
AttDef
(
append/only the-AttlistDecl-AttDefs the-AttDef
)
]
opt S ">"
(
the-AttlistDecl: reduce
[
the-AttlistDecl-QName the-AttlistDecl-AttDefs
]
)
]
[53] [18] AttDef:
[
S
[
NSAttName
( the-AttDef-AttName: the-NSAttName )
|
QName
( the-AttDef-AttName: the-QName )
]
(
print [
{It declares an attribute "}
the-AttDef-AttName {" .}
]
)
S
AttType ( the-AttDef-AttType: the-AttType )
( print [{The AttType is "} the-AttType {" .}])
S
DefaultDecl
(
the-AttDef-DefaultDecl: the-DefaultDecl
the-AttDef: reduce
[
the-AttDef-AttName
the-AttDef-AttType
the-AttDef-DefaultDecl
]
)
]
[54] AttType:
[
StringType
( the-AttType: the-StringType )
|
TokenizedType
( the-AttType: the-TokenizedType )
|
EnumeratedType
( the-AttType: the-EnumeratedType )
]
[55] StringType:
[
copy the-StringType "CDATA"
]
[56] TokenizedType:
[
copy the-TokenizedType
[ "IDREFS"
| "IDREF"
| "ID"
| "ENTITY"
| "ENTITIES"
| "NMTOKENS"
| "NMTOKEN"
]
]
[57] EnumeratedType:
[
NotationType
( the-EnumeratedType: the-NotationType )
|
Enumeration
( the-EnumeratedType: the-Enumeration )
]
[58] NotationType:
[
( the-NotationType: make block! [] )
"NOTATION"
S
"("
opt S
Name
( append the-NotationType the-Name )
any
[
opt S
"|"
opt S
Name
(
repend the-NotationType [ '| the-Name ]
)
]
opt S
")"
]
[59] Enumeration:
[
(
the-Enumeration: make block! []
)
"("
opt S
Nmtoken
(
append the-Enumeration the-Nmtoken
)
any
[
opt S
"|"
opt S
Nmtoken
(
repend the-Enumeration [ '| the-Nmtoken ]
)
]
opt S
")"
]
[60] DefaultDecl:
[
"#REQUIRED"
( the-DefaultDecl: reduce [ "#REQUIRED" none ] )
( print "This attribute is required!" )
|
"#IMPLIED"
( the-DefaultDecl: reduce [ "#IMPLIED" none ] )
( print "This attribute is optional." )
( print [{If omitted, applications guesses a default!}] )
|
"#FIXED"
S AttValue
( the-DefaultDecl: reduce [ "#FIXED" the-AttValue ] )
(
print [
{This attr. is required fixed to the value "}
the-AttValue {" .}
]
)
|
AttValue
(
the-DefaultDecl: reduce [ none the-AttValue ]
print [
"This attribute is optional."
{If omitted, this attribute defaults to "}
the-AttValue {" .}
]
)
]
[66] CharRef:
[
copy the-CharRef
[
"&#" some CharRefDigit! ";"
]
(
the-CharRef: to-char to-integer
head remove back tail
remove/part the-CharRef 2
)
]
[66.1] CharRefDigit!: charset [ #"0" - #"9" ]
[67] Reference:
[
EntityRef
(
the-Reference: the-EntityRef
)
|
CharRef
(
the-Reference: the-CharRef
)
]
[68] EntityRef:
[
copy the-EntityRef the-EntityRefs
(
the-EntityRef: select the-EntityRefs the-EntityRef
)
]
[69] PEReference: [ copy the-PEReference [ "%" Name ";" ] ]
[70] EntityDecl:
[
GEDecl
(
append the-EntityRefs reduce
[
'|
rejoin
[
"&" the-GEDecl-Name ";"
]
to-paren mold the-GEDecl-EntityDef
]
)
|
PEDecl
(
append the-PEReferences reduce
[
'|
rejoin
[
"%"
the-PEDecl-Name ";"
]
to-paren mold the-PEDecl-PEDef
]
)
]
[71] GEDecl:
[
"<!ENTITY"
S
Name
(
the-GEDecl-Name: the-Name
)
S
EntityDef
(
the-GEDecl-EntityDef: the-EntityDef
)
opt S
">"
]
[72] PEDecl:
[
"<!ENTITY"
S
"%"
S
Name
(
the-PEDecl-Name: the-Name
)
S
PEDef
(
the-PEDecl-PEDef: the-PEDef
)
opt S
">"
]
[73] EntityDef:
[
[
EntityValue
(
the-EntityDef: the-EntityValue
)
|
ExternalID
opt NDataDecl
]
]
[74] PEDef:
[
[
EntityValue
(
the-PEDef: the-EntityValue
)
|
ExternalID
]
]
[75] ExternalID:
[
"SYSTEM" S SystemLiteral
|
"PUBLIC" S PubidLiteral S SystemLiteral
]
[76] NDataDecl:
[
S
"NDATA"
S
Name
( the-NDataDecl: the-Name )
]
[77] TextDecl:
[
"<?xml" opt VersionInfo EncodingDecl opt S "?>"
]
[80] EncodingDecl:
[
S
"encoding"
Eq
[ {"} EncName {"} | "'" EncName "'" ]
]
[81.1] EncChar!: charset [ #"A" - #"Z" #"a" - #"z" ]
[81.2] EncChars!: charset
[
#"A" - #"Z" #"a" - #"z" #"0" - #"9" "._-"
]
[81] EncName:
[
copy the-EncName [ EncChar! some EncChars! ]
]
[82] NotationDecl: [
"<!NOTATION"
S
Name
S
[ ExternalID | PublicID ]
opt S
">"
]
[83] PublicID: [ "PUBLIC" S PubidLiteral ]
[84] Letter!: [ BaseChar! | Ideographic! ]
[85] BaseChar!: charset
[
#"A" - #"Z"
#"a" - #"z"
#"À" - #"Ö"
#"Ĝ" - #"ö"
#"ĝ" - #"˙"
]
[86] Ideographic!: charset [ ]
[87] CombiningChar!: charset [ ]
[88] Digit!: charset [ #"0" - #"9" ]
[89] Extender!: charset [ #"·" ]
]
-- Attached file included as plaintext by Listar --
-- File: xml-test.xml
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE test [
<!ENTITY ME "Christian Ensel">
<!ELEMENT che:money ANY>
<!ATTLIST che:money che:currency CDATA "USD"
che:amount CDATA #REQUIRED
>
]>
<space:name>
This is some text typed by &ME;.
<che:money xmlns:che = "http://www.foo.bar"
che:amount = "0.02"
che:currency = "USD"
>
My two cents?!?
<element attribute="<1>" />
</che:money>
</space:name>
--
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with "unsubscribe" in the
subject, without the quotes.