# document, min length 3
document ::= (prolog | EMPTY) (misc)* element (misc)* ;

# prolog, min length 3
prolog ::= XMLDeclOpen (attribute)* "?>" ;

# misc, min length 1
misc ::= (COMMENT | "?>" | SEA_WS) ;

# element, min length 3
element ::= ( "<" Name (attribute)* ">" content "<" "/" Name ">"
	| "<" Name (attribute)* "/>") ;

# XMLDeclOpen, min length 2
XMLDeclOpen ::= "<?xml" S ;

# attribute, min length 5
attribute ::= Name "=" STRING ;

# content, min length 0
content ::= (chardata | EMPTY) ((element | reference | CDATA | "?>" | COMMENT) (chardata | EMPTY))* ;

# chardata, min length 1
chardata ::= (TEXT | SEA_WS) ;

# reference, min length 3
reference ::= (EntityRef | CharRef) ;

# CDATA, min length 2
CDATA ::= "<![CDATA[" ANY "]]>" ;

# COMMENT, min length 2
COMMENT ::= "<!--" (DOT)* "-->" ;

# Name, min length 1
Name ::= NameStartChar (NameChar)* ;

# EntityRef, min length 3
EntityRef ::= "&" Name ";" ;

# CharRef, min length 3
CharRef ::= ("&#" DIGIT (DIGIT)* ";" | "&#x" HEXDIGIT (HEXDIGIT)* ";") ;

# STRING, min length 3
STRING ::= ("\"" TEXT "\"" | "'" TEXT "'") ;

# TEXT, min length 1
TEXT ::= DOT (DOT)* ;

# SEA_WS, min length 1
SEA_WS ::= (" " | "\t" | ("\r" | EMPTY) "\n") ((" " | "\t" | ("\r" | EMPTY) "\n"))* ;

# DOT, min length 1
DOT ::= (some_alpha | some_digit | some_punc | some_multibyte) ;

# some_alpha, min length 1
some_alpha ::= (("W" | "X" | "Y" | "Z") | ("w" | "x" | "y" | "z")) ;

# some_digit, min length 1
some_digit ::= ("0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9") ;

# some_punc, min length 1
some_punc ::= ("\"" | "'" | "," | "/" | ":" | ";") ;

# some_multibyte, min length 1
some_multibyte ::= [\u203F-\u2040] ;

# ANY, min length 0
ANY ::= (DOT)* ;

# DIGIT, min length 1
DIGIT ::= ("0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9") ;

# HEXDIGIT, min length 1
HEXDIGIT ::= ( ("0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9")
	| ("A" | "B" | "C" | "D" | "E" | "F")
	| ("a" | "b" | "c" | "d" | "e" | "f")) ;

# S, min length 1
S ::= [ \t\r\n] ;

# NameStartChar, min length 1
NameStartChar ::= ( ( (":")
	| ( "A"
	| "B"
	| "C"
	| "D"
	| "E"
	| "F"
	| "G"
	| "H"
	| "I"
	| "J"
	| "K"
	| "L"
	| "M"
	| "N"
	| "O"
	| "P"
	| "Q"
	| "R"
	| "S"
	| "T"
	| "U"
	| "V"
	| "W"
	| "X"
	| "Y"
	| "Z")
	| ( "a"
	| "b"
	| "c"
	| "d"
	| "e"
	| "f"
	| "g"
	| "h"
	| "i"
	| "j"
	| "k"
	| "l"
	| "m"
	| "n"
	| "o"
	| "p"
	| "q"
	| "r"
	| "s"
	| "t"
	| "u"
	| "v"
	| "w"
	| "x"
	| "y"
	| "z"))
	| [\u2070-\u218F]
	| [\u2C00-\u2FEF]
	| [\u3001-\uD7FF]
	| [\uF900-\uFDCF]
	| [\uFDF0-\uFFFD]) ;

# NameChar, min length 1
NameChar ::= ( NameStartChar
	| "-"
	| "_"
	| "."
	| DIGIT
	| "\xb7"
	| [\u0300-\u036F]
	| [\u203F-\u2040]) ;

# EMPTY, min length 0
EMPTY ::= /* empty */ ;


