[1]     document           ::= prolog element Misc*

[2]     Char               ::= #x9 | #xA | #xD
                             | [#x20-#xD7FF]
                             | [#xE000-#xFFFD]
                             | [#x10000-#x10FFFF]

[3]     S                  ::= (#x20 | #x9 | #xD | #xA)+

[4]     NameStartChar      ::= ":" | [A-Z] | "_" | [a-z]
                             | [#xC0-#xD6]
                             | [#xD8-#xF6]
                             | [#xF8-#x2FF]
                             | [#x370-#x37D]
                             | [#x37F-#x1FFF]
                             | [#x200C-#x200D]
                             | [#x2070-#x218F]
                             | [#x2C00-#x2FEF]
                             | [#x3001-#xD7FF]
                             | [#xF900-#xFDCF]
                             | [#xFDF0-#xFFFD]
                             | [#x10000-#xEFFFF]

[4a]    NameChar           ::= NameStartChar
                             | "-" | "." | [0-9]
                             | #xB7
                             | [#x0300-#x036F]
                             | [#x203F-#x2040]

[5]     Name               ::= NameStartChar (NameChar)*

[6]     Names              ::= Name (#x20 Name)*

[7]     Nmtoken            ::= (NameChar)+

[8]     Nmtokens           ::= Nmtoken (#x20 Nmtoken)*

[9]     EntityValue        ::= '"' ([^%&"] | PEReference | Reference)* '"'
                             | "'" ([^%&'] | PEReference | Reference)* "'"

[10]    AttValue           ::= '"' ([^<&"] | Reference)* '"'
                             | "'" ([^<&'] | Reference)* "'"

[11]    SystemLiteral      ::= ('"' [^"]* '"') | ("'" [^']* "'")

[12]    PubidLiteral       ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"

[13]    PubidChar          ::= #x20 | #xD | #xA
                             | [a-zA-Z0-9]
                             | [-'()+,./:=?;!*#@$_%]

[14]    CharData           ::= [^<&]* - ([^<&]* ']]>' [^<&]*)

[15]    Comment            ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'

[16]    PI                 ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'

[17]    PITarget           ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))

[18]    CDSect             ::= CDStart CData CDEnd

[19]    CDStart            ::= '<![CDATA['

[20]    CData              ::= (Char* - (Char* ']]>' Char*))

[21]    CDEnd              ::= ']]>'

[22]    prolog             ::= XMLDecl? Misc* (doctypedecl Misc*)?

[23]    XMLDecl            ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'

[24]    VersionInfo        ::= S 'version' Eq ("'" VersionNum "'" | '"' VersionNum '"')

[25]    Eq                 ::= S? '=' S?

[26]    VersionNum         ::= '1.' [0-9]+

[27]    Misc               ::= Comment | PI | S

[28]    doctypedecl        ::= '<!DOCTYPE' S Name (S ExternalID)? S? ('[' intSubset ']' S?)? '>'

[28a]       DeclSep        ::= PEReference | S

[28b]       intSubset      ::= (markupdecl | DeclSep)*

[29]    markupdecl         ::= elementdecl
                             | AttlistDecl
                             | EntityDecl
                             | NotationDecl
                             | PI
                             | Comment

[30]    extSubset          ::= TextDecl? extSubsetDecl

[31]    extSubsetDecl      ::= ( markupdecl | conditionalSect | DeclSep)*

[32]    SDDecl             ::= S 'standalone' Eq (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no') '"'))

[39]    element            ::= EmptyElemTag
                             | STag content ETag

[40]    STag               ::= '<' Name (S Attribute)* S? '>'

[41]    Attribute          ::= Name Eq AttValue

[42]    ETag               ::= '</' Name S? '>'

[43]    content            ::= CharData? ((element | Reference | CDSect | PI | Comment) CharData?)*

[44]    EmptyElemTag       ::= '<' Name (S Attribute)* S? '/>'

[45]    elementdecl        ::= '<!ELEMENT' S Name S contentspec S? '>'

[46]    contentspec        ::= 'EMPTY' | 'ANY' | Mixed | children

[47]    children           ::= (choice | seq) ('?' | '*' | '+')?

[48]    cp                 ::= (Name | choice | seq) ('?' | '*' | '+')?

[49]    choice             ::= '(' S? cp ( S? '|' S? cp )+ S? ')'

[50]    seq                ::= '(' S? cp ( S? ',' S? cp )* S? ')'

[51]    Mixed              ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*'
                             | '(' S? '#PCDATA' S? ')'

[52]    AttlistDecl        ::= '<!ATTLIST' S Name AttDef* S? '>'

[53]    AttDef             ::= S Name S AttType S DefaultDecl

[54]    AttType            ::= StringType | TokenizedType | EnumeratedType

[55]    StringType         ::= 'CDATA'

[56]    TokenizedType      ::= 'ID'
                             | 'IDREF'
                             | 'IDREFS'
                             | 'ENTITY'
                             | 'ENTITIES'
                             | 'NMTOKEN'
                             | 'NMTOKENS'

[57]    EnumeratedType     ::= NotationType | Enumeration

[58]    NotationType       ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'

[59]    Enumeration        ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'

[60]    DefaultDecl        ::= '#REQUIRED' | '#IMPLIED'
                             | (('#FIXED' S)? AttValue)

[61]    conditionalSect    ::= includeSect | ignoreSect

[62]    includeSect        ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'

[63]    ignoreSect         ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'

[64]    ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*

[65]    Ignore             ::= Char* - (Char* ('<![' | ']]>') Char*)

[66]    CharRef            ::= '&#' [0-9]+ ';'
                             | '&#x' [0-9a-fA-F]+ ';'

[67]    Reference          ::= EntityRef | CharRef

[68]    EntityRef          ::= '&' Name ';'

[69]    PEReference        ::= '%' Name ';'

[70]    EntityDecl         ::= GEDecl | PEDecl

[71]    GEDecl             ::= '<!ENTITY' S Name S EntityDef S? '>'

[72]    PEDecl             ::= '<!ENTITY' S '%' S Name S PEDef S? '>'

[73]    EntityDef          ::= EntityValue | (ExternalID NDataDecl?)

[74]    PEDef              ::= EntityValue | ExternalID

[75]    ExternalID         ::= 'SYSTEM' S SystemLiteral
                             | 'PUBLIC' S PubidLiteral S SystemLiteral

[76]    NDataDecl          ::= S 'NDATA' S Name

[77]    TextDecl           ::= '<?xml' VersionInfo? EncodingDecl S? '?>'

[78]    extParsedEnt       ::= TextDecl? content

[80]    EncodingDecl       ::= S 'encoding' Eq ('"' EncName '"' | "'" EncName "'" )

[81]    EncName            ::= [A-Za-z] ([A-Za-z0-9._] | '-')*

[82]    NotationDecl       ::= '<!NOTATION' S Name S (ExternalID | PublicID) S? '>'

[83]    PublicID           ::= 'PUBLIC' S PubidLiteral

# Extensions for namespaces

[1]     NSAttName          ::= PrefixedAttName
                             | DefaultAttName

[2]     PrefixedAttName    ::= 'xmlns:' NCName

[3]     DefaultAttName     ::= 'xmlns'

[4]     NCName             ::= Name - (Char* ':' Char*)

[7]     QName              ::= PrefixedName
                             | UnprefixedName

[8]     PrefixedName       ::= Prefix ':' LocalPart

[9]     UnprefixedName     ::= LocalPart

[10]    Prefix             ::= NCName

[11]    LocalPart          ::= NCName

[12]    STag               ::= '<' QName (S Attribute)* S? '>'

[13]    ETag               ::= '</' QName S? '>'

[14]    EmptyElemTag       ::= '<' QName (S Attribute)* S? '/>'

[15]    Attribute          ::= NSAttName Eq AttValue
                             | QName Eq AttValue

[16]    doctypedecl        ::= '<!DOCTYPE' S QName (S ExternalID)? S? ('[' (markupdecl | PEReference | S)* ']' S?)? '>'

[17]    elementdecl        ::= '<!ELEMENT' S QName S contentspec S? '>'

[18]    cp                 ::= (QName | choice | seq) ('?' | '*' | '+')?

[19]    Mixed              ::= '(' S? '#PCDATA' (S? '|' S? QName)* S? ')*'
                             | '(' S? '#PCDATA' S? ')'

[20]    AttlistDecl        ::= '<!ATTLIST' S QName AttDef* S? '>'

[21]    AttDef             ::= S (QName | NSAttName) S AttType S DefaultDecl
