<!ENTITY % char-instructions "
  | apply-templates
  | call-template
  | apply-imports
  | for-each
  | value-of
  | copy-of
  | number
  | choose
  | if
  | text
  | copy
  | variable
  | message
  | fallback
">

<!ENTITY % instructions "
  %char-instructions;
  | processing-instruction
  | comment
  | element
  | attribute
">

<!ENTITY % char-template "
 (#PCDATA
  %char-instructions;)*
">

<!ENTITY % template "
 (#PCDATA
  %instructions;
  %result-elements;)*
">

<!-- Used for the type of an attribute value that is a URI reference.-->
<!ENTITY % URI "CDATA">

<!-- Used for the type of an attribute value that is a pattern.-->
<!ENTITY % pattern "CDATA">

<!-- Used for the type of an attribute value that is an
     attribute value template.-->
<!ENTITY % avt "CDATA">

<!-- Used for the type of an attribute value that is a QName; the prefix
     gets expanded by the XSLT processor. -->
<!ENTITY % qname "NMTOKEN">

<!-- Like qname but a whitespace-separated list of QNames. -->
<!ENTITY % qnames "NMTOKENS">

<!-- Used for the type of an attribute value that is an expression.-->
<!ENTITY % expr "CDATA">

<!-- Used for the type of an attribute value that consists
     of a single character.-->
<!ENTITY % char "CDATA">

<!-- Used for the type of an attribute value that is a priority. -->
<!ENTITY % priority "NMTOKEN">

<!ENTITY % space-att "xml:space (default|preserve) #IMPLIED">

<!-- This may be overridden to customize the set of elements allowed
at the top-level. -->

<!ENTITY % non-xsl-top-level "">

<!ENTITY % top-level "
 (import*,
  (include
  | strip-space
  | preserve-space
  | output
  | key
  | decimal-format
  | attribute-set
  | variable
  | param
  | template
  | namespace-alias
  %non-xsl-top-level;)*)
">

<!ENTITY % top-level-atts '
  extension-element-prefixes CDATA #IMPLIED
  exclude-result-prefixes CDATA #IMPLIED
  id ID #IMPLIED
  version NMTOKEN #REQUIRED
  xmlns:xsl CDATA #FIXED "http://www.w3.org/1999/XSL/Transform"
  %space-att;
'>

<!-- This entity is defined for use in the ATTLIST declaration
for result elements. -->

<!ENTITY % result-element-atts '
  extension-element-prefixes CDATA #IMPLIED
  exclude-result-prefixes CDATA #IMPLIED
  use-attribute-sets %qnames; #IMPLIED
  version NMTOKEN #IMPLIED
'>

<!ELEMENT stylesheet %top-level;>
<!ATTLIST stylesheet %top-level-atts;>

<!ELEMENT transform %top-level;>
<!ATTLIST transform %top-level-atts;>

<!ELEMENT import EMPTY>
<!ATTLIST import href %URI; #REQUIRED>

<!ELEMENT include EMPTY>
<!ATTLIST include href %URI; #REQUIRED>

<!ELEMENT strip-space EMPTY>
<!ATTLIST strip-space elements CDATA #REQUIRED>

<!ELEMENT preserve-space EMPTY>
<!ATTLIST preserve-space elements CDATA #REQUIRED>

<!ELEMENT output EMPTY>
<!ATTLIST output
  method %qname; #IMPLIED
  version NMTOKEN #IMPLIED
  encoding CDATA #IMPLIED
  omit-xml-declaration (yes|no) #IMPLIED
  standalone (yes|no) #IMPLIED
  doctype-public CDATA #IMPLIED
  doctype-system CDATA #IMPLIED
  cdata-section-elements %qnames; #IMPLIED
  indent (yes|no) #IMPLIED
  media-type CDATA #IMPLIED
>

<!ELEMENT key EMPTY>
<!ATTLIST key
  name %qname; #REQUIRED
  match %pattern; #REQUIRED
  use %expr; #REQUIRED
>

<!ELEMENT decimal-format EMPTY>
<!ATTLIST decimal-format
  name %qname; #IMPLIED
  decimal-separator %char; "."
  grouping-separator %char; ","
  infinity CDATA "Infinity"
  minus-sign %char; "-"
  NaN CDATA "NaN"
  percent %char; "%"
  per-mille %char; "&#x2030;"
  zero-digit %char; "0"
  digit %char; "#"
  pattern-separator %char; ";"
