<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns="https://gitlab.com/danieljrmay/xmlsrc"
    targetNamespace="https://gitlab.com/danieljrmay/xmlsrc"
    elementFormDefault="qualified">

  <xsd:annotation>
    <xsd:appinfo>XMLSRC — XML Source</xsd:appinfo>
    <xsd:documentation xml:lang="en">
      This schema defines XMLSRC (XML Source) a way of representing
      the source code of an XML document. This is useful if you want
      to display the source code of a XML document or fragment within
      a browser. It requires an appropriate CSS stylesheet, see
      https://gitlab.com/danieljrmay/xmlsrc/css/xmlsrc.css for an
      example. The design of XMLSRC is such that all the parameters of
      the XML files e.g. element tag names, attribute names and
      values, character data, processing instructions and comments are
      represented by text nodes within XMLSRC. The control characters
      of an XML file e.g. angle brackets, equals signs, etc. are
      provided by the CSS stylesheet.

      Along with XMLSRC there exists MXS (Minified XML Source) which
      is exactly the same as XMLSRC, apart from that the element names
      have been shortened to a single character to minimise filesize,
      memory consumption and processing speed at the expense of human
      readability.
    </xsd:documentation>
  </xsd:annotation>

  <xsd:attributeGroup name="xmlsrcAttributes">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	This attribute group contains attributes which can be used on
	several XMLSRC element types.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:attribute name="display" type="xsd:boolean" default="true"/>
  </xsd:attributeGroup>
  
  <xsd:element name="xmlsrc">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"xmlsrc" is the root element of all XMLSRC documents or document
	fragments.
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:complexType>
      <xsd:sequence>
	<xsd:element ref="xmlDeclaration" minOccurs="0"/>
	<xsd:element ref="documentTypeDeclaration" minOccurs="0"/>
	<xsd:group ref="elementContentGroup" minOccurs="0" maxOccurs="unbounded"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="xmlDeclaration">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"xmlDeclaration" represents an XML declaration. The version
	number is fixed as "1.0" as this schema only allows XML 1.0
	compatible characters.
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:complexType>
      <xsd:sequence>
	<xsd:element name="version" type="xsd:string" fixed="1.0"/>
	<xsd:element ref="encoding" minOccurs="0"/>
	<xsd:element ref="standalone" minOccurs="0"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
  
  <xsd:element name="encoding">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"encoding" represents the encoding specified by an XML declaration.
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:simpleType>
      <xsd:restriction base="xsd:string">
	<xsd:pattern value="[A-Za-z][A-Za-z0-9._\-]*"/>
      </xsd:restriction>
    </xsd:simpleType>
  </xsd:element>

  <xsd:element name="standalone">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"standalone" represents the standalone parameter of an XML
	declaration.
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:simpleType>
      <xsd:restriction base="xsd:string">
	<xsd:enumeration value="yes"/>
	<xsd:enumeration value="no"/>
      </xsd:restriction>
    </xsd:simpleType>
  </xsd:element>

  <xsd:element name="documentTypeDeclaration">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"documentTypeDeclaration" represents a DOCTYPE declaration in
	an XML document.
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:complexType>
      <xsd:sequence>
	<xsd:element ref="name"/>
	<xsd:choice minOccurs="0">
	  <xsd:element ref="systemExternalEntity"/>
	  <xsd:element ref="publicExternalEntity"/>
	</xsd:choice>
	<xsd:element ref="internalSubset" minOccurs="0"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="systemExternalEntity">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"systemExternalEntity" represents a SYSTEM external entity
	declaration within a DOCTYPE declaration.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:complexType>
      <xsd:sequence>
	<xsd:element ref="systemLiteral"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="publicExternalEntity">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"publicExternalEntity" represents a PUBLIC external entity
	declaration within a DOCTYPE declaration.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:complexType>
      <xsd:sequence>
	<xsd:element ref="pubIdLiteral"/>
	<xsd:element ref="systemLiteral"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="systemLiteral">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"systemLiteral" represents the system literal in an external
	entity declaration part of a DOCTYPE declaration.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:simpleType>
      <xsd:restriction base="xsd:string">
	<xsd:pattern value='[^"]*'/>
      </xsd:restriction>
    </xsd:simpleType>
  </xsd:element>
  
  <xsd:element name="pubIdLiteral">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"pubIdLiteral" represents a public ID literal in an external
	entity declaration part of a DOCTYPE declaration.
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:simpleType>
      <xsd:restriction base="xsd:string">
	<xsd:pattern value="[A-Za-z0-9/._\-\s]*"/><!-- TODO: https://www.w3.org/TR/xml/#NT-PubidChar -->
      </xsd:restriction>
    </xsd:simpleType>
  </xsd:element>

  <xsd:element name="internalSubset" type="xsd:string">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"internalSubset" represents an internal subset declaration
	part of a DOCTYPE declaration.
      </xsd:documentation>
    </xsd:annotation>    
  </xsd:element>
  
  <xsd:group name="elementContentGroup">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"elementContentGroup" represents the possible content of a
	non-empty element not including the start and end tags.
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:choice>
      <xsd:element ref="cdata"/>
      <xsd:element ref="comment"/>
      <xsd:element ref="element"/>
      <xsd:element ref="processingInstruction"/>
      <xsd:element ref="text"/>
    </xsd:choice>
  </xsd:group>

  <xsd:element name="element">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"element" represents any kind of element: with children or
	empty, with a namespace prefix or without.
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:complexType>
      <xsd:choice>
	<xsd:element ref="emptyTag"/>
	<xsd:element ref="prefixedEmptyTag"/>
	<xsd:sequence>
	  <xsd:element ref="startTag"/>
	  <xsd:group ref="elementContentGroup" minOccurs="0" maxOccurs="unbounded"/>
	  <xsd:element ref="endTag"/>
	</xsd:sequence>	
	<xsd:sequence>
	  <xsd:element ref="prefixedStartTag"/>
	  <xsd:group ref="elementContentGroup" minOccurs="0" maxOccurs="unbounded"/>
	  <xsd:element ref="prefixedEndTag"/>
	</xsd:sequence>	
      </xsd:choice>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="emptyTag">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"emptyTag" represents an empty elements tag when that element
	does not have a namespace prefix.
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:complexType>
      <xsd:sequence>
	<xsd:element ref="name"/>
	<xsd:element ref="defaultNamespace" minOccurs="0"/>
	<xsd:element ref="namespace" minOccurs="0" maxOccurs="unbounded"/>
	<xsd:element ref="attribute" minOccurs="0" maxOccurs="unbounded"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="startTag">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"startTag" represents an element's start tag when that element
	has children and does not have a namespace prefix.
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:complexType>
      <xsd:sequence>
	<xsd:element ref="name"/>
	<xsd:element ref="defaultNamespace" minOccurs="0"/>
	<xsd:element ref="namespace" minOccurs="0" maxOccurs="unbounded"/>
	<xsd:element ref="attribute" minOccurs="0" maxOccurs="unbounded"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="endTag">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"endTag" represents an element's end tag when that element
	does not have a namespace prefix.
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:complexType>
      <xsd:sequence>
	<xsd:element ref="name"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="prefixedEmptyTag">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"prefixedEmptyTag" represents an empty elements tag when that element
	has a namespace prefix.
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:complexType>
      <xsd:sequence>
	<xsd:element ref="prefix"/>
	<xsd:element ref="name"/>
	<xsd:element ref="defaultNamespace" minOccurs="0"/>
	<xsd:element ref="namespace" minOccurs="0" maxOccurs="unbounded"/>
	<xsd:element ref="attribute" minOccurs="0" maxOccurs="unbounded"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="prefixedStartTag">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"prefixedStartTag" represents an elements start tag when that element
	has children and has a namespace prefix.	
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:complexType>
      <xsd:sequence>
	<xsd:element ref="prefix"/>
	<xsd:element ref="name"/>
	<xsd:element ref="defaultNamespace" minOccurs="0"/>
	<xsd:element ref="namespace" minOccurs="0" maxOccurs="unbounded"/>
	<xsd:element ref="attribute" minOccurs="0" maxOccurs="unbounded"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="prefixedEndTag">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"prefixedEndTag" represents an elements end tag when that element
	has children and has a namespace prefix.		
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:complexType>
      <xsd:sequence>
	<xsd:element ref="prefix"/>
	<xsd:element ref="name"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="defaultNamespace">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"defaultNamespace" represents a default namespace declaration
	i.e. one without a prefix.
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:complexType>
      <xsd:sequence>
	<xsd:element ref="uri"/>
      </xsd:sequence>
      <xsd:attributeGroup ref="xmlsrcAttributes"/>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="namespace">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"namespace" represents a namespace declaration with a prefix,
	you must use "defaultNamespace" to represent default namespace
	declaration i.e. one without a prefix.
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:complexType>
      <xsd:sequence>
	<xsd:element ref="prefix"/>
	<xsd:element ref="uri"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="uri" type="xsd:anyURI">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"uri" represents a namespace uri.
      </xsd:documentation>
    </xsd:annotation>    
  </xsd:element>

  <xsd:element name="attribute">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"attribute" represents any kind of attribute: with a namespace
	prefix or without.
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:complexType>
      <xsd:sequence>
	<xsd:element ref="prefix" minOccurs="0"/>
	<xsd:element ref="name"/>
	<xsd:element ref="value"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="name">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"name" represents the local name of an attribute.
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:simpleType>
      <xsd:restriction base="xsd:string">
	<xsd:pattern value="[A-Za-z][A-Za-z0-9._\-]*"/><!-- TODO: https://www.w3.org/TR/xml/#NT-Name -->
      </xsd:restriction>
    </xsd:simpleType>
  </xsd:element>

  <xsd:element name="value">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"value" represents the value of an attribute.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:complexType mixed="true">
      <xsd:sequence>
	<xsd:element ref="entity" minOccurs="0" maxOccurs="unbounded"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="prefix">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"prefix" represents a namespace prefix.
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:simpleType>
      <xsd:restriction base="xsd:string">
	<xsd:pattern value="[A-Za-z][^:]*"/><!-- TODO: See https://www.w3.org/TR/xml-names/#ns-decl -->
      </xsd:restriction>
    </xsd:simpleType>
  </xsd:element>
  
  <xsd:element name="cdata">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"cdata" represents a CDATA section.
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:simpleType>
      <xsd:restriction base="xsd:string">
	<xsd:pattern value=".*"/><!-- TODO: https://www.w3.org/TR/xml/#NT-CData  -->
      </xsd:restriction>
    </xsd:simpleType>
  </xsd:element>

  <xsd:element name="comment">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"comment" represents an XML comment.
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:simpleType>
      <xsd:restriction base="xsd:string">
	<xsd:pattern value=".*"/><!-- TODO: https://www.w3.org/TR/xml/#NT-Char -->
      </xsd:restriction>
    </xsd:simpleType>
  </xsd:element>

  <xsd:element name="text">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"text" represents a text node.
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:complexType mixed="true">
      <xsd:sequence>
	<xsd:element ref="entity" minOccurs="0" maxOccurs="unbounded"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="processingInstruction">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"processingInstruction" represents a processing instruction node.
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:complexType>
      <xsd:sequence>
	<xsd:element name="target"/>
	<xsd:element name="data"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="target">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"target" represents the target of a processing instruction.
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:simpleType>
      <xsd:restriction base="xsd:string">
	<xsd:pattern value="[A-Za-z][A-Za-z0-9._\-]*"/><!-- TODO: https://www.w3.org/TR/xml/#NT-Name with NOT XML or xml -->
      </xsd:restriction>
    </xsd:simpleType>
  </xsd:element>

  <xsd:element name="data">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"data" represents the data of a processing instruction.
      </xsd:documentation>
    </xsd:annotation>    
    <xsd:simpleType>
      <xsd:restriction base="xsd:string">
	<xsd:pattern value=".*"/><!-- TODO: https://www.w3.org/TR/xml/#NT-Name with NOT XML or xml -->
      </xsd:restriction>
    </xsd:simpleType>
  </xsd:element>

  <xsd:element name="entity">
    <xsd:annotation>
      <xsd:documentation xml:lang="en">
	"entity" represents a numeric character reference or
	character entity reference.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:complexType>
      <xsd:simpleContent>
	<xsd:extension base="xsd:string"> <!-- TODO: Add RegExp restriction to only allow legal entity reference forms. -->
	  <xsd:attribute name="title" type="xsd:string"/>
	</xsd:extension>
      </xsd:simpleContent>
    </xsd:complexType>
  </xsd:element>

</xsd:schema>
