Relax NG Compact

The name of a Relax NG Compact document ends with “.rnc”.
This illustrates the basic semantics of Relax NG Compact.
<?xml version="1.0" ?>
<emailsList>
<person id="232133">
<firstName>Adam</firstName>
<lastName>Khoo</lastName>
<email>adamkhoo@yahoo.com</email>
<sex>M</sex>
<scores>88 97</scores>
<description>
This is a <b>smart guy</b>.
</description>
<VIP/>
</person>
<person>
<id>234023</id>
<name>Serena</name>
<email>serena@yahoo.com</email>
<sex>  F  </sex>
<scores>50 78.5</scores>
</person>
</emailsList>
datatypes xs=
"http://www.w3.org/2001/XMLSchema-datatypes" element emailsList {
element person {
(element id {xs:integer} |   # a comment
attribute id {xs:integer}),
(element name {text} |
(element firstName {text} &
element lastName {text})),
element email {
xsd:string {
minLength="5"
maxLength="125"}
},
element sex {string "M" | "F"},
element scores {
list {xsd:float, xsd:float}
},
element description{
mixed {element b{text}}
}?,
element VIP {empty}?
}*
}
* denotes zero or more.
+ denotes one or more.
? denotes zero or one.
() denotes grouping.
, denotes a sequence.
| denotes a choice.
& denotes interleaving (out-of-order sequence).
# denotes  a comment
‘xsd’ is a built-in datatypes library. Its URI is "http://www.w3.org/2001/XMLSchema-datatypes".
The ‘string’ before “M” means that there must not be spaces before and after “M”.
The order of elements in a sequence (denoted by ,) is significant. The order of attributes in a sequence is not.

This is a rather complex example that demonstrates the various ways to use references.
<?xml version="1.0"?>
<!-- badminton.xml --> <badminton id="3432">
<players.min>2</players.min>
<players.max>4</players.max>
</badminton>
#badminton1.rnc
element badminton {
external "badminton2.rnc"
}
#badminton2.rnc
grammar {
include "badminton3.rnc" {
idd = attribute id{text}
}
pNum &= element players.min {text}
pNum &= idd
start = pNum
}
#badminton3.rnc
grammar {
pNum=element players.max {text}
idd=element id {text}
}
‘external’ references another .rnc document as if the content of that document is at the current place. ‘include’ allows grammars to be merged. The optional {…} clause next to ‘include’ overrides the included definitions. The content designator, ‘start’, can be replaced likewise.
&= combines the definitions, interleaving them.
|= combines the definitions, joining them with |.
In a grammar definition, there can be recursive references within an element. Eg.:
inline = element span {inline | text}
To use keywords such as ‘element’, ‘attribute’, ‘text’, ‘empty’, ‘grammar’ as the name of a definition, it must be prefixed with \, Eg.:
start = \element
\element = element element {text}
In a nested grammar, to use the definition from the parent, prefix the name with ‘parent ’.
‘notAllowed’ is typically used to allow an including pattern to specify additional choices with |=. Eg.:
grammar {
inline =notAllowed       # inline.rnc
}
----------------------------------------------
grammar {
include “inline.rnc”
inline |= element code {inline} | element em {inline}
}

This illustrates various ways to use namespaces.
<?xml version="1.0"?>
<book xmlns="http://example2.com">
<title xmlns="http://example1.com">
Web Coding Bible
</title>
<genre xmlns="http://example1.com">
Manual
</genre>
</book>
#book.rnc
namespace a = "http://example1.com"
default namespace = "http://example2.com" element book {
element a:title {text},
external "book2.rnc" inherit = a
}
#book2.rnc
namespace c = inherit
element c:genre {text}
Unless ‘inherit’ed explicitly, a namespace declaration applies only to the file in which it appears. A file referenced using ‘include’ or ‘external’ cannot take advantage of the namespace declarations of the referencing file.
A default namespace does not apply to attributes. The attribute name in an attribute declaration must be prefixed with the namespace prefix if so desired.
      default namespace eg = “http://example.com”
is equivalent to
default namespace = “http://example.com”
namespace eg = “http://example.com”
In the example above, ‘inherit = a’ can be omitted if the default namespace is to be inherited instead.

* can be used to denote any element or any attribute.
<?xml version="1.0"?>
<house id="100">
<type>bungalow</type>
<cost xmlns="http://example.com">500000</cost>
<area>10000</area>
</house>
namespace a = "http://example.com"
element house {
attribute * {text}+,      #any attribute
element * {text},         #any element
element (a:*|*) {text}, #union of namespaces
element * - a:* {text}  #difference
}

This shows how to use annotations.
namespace an = "http://example.com"
grammar {
[an:dummy = "elements"]
div {
a = element a {text}
an:entity [name=”picture”]
b = element b {text}
}
[an:dummy = "attributes"]
div {
c = attribute c {text}
d = attribute d {text}
}
start = a
}
   ## This is the documentation syntax.
element a {text}
is equivalent to
namespace d=
”http://relaxng.org/ns/compatibility/annotations/1.0”
[d:documentation [ This is documentation syntax.”]]
element a {text}
      “Line 1\x{A}” ~ “Line 2”
is equivalent to
‘‘‘Line 1
Line 2‘‘‘
and
“““Line 1
Line 2“““
Here, \x{A} denotes an escaped newline, and ~ concatenation. String literals can be delimited by triple quotes.