<addressBook> <card> <name>John Smith</name> <email>js@example.com</email> </card> <card> <name>Fred Bloggs</name> <email>fb@example.net</email> </card> </addressBook>
.rng
and .rnc
file extensions
XML Schema:
From relaxng.org:
Based on RELAX designed by OASIS-OPEN:
Now ISO standard:
RELAX NG home page (Key resource to Relax NG!):
RELAX NG — an excellent book by Eric van der Vlist:
Validators:
Editors, other tools:
(following samples from http://relaxng.org/compact-tutorial-20030326.html)
<addressBook> <card> <name>John Smith</name> <email>js@example.com</email> </card> <card> <name>Fred Bloggs</name> <email>fb@example.net</email> </card> </addressBook>
<!DOCTYPE addressBook [ <!ELEMENT addressBook (card*)> <!ELEMENT card (name, email)> <!ELEMENT name (#PCDATA)> <!ELEMENT email (#PCDATA)> ]>
element addressBook { element card { element name { text }, element email { text } }* }
If the addressBook is required to be non-empty, then we can use + instead of *:
element addressBook { element card { element name { text }, element email { text } }+ }
Now let’s change it to allow each card to have an optional note
element
[1] : Note that the text pattern matches arbitrary text, including empty text. Note also that whitespace separating tags is ignored when matching against a pattern.
[1]
element addressBook { element card { element name { text }, element email { text }, element note { text }? }* } # and this is a comment :-)
If we want to have a choice of two (more) alternatives
for one content model (eg. in card
):
<addressBook> <card> <givenName>John</givenName> <familyName>Smith</familyName> <email>js@example.com</email> </card> <card> <name>Fred Bloggs</name> <email>fb@example.net</email> </card> </addressBook>
element addressBook { element card { # here is the option (element name { text } | (element givenName { text }, element familyName { text })), element email { text }, element note { text }? }* }
Specifies that addressBook has attributes instead of elements:
element addressBook { element card { attribute name { text }, attribute email { text } }* }
name
and the email
part of a card
:
element addressBook { element card { (element name { text } | attribute name { text }), (element email { text } | attribute email { text }) }* }
<card name="John Smith" email="js@example.com"/> <card email="js@example.com" name="John Smith"/> <card email="js@example.com"><name>John Smith</name></card> <card name="John Smith"><email>js@example.com</email></card> <card><name>John Smith</name><email>js@example.com</email></card>
grammar { start = AddressBook AddressBook = element addressBook { Card* } Card = element card { Name, Email } Name = element name { text } Email = element email { text } }
The "inline" content is defined recursively [2] : This is, of course, allowed for elements only (attributes cannot be nested). [2].
inline = (text | element bold { inline } | element italic { inline } | element span { attribute style { text }?, # here is the recursion inline })*
element number { xsd:integer } element numberWithNote { xsd:int, attribute note { text } } element email { xsd:string { minLength = "6" maxLength = "127" } }
element card { attribute name { text }, attribute email { text }, attribute preferredFormat { "html" | "text" } }
element card { element name { text }, element email { text }, element preferredFormat { "html" | "text" } }
element list_of_two_floats { list { xsd:float, xsd:float } } element list_of_some_doubles { list { xsd:double+ } } element list_of_some_double_pairs { list { (xsd:double, xsd:double)+ } }
name
, email
element addressBook { element card { element name { text } & element email { text } }* }
start = inline inline = (text | element code { inline } | element em { inline } # etc )*
Then we could allow the note element to contain inline HTML markup by using external as follows:
element addressBook { element card { element name { text }, element email { text }, element note { external "inline.rnc" }? }* }
namespace eg = "http://www.example.com" element eg:foo { empty }
namespace = "http://www.example.com" element foo { empty }