<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://purl.oclc.org/dsdl/schematron" xmlns:sch="http://purl.oclc.org/dsdl/schematron">
	
	<!-- schema -->
	<xs:element name="schema">
		<xs:complexType>
			<xs:sequence>
				<xs:element minOccurs="0" maxOccurs="1" ref="sch:title"/>
				<xs:element minOccurs="0" maxOccurs="1" ref="sch:diagnostics"/>
				<xs:sequence minOccurs="1" maxOccurs="unbounded">
					<xs:choice minOccurs="0" maxOccurs="unbounded">
						<xs:group ref="sch:foreign"/>
						<xs:element ref="sch:include"/>
						<xs:choice minOccurs="0" maxOccurs="unbounded">
							<xs:element ref="sch:ns"/>
							<xs:element ref="sch:p"/>
							<xs:element ref="sch:let"/>
							<xs:element ref="sch:phase"/>
						</xs:choice>
					</xs:choice>
					<xs:element ref="sch:pattern"/>
				</xs:sequence>
			</xs:sequence>
			<xs:attribute name="id" type="xs:ID"/>
			<xs:attributeGroup ref="sch:rich"/>
			<xs:attribute name="schemaVersion" type="sch:non-empty-string"/>
			<xs:attribute name="defaultPhase" type="xs:IDREF"/>
			<xs:attribute name="queryBinding" type="sch:non-empty-string"/>
			<xs:attributeGroup ref="sch:foreign"/>
		</xs:complexType>
	</xs:element>
	
	<!-- active -->
	<xs:element name="active">
		<xs:complexType mixed="true">
			<xs:choice minOccurs="0" maxOccurs="unbounded">
				<xs:group ref="sch:foreign"/>
				<xs:choice>
					<xs:element ref="sch:dir"/>
					<xs:element ref="sch:emph"/>
					<xs:element ref="sch:span"/>
				</xs:choice>
			</xs:choice>
			<xs:attribute name="pattern" use="required" type="xs:IDREF"/>
			<xs:attributeGroup ref="sch:foreign"/>
		</xs:complexType>
	</xs:element>
	
	<!-- assert -->
	<xs:element name="assert">
		<xs:annotation>
			<xs:documentation>An assertion made about the context nodes. The data content is a natural-language assertion.
			The required test attribute is an assertion test evaluated in the current context. If the test evaluates positive (true),
			the assertion is added. The optional diagnostics attribute is a reference to further diagnostic information.</xs:documentation>
		</xs:annotation>
		<xs:complexType mixed="true">
			<xs:choice minOccurs="0" maxOccurs="unbounded">
				<xs:group ref="sch:foreign"/>
				<xs:choice>
					<xs:element ref="sch:name"/>
					<xs:element ref="sch:value-of"/>
					<xs:element ref="sch:emph"/>
					<xs:element ref="sch:dir"/>
					<xs:element ref="sch:span"/>
				</xs:choice>
			</xs:choice>
			<xs:attribute name="test" use="required" type="sch:exprValue"/>
			<xs:attribute name="flag" type="sch:flagValue"/>
			<xs:attribute name="id" type="xs:ID"/>
			<xs:attribute name="diagnostics" type="xs:IDREFS"/>
			<xs:attributeGroup ref="sch:rich"/>
			<xs:attributeGroup ref="sch:linkable"/>
			<xs:attributeGroup ref="sch:foreign"/>
		</xs:complexType>
	</xs:element>
	
	<!-- diagnostic -->
	<xs:element name="diagnostic">
		<xs:complexType mixed="true">
			<xs:choice minOccurs="0" maxOccurs="unbounded">
				<xs:group ref="sch:foreign"/>
				<xs:choice>
					<xs:element ref="sch:value-of"/>
					<xs:element ref="sch:emph"/>
					<xs:element ref="sch:dir"/>
					<xs:element ref="sch:span"/>
				</xs:choice>
			</xs:choice>
			<xs:attribute name="id" use="required" type="xs:ID"/>
			<xs:attributeGroup ref="sch:rich"/>
		</xs:complexType>
	</xs:element>
  
	<!-- diagnostics -->
	<xs:element name="diagnostics">
		<xs:complexType>
			<xs:choice minOccurs="0" maxOccurs="unbounded">
				<xs:group ref="sch:foreign"/>
				<xs:element ref="sch:include"/>
				<xs:element ref="sch:diagnostic"/>
			</xs:choice>
		</xs:complexType>
	</xs:element>
  
	<xs:element name="dir">
		<xs:complexType mixed="true">
			<xs:group ref="sch:foreign"/>
			<xs:attribute name="value">
				<xs:simpleType>
					<xs:restriction base="xs:token">
					<xs:enumeration value="ltr"/>
					<xs:enumeration value="rtl"/>
					</xs:restriction>
				</xs:simpleType>
			</xs:attribute>
		</xs:complexType>
	</xs:element>
  
	<xs:element name="emph" type="xs:string"/>
  
	<xs:element name="extends">
		<xs:complexType>
			<xs:attribute name="rule" use="required" type="xs:IDREF"/>
			<xs:attributeGroup ref="sch:foreign-attributes"/>
		</xs:complexType>
	</xs:element>
  
	<xs:element name="let">
		<xs:annotation>
			<xs:documentation>A declaration of a named variable. If the let element is the child of a rule element,
			the variable is calculated and scoped to the current rule and context. Otherwise,
			the variable is calculated with the context of the instance document root. The required
			name attribute is the name of the variable. The required value attribute is an expression
			evaluated in the current context.</xs:documentation>
		</xs:annotation>
		<xs:complexType>
			<xs:attribute name="name" use="required" type="sch:nameValue"/>
			<xs:attribute name="value" use="required" type="xs:string"/>
		</xs:complexType>
	</xs:element>
  
	<xs:element name="name">
		<xs:complexType>
			<xs:attribute name="path" type="sch:pathValue"/>
		</xs:complexType>
	</xs:element>
  
	<xs:element name="ns">
		<xs:complexType>
			<xs:attribute name="uri" use="required" type="sch:uriValue"/>
			<xs:attribute name="prefix" use="required" type="sch:nameValue"/>
		</xs:complexType>
	</xs:element>
  
	<!-- p -->
	<xs:element name="p">
		<xs:annotation>
			<xs:documentation>A paragraph of natural language text containing maintainer and user information
			about the parent element. The schema can nominate paragraphs that should be rendered
			in a distinct way, keyed with the class attribute.
			An implementation is not required to make use of this element.</xs:documentation>
		</xs:annotation>
		<xs:complexType mixed="true">
			<xs:choice minOccurs="0" maxOccurs="unbounded">
				<xs:group ref="sch:foreign"/>
				<xs:choice>
					<xs:element ref="sch:dir"/>
					<xs:element ref="sch:emph"/>
					<xs:element ref="sch:span"/>
				</xs:choice>
			</xs:choice>
			<xs:attribute name="id" type="xs:ID"/>
			<xs:attribute name="class" type="sch:classValue"/>
			<xs:attribute name="icon" type="sch:uriValue"/>
			<xs:attributeGroup ref="sch:foreign"/>
		</xs:complexType>
	</xs:element>
  
	<xs:element name="param">
		<xs:annotation>
			<xs:documentation>A name-value pair providing parameters for an abstract pattern.
			The required name attribute is an XML name with no colon. The required value
			attribute is a fragment of a query.</xs:documentation>
		</xs:annotation>
		<xs:complexType>
			<xs:attribute name="name" use="required" type="sch:nameValue"/>
			<xs:attribute name="value" use="required" type="sch:non-empty-string"/>
		</xs:complexType>
	</xs:element>
  
	<xs:element name="pattern">
		<xs:annotation>
			<xs:documentation>
			A structure, simple or complex. A set of rules giving constraints that are in some way related.
			The id attribute provides a unique name for the pattern and is required for abstract patterns.
			</xs:documentation>
		</xs:annotation>
		<xs:complexType>
			<xs:choice minOccurs="0" maxOccurs="unbounded">
				<xs:group ref="sch:foreign"/>
				<xs:element ref="sch:include"/>
				<xs:element ref="sch:title"/>
				<xs:element ref="sch:p"/>
				<xs:element ref="sch:let"/>
				<xs:element ref="sch:param"/>
				<xs:element ref="sch:rule"/>
			</xs:choice>
			<xs:attributeGroup ref="sch:rich"/>
			<xs:attributeGroup ref="sch:foreign"/>
			<xs:attribute name="abstract">
				<xs:simpleType>
					<xs:restriction base="xs:token">
						<xs:enumeration value="true"/>
						<xs:enumeration value="false"/>
					</xs:restriction>
				</xs:simpleType>
			</xs:attribute>
			<xs:attribute name="id" type="xs:ID"/>
			<xs:attribute name="is-a" type="xs:IDREF"/>
		</xs:complexType>
	</xs:element>
  
	<xs:element name="phase">
		<xs:annotation>
			<xs:documentation>A grouping of patterns, to name and declare variations in schemas, for example,
			to support progressive validation. The required id attribute is the name of the phase.
			The implementation determines which phase to use for validating documents,
			for example by user command.</xs:documentation>
		</xs:annotation>
		<xs:complexType>
			<xs:choice minOccurs="0" maxOccurs="unbounded">
				<xs:group ref="sch:foreign"/>
				<xs:element ref="sch:include"/>
				<xs:choice>
					<xs:element ref="sch:p"/>
					<xs:element ref="sch:let"/>
					<xs:element ref="sch:active"/>
				</xs:choice>
			</xs:choice>
			<xs:attribute name="id" use="required" type="xs:ID"/>
			<xs:attributeGroup ref="sch:rich"/>
			<xs:attributeGroup ref="sch:foreign"/>
		</xs:complexType>
	</xs:element>
  
  <xs:element name="report">
	<xs:annotation>
		<xs:documentation>A report made about the context nodes. The data content is a natural-language assertion.
		The required test attribute is a report test evaluated in the current context. If the test evaluates negative (false),
		the report is added. The optional diagnostics attribute is a reference to further diagnostic information.</xs:documentation>
	</xs:annotation>
    <xs:complexType mixed="true">
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:group ref="sch:foreign"/>
        <xs:choice>
          <xs:element ref="sch:name"/>
          <xs:element ref="sch:value-of"/>
          <xs:element ref="sch:emph"/>
          <xs:element ref="sch:dir"/>
          <xs:element ref="sch:span"/>
        </xs:choice>
      </xs:choice>
      <xs:attribute name="test" use="required" type="sch:exprValue"/>
      <xs:attribute name="flag" type="sch:flagValue"/>
      <xs:attribute name="id" type="xs:ID"/>
      <xs:attribute name="diagnostics" type="xs:IDREFS"/>
      <xs:attributeGroup ref="sch:rich"/>
      <xs:attributeGroup ref="sch:linkable"/>
      <xs:attributeGroup ref="sch:foreign"/>
    </xs:complexType>
  </xs:element>
  
  <xs:element name="rule">
	<xs:annotation>
		<xs:documentation>
		A list of assertions tested within the context specified by the required context attribute.
		The context attribute specifies the rule context expression.
		</xs:documentation>
	</xs:annotation>
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:group ref="sch:foreign"/>
        <xs:element ref="sch:include"/>
        <xs:choice>
          <xs:choice>
            <xs:element ref="sch:let"/>
            <xs:choice>
              <xs:element ref="sch:assert"/>
              <xs:element ref="sch:report"/>
              <xs:element ref="sch:extends"/>
            </xs:choice>
          </xs:choice>
        </xs:choice>
      </xs:choice>
      <xs:attribute name="flag" type="sch:flagValue"/>
      <xs:attributeGroup ref="sch:rich"/>
      <xs:attributeGroup ref="sch:linkable"/>
      <xs:attributeGroup ref="sch:foreign"/>
      <xs:attribute name="abstract">
        <xs:simpleType>
          <xs:restriction base="xs:token">
            <xs:enumeration value="true"/>
            <xs:enumeration value="false"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="id" type="xs:ID"/>
      <xs:attribute name="context" type="sch:pathValue"/>
    </xs:complexType>
  </xs:element>
  
	<xs:element name="span">
		<xs:annotation>
			<xs:documentation>A portion of some paragraph that should be rendered in a distinct way,
			keyed with the class attribute.
			An implementation is not required to make use of this element.</xs:documentation>
		</xs:annotation>
		<xs:complexType mixed="true">
			<xs:group ref="sch:foreign"/>
			<xs:attribute name="class" use="required" type="sch:classValue"/>
			<xs:attributeGroup ref="sch:foreign"/>
		</xs:complexType>
	</xs:element>
  
	<xs:element name="title">
		<xs:complexType mixed="true">
			<xs:sequence>
				<xs:element minOccurs="0" maxOccurs="unbounded" ref="sch:dir"/>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
  
	<!-- value-of -->
	<xs:element name="value-of">
		<xs:complexType>
			<xs:attribute name="select" use="required" type="sch:pathValue"/>
			<xs:attributeGroup ref="sch:foreign-attributes"/>
		</xs:complexType>
	</xs:element>
	
	<!-- include -->
	<xs:element name="include">
		<xs:complexType>
			<xs:attribute name="href" use="required" type="sch:uriValue"/>
		</xs:complexType>
	</xs:element>
  
  <!-- common declarations -->
  <xs:attributeGroup name="rich">
    <xs:attribute name="icon" type="sch:uriValue"/>
    <xs:attribute name="see" type="sch:uriValue"/>
    <xs:attribute name="fpi" type="sch:fpiValue"/>
    <xs:attribute ref="sch:lang"/>
    <xs:attribute ref="sch:space"/>
  </xs:attributeGroup>
  
  <xs:attributeGroup name="linkable">
    <xs:attribute name="role" type="sch:roleValue"/>
    <xs:attribute name="subject" type="sch:pathValue"/>
  </xs:attributeGroup>
  
  <xs:group name="foreign">
    <xs:sequence>
      <xs:group minOccurs="0" maxOccurs="unbounded" ref="sch:foreign-element"/>
    </xs:sequence>
  </xs:group>
  
  <xs:attributeGroup name="foreign">
    <xs:attributeGroup ref="sch:foreign-attributes"/>
  </xs:attributeGroup>
  
  <xs:attributeGroup name="foreign-attributes">
    <xs:attributeGroup ref="sch:local"/>
  </xs:attributeGroup>
  
  <xs:group name="foreign-element">
    <xs:choice>
      <xs:any namespace="##other" processContents="skip"/>
      <xs:any namespace="##local" processContents="skip"/>
    </xs:choice>
  </xs:group>
  <!-- Data types -->
  <xs:simpleType name="uriValue">
    <xs:restriction base="xs:anyURI"/>
  </xs:simpleType>
  <xs:simpleType name="pathValue">
    <xs:restriction base="xs:string"/>
  </xs:simpleType>
  <xs:simpleType name="exprValue">
    <xs:restriction base="xs:string"/>
  </xs:simpleType>
  <xs:simpleType name="fpiValue">
    <xs:restriction base="xs:string"/>
  </xs:simpleType>
  <xs:simpleType name="langValue">
    <xs:restriction base="xs:language"/>
  </xs:simpleType>
  <xs:simpleType name="roleValue">
    <xs:restriction base="xs:string"/>
  </xs:simpleType>
  <xs:simpleType name="flagValue">
    <xs:restriction base="xs:string"/>
  </xs:simpleType>
  <xs:simpleType name="nameValue">
    <xs:restriction base="xs:string"/>
  </xs:simpleType>
  <!-- In the default query language binding, xsd:NCNAME -->
  <xs:simpleType name="classValue">
    <xs:restriction base="xs:string"/>
  </xs:simpleType>
  <xs:simpleType name="non-empty-string">
    <xs:restriction base="xs:token">
      <xs:minLength value="1"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:attribute name="lang" type="sch:langValue"/>
  <xs:attribute name="space">
    <xs:simpleType>
      <xs:restriction base="xs:token">
        <xs:enumeration value="preserve"/>
        <xs:enumeration value="default"/>
      </xs:restriction>
    </xs:simpleType>
  </xs:attribute>
  <xs:attributeGroup name="local">
    <xs:anyAttribute namespace="##other" processContents="skip"/>
  </xs:attributeGroup>  
</xs:schema>