>

<!ELEMENT namespace-alias EMPTY>
<!ATTLIST namespace-alias
  stylesheet-prefix CDATA #REQUIRED
  result-prefix CDATA #REQUIRED
>

<!ELEMENT template
 (#PCDATA
  %instructions;
  %result-elements;
  | param)*
>

<!ATTLIST template
  match %pattern; #IMPLIED
  name %qname; #IMPLIED
  priority %priority; #IMPLIED
  mode %qname; #IMPLIED
  %space-att;
>

<!ELEMENT value-of EMPTY>
<!ATTLIST value-of
  select %expr; #REQUIRED
  disable-output-escaping (yes|no) "no"
>

<!ELEMENT copy-of EMPTY>
<!ATTLIST copy-of select %expr; #REQUIRED>

<!ELEMENT number EMPTY>
<!ATTLIST number
   level (single|multiple|any) "single"
   count %pattern; #IMPLIED
   from %pattern; #IMPLIED
   value %expr; #IMPLIED
   format %avt; '1'
   lang %avt; #IMPLIED
   letter-value %avt; #IMPLIED
   grouping-separator %avt; #IMPLIED
   grouping-size %avt; #IMPLIED
>

<!ELEMENT apply-templates (sort|with-param)*>
<!ATTLIST apply-templates
  select %expr; "node()"
  mode %qname; #IMPLIED
>

<!ELEMENT apply-imports EMPTY>

<!-- sort cannot occur after any other elements or
any non-whitespace character -->

<!ELEMENT for-each
 (#PCDATA
  %instructions;
  %result-elements;
  | sort)*
>

<!ATTLIST for-each
  select %expr; #REQUIRED
  %space-att;
>

<!ELEMENT sort EMPTY>
<!ATTLIST sort
  select %expr; "."
  lang %avt; #IMPLIED
  data-type %avt; "text"
  order %avt; "ascending"
  case-order %avt; #IMPLIED
>

<!ELEMENT if %template;>
<!ATTLIST if
  test %expr; #REQUIRED
  %space-att;
>

<!ELEMENT choose (when+, otherwise?)>
<!ATTLIST choose %space-att;>

<!ELEMENT when %template;>
<!ATTLIST when
  test %expr; #REQUIRED
  %space-att;
>

<!ELEMENT otherwise %template;>
<!ATTLIST otherwise %space-att;>

<!ELEMENT attribute-set (attribute)*>
<!ATTLIST attribute-set
  name %qname; #REQUIRED
  use-attribute-sets %qnames; #IMPLIED
>

<!ELEMENT call-template (with-param)*>
<!ATTLIST call-template
  name %qname; #REQUIRED
>

<!ELEMENT with-param %template;>
<!ATTLIST with-param
  name %qname; #REQUIRED
  select %expr; #IMPLIED
>

<!ELEMENT variable %template;>
<!ATTLIST variable
  name %qname; #REQUIRED
  select %expr; #IMPLIED
>

<!ELEMENT param %template;>
<!ATTLIST param
  name %qname; #REQUIRED
  select %expr; #IMPLIED
>

<!ELEMENT text (#PCDATA)>
<!ATTLIST text
  disable-output-escaping (yes|no) "no"
>

<!ELEMENT processing-instruction %char-template;>
<!ATTLIST processing-instruction
  name %avt; #REQUIRED
  %space-att;
>

<!ELEMENT element %template;>
<!ATTLIST element
  name %avt; #REQUIRED
  namespace %avt; #IMPLIED
  use-attribute-sets %qnames; #IMPLIED
  %space-att;
>

<!ELEMENT attribute %char-template;>
<!ATTLIST attribute
  name %avt; #REQUIRED
  namespace %avt; #IMPLIED
  %space-att;
>

<!ELEMENT comment %char-template;>
<!ATTLIST comment %space-att;>

<!ELEMENT copy %template;>
<!ATTLIST copy
  %space-att;
  use-attribute-sets %qnames; #IMPLIED
>

<!ELEMENT message %template;>
<!ATTLIST message
  %space-att;
  terminate (yes|no) "no"
>

<!ELEMENT fallback %template;>
<!ATTLIST fallback %space-att;>
