<?xml version="1.0"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.gerdcastan.de/MusiXML"
        xmlns:MusiXML="http://www.gerdcastan.de/MusiXML"
        version="0.2"
	 elementFormDefault = "qualified">


<!-- 			xmlns:xml="http://www.w3.org/XML/1998/namespace" 
 -->


<!-- update 11. April 2000: key/keyref example for stRef 
	update 16. April 2000: included MFraction and Duration, added some attribute defaults.
     20010902 extract must start with a bibdata element that describes for which part/instrument 
              this extract is intended. Example: Violin 1 or Score
     20010904 removed lines from thRef. lines in staff is enough.
     20010904 removed voice from thRef. If something human readable is necesary, make it language independant
     20010907 replaced t by tm, tn, td. My Java application had no problem, but avoiding microparsing makes MusiXML XSLT friendly
     20010907 same vor staff.start
     20010908 replaced level by breakLevel
     20010908 resetPageNo
     20010910 extractId
     20011016 changed syntax to xml schema 1.0;
     20011016 changed xml:lang to lang until I get it running with Xerces
     20021214 Version 0.2: Major revision. Runs with Xerces now and uses xml:lang again.

-->

<import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/>
<attributeGroup name="xml-atts">
	<attribute ref="xml:lang"/>
	<attribute ref="xml:space"/>
</attributeGroup> 

<annotation>
	<documentation>
	MusiXML schema v0.2 for music notation. Last change 14-Dec-2002.
	Experimental implementation
	Copyright 1999 - 2009 Gerd Castan.
	</documentation>
</annotation>

<!-- XXX the src attribute in an stRef element has to refer to a unique staff element.
	It was not possible to express this in a DTD with ID/IDREF:

	stRef.src -> staff.id
	thRef.src -> thread.id
	bracket.start -> staff.id
	bracket.end -> staff.id
	conRef.src -> con.id
	lasting.tupletID -> tuplet.id (elements derived from lasting: chord and note)
	lasting.beam -> beam.id (elements derived from lasting: chord and note)
	barRef.barID -> bar.id
	slur.left -> note.id
	slur.right -> note.id
	
	I will use key/keyref pairs for this, but this means that I have to drop the
	ID/IDREF mechanism in the DTD, too.
	
	See the stRef key below.
-->


<!-- main hierarchy: use anonymous types where elements are used only once -->
<element name="work">
	<complexType>
	<complexContent>
	<extension base="MusiXML:core">
	<sequence>
		<element ref="MusiXML:bibdata" minOccurs="0"  maxOccurs="1" />

		<element name="body" minOccurs="1" maxOccurs="1" >
			<complexType>
	        <complexContent>
			<extension base="MusiXML:core">
			<sequence>
				<element name="workSeg" minOccurs="1">
					<complexType>
        	        <complexContent>
					<extension base="MusiXML:core">
					<sequence>
						<element name="masterThread" minOccurs="1" maxOccurs="1">
							<!-- time dependant elements that occur only once per score -->
							<!-- and influence each extract -->
							<complexType>
		        	        <complexContent>
							<extension base="MusiXML:core">
								<choice maxOccurs="unbounded">
									<element ref="MusiXML:masterSymbol" />  <!-- abstract -->
									<element ref="MusiXML:sharedSymbol" />  <!-- abstract -->
								</choice>
							</extension>
		        	        </complexContent>
							</complexType>
						</element>
						<!-- A program in LISP ;-) uses the word "Musician" for a similar (not exactly the same) thing. -->
						<element name="thread" minOccurs="1" maxOccurs="unbounded">
							<complexType>
		        	        <complexContent>
							<extension base="MusiXML:core">
								<choice maxOccurs="unbounded">
									<element ref="MusiXML:threadSymbol" />  <!-- abstract -->
									<element ref="MusiXML:sharedSymbol" />  <!-- abstract -->
								</choice>
							</extension>
		        	        </complexContent>
							</complexType>
						</element> <!-- thread -->
					</sequence>
					</extension>
        	        </complexContent>
					</complexType>
				</element> <!-- workSeg -->
			</sequence>
			</extension>
	        </complexContent>
			</complexType>
		</element> <!-- body -->

		<element name="filter" minOccurs="1" maxOccurs="1" >
			<complexType>
		    <complexContent>
			<extension base="MusiXML:core">
			<sequence>
				<element name="extract" minOccurs="0" maxOccurs="unbounded" >
					<complexType>
				    <complexContent>
					<extension base="MusiXML:core">
					<sequence>
						<element ref="MusiXML:bibdata" minOccurs="1" maxOccurs="1" />
						<element name="paragraph" minOccurs="1" maxOccurs="unbounded" >
							<complexType>
						    <complexContent>
							<extension base="MusiXML:core">
							<sequence>
								<element ref="MusiXML:bibdata" minOccurs="0" maxOccurs="1" />
								<element name="bracket" minOccurs="0" maxOccurs="1">
									<complexType>
								    <complexContent>
									<extension base="MusiXML:core">
										<attribute name="type" type="string"  />   <!-- XXX (bracket|brace)    "bracket"  -->
										<attribute name="start" type="IDREF" use="required" />
										<attribute name="end" type="IDREF" use="required"  />
									</extension>
									</complexContent>
									</complexType>
								</element>
								<element name="break" minOccurs="0" maxOccurs="unbounded">
									<complexType>
								    <complexContent>
									<extension base="MusiXML:momentOfTime">
										<attribute name="breakLevel" type="NMTOKEN" />   <!-- XXX (dontBreak|lineBreak|pageBreak)    "lineBreak"  -->
										<attribute name="resetPageNo" type="integer" /> 
										<attribute name="man_pg" type="integer" /> 
										<attribute name="man_ln" type="integer" /> 
										<attribute name="aut_pg" type="integer" /> 
										<attribute name="aut_ln" type="integer" /> 
									</extension>
									</complexContent>
									</complexType>
								</element>
								<element name="stRef" minOccurs="0" maxOccurs="unbounded">
									<complexType>
								    <complexContent>
									<extension base="MusiXML:core">
										<attribute name="src" type="IDREF" use="required"  />
									</extension>
									</complexContent>
									</complexType>
								</element>
							</sequence>
								<attribute name="type" type="string" use="required"  /> 
							</extension>
							</complexContent>
							</complexType>
						</element>
					</sequence>

						<attribute name='extractId' type="NMTOKEN" use="required"/>
					</extension>
					</complexContent>
					</complexType>
				</element> <!-- extract -->
		
				<element name="staff" minOccurs="0" maxOccurs="unbounded" >
					<complexType>
				    <complexContent>
					<extension base="MusiXML:core">
					<sequence>
						<element name="thRef" minOccurs="0" maxOccurs="unbounded" >
							<complexType>
						    <complexContent>
							<extension base="MusiXML:core">
								<attribute name="src" type="IDREF" use="required"  /> 
								<attribute name="stem" type="NMTOKEN" /> <!-- XXX (auto|up|down)     "auto" -->
							</extension>
							</complexContent>
							</complexType>
						</element>
						<element name="conRef" minOccurs="0" maxOccurs="unbounded" >
							<complexType>
						    <complexContent>
							<extension base="MusiXML:Con">
								<attribute name="src" type="IDREF" use="required"  /> 
							</extension>
							</complexContent>
							</complexType>
						</element>
					</sequence>
						<attribute name="name" type="NMTOKEN" /> <!-- new key, replacement for id in DTD -->
						<attribute name="startm" type="short" /> 
						<attribute name="startn" type="short" /> 
						<attribute name="startd" type="short" /> 
						<attribute name="lines" type="short" /> <!-- defauld 5 -->
					</extension>
				    </complexContent>
					</complexType>
				</element> <!-- staff -->
			</sequence>
			</extension>
		    </complexContent>
			</complexType>

			<key name="staff.name">
				<selector xpath="staff" />
				<field xpath="@name" />
			</key>
			<keyref name="stRef.src" refer="MusiXML:staff.name">
				<selector xpath="extract/paragraph/stRef" />
				<field xpath="@src" />
			</keyref>
			<key name="extractRef">
				<selector xpath="extract" />
				<field xpath="@extractId" />
			</key>
			
		</element> <!-- filter -->
	</sequence>
	</extension>
	</complexContent>
	</complexType>	

</element> <!-- work -->

<!-- ================================================================================= -->
<!--core type                                                                          -->
<!-- ================================================================================= -->

<!-- everything but localText is derived by core -->
<complexType name="core">
	<attribute name="lang" />
	<attribute name="id" type="ID" />
</complexType>



<!-- ================================================================================= -->
<!-- types                                                                             -->
<!-- ================================================================================= -->

<!-- everything child of masterThread and thread is derived by momentOfTime -->
<complexType name="momentOfTime">
<complexContent>
<extension base="MusiXML:core">
	<attribute name="tm" type="short" /> 
	<attribute name="tn" type="short" /> 
	<attribute name="td" type="short" /> 
</extension>
</complexContent>
</complexType>

<!-- Duration
	first number: enumerator (1 if omitted)
	second number: denominator (4 if omitted)
	dots: number of dots
-->
<simpleType name="Duration">
	<restriction base="string">
    	<pattern value="[0-9]*(:[0-9]*)?\.*"/>
	</restriction>
</simpleType>

<!-- XXX chord and note are derived by lasting -->
<complexType name="lasting">
<complexContent>
<extension base="MusiXML:momentOfTime">
	<attribute name="dots" type="integer" />   <!-- XXX restrict -->
	<attribute name="dur" type="MusiXML:Duration" />
	<attribute name="tupletID" type="IDREF" />  <!-- XXX referential integrity --> 
	<attribute name="beam" type="IDREF" />  <!-- XXX referential integrity --> 
	<attribute name="leftBeams" type="integer" />   
	<attribute name="rightBeams" type="integer" />   
	<attribute name="abbrev" type="integer" />   
	<!-- XXX articulation -->
	<attributeGroup ref="MusiXML:articulation" />
</extension>
</complexContent>
</complexType>

<!-- articulation:
     staccato="1" finger1="2" means the first sign above the note is a staccato point 
     and the second is a "1" (finger 1). The same holds with negative numbers under
     the note. 
     Exception: numtonguing is the number of points whereas tonguing indicates the 
     position of these tonguing points. 
  -->
<attributeGroup name="articulation">
	<attribute name="strongaccent" type="integer" />   
	<attribute name="mediumaccent" type="integer" />   
	<attribute name="portato" type="integer" />   
	<attribute name="staccato" type="integer" />   
	<attribute name="downbow" type="integer" />   
	<attribute name="upbow" type="integer" />   
	<attribute name="harmonic" type="integer" />   
	<attribute name="fermata" type="integer" />   
	<attribute name="arsis" type="integer" />   
	<attribute name="thesis" type="integer" />   
	<attribute name="plus" type="integer" />   
	<attribute name="staccatissimo" type="integer" />   
	<attribute name="tonguing" type="integer" />   
	<attribute name="numtonguing" type="integer" />   
	<attribute name="pizzicato" type="integer" />   
	<attribute name="finger1" type="integer" />   
	<attribute name="finger2" type="integer" />   
	<attribute name="finger3" type="integer" />   
	<attribute name="finger4" type="integer" />   
	<attribute name="finger5" type="integer" />   
</attributeGroup>

<!-- Bar is used for elements bar and barRef -->
<complexType name="Bar">
<complexContent>
<extension base="MusiXML:momentOfTime">
	<attribute name="type">
		<simpleType>
			<restriction base="NMTOKEN">
				<enumeration value="standard"/>
				<enumeration value="invisible"/>
				<enumeration value="tactus"/>
				<enumeration value="double"/>
				<enumeration value="fat"/>
				<enumeration value="fatthin"/>
			</restriction>
		</simpleType>
	</attribute>

	<attribute name="leftRepeat" type="integer" />
	<attribute name="rightRepeat" type="integer" />
	<attribute name="count" type="boolean" />
</extension>
</complexContent>
</complexType>


<complexType name="Con">
<complexContent>
<extension base="MusiXML:momentOfTime">
	<attribute name="vis" type="NMTOKEN" />    <!-- XXX (nothing|clef|key) -->
	<attribute name="cname" type="string" />
	<attribute name="coct" type="NMTOKEN" />   <!-- XXX (S|s|K|g|k|1|2|3|4|5) -->
	<attribute name="clefLine" type="integer" /> <!-- XXX short? -->
	<attribute name="kacc" type="integer" />    <!-- XXX (-7|-6|-5|-4|-3|-2|-1|0|1|2|3|4|5|6|7) -->
	<attribute name="kname" type="string" />
	<attribute name="sign1" type="string" />    <!-- XXX notename -->
	<attribute name="sign2" type="string" />    <!-- XXX notename -->
	<attribute name="sign3" type="string" />    <!-- XXX notename -->
	<attribute name="sign4" type="string" />    <!-- XXX notename -->
	<attribute name="sign5" type="string" />    <!-- XXX notename -->
	<attribute name="sign6" type="string" />    <!-- XXX notename -->
	<attribute name="sign7" type="string" />    <!-- XXX notename -->
</extension>
</complexContent>
</complexType>




<!-- ================================================================================= -->
<!-- masterSymbol and equivalent classes                                               -->
<!-- ================================================================================= -->

<!-- a masterSymbol is an element that may only occur as child of masterThread -->
<element name="masterSymbol" abstract="true" type="MusiXML:momentOfTime" />

<!-- element name="bar" equivClass="MusiXML:masterSymbol" type="MusiXML:Bar" / -->
<element name="bar" substitutionGroup="MusiXML:masterSymbol" type="MusiXML:Bar" />



<!-- ================================================================================= -->
<!-- sharedSymbol and equivalent classes                                               -->
<!-- ================================================================================= -->

<!-- a sharedSymbol is an element that may occur as child of masterThread or thread respectively -->
<element name="sharedSymbol" abstract="true" type="MusiXML:momentOfTime" />

<!--element name="dynamics" equivClass="sharedSymbol" -->
<element name="dynamics" substitutionGroup="MusiXML:sharedSymbol" >
	<complexType>
	<complexContent>
	<extension base="MusiXML:momentOfTime">
		<attribute name="name" type="string" />   <!-- XXX replace string enum -->
	</extension>
	</complexContent>
	</complexType>
</element>


<!-- repeat can contain all signs related to repetitions or omissions.
     The only exception are the repeat signs around the bar.
     Text positioning depends on the sign.
  -->
<!-- element name="repeat" equivClass="sharedSymbol" -->
<element name="repeat" substitutionGroup="MusiXML:sharedSymbol" >
	<complexType>
	<complexContent>
	<extension base="MusiXML:momentOfTime">
		<sequence>
		<element name="localText" type="MusiXML:LocalTextType" minOccurs="0" maxOccurs="1" />
		</sequence>
		<attribute name="sign" type="NMTOKEN" default="empty" />   <!-- XXX replace by (empty|segno|dalsegno|coda|tocoda|start_klammer|end_klammer|dacapo|fine|dcalfinesenzarep|dcalfine|dcsenzarep|vi|de) "empty"  -->
	</extension>
	</complexContent>
	</complexType>
</element>


<!-- chordSymbol: a text String that describes a chord -->
<!-- element name="chordSymbol" equivClass="sharedSymbol" -->
<element name="chordSymbol" substitutionGroup="MusiXML:sharedSymbol">
	<complexType>
	<complexContent>
	<extension base="MusiXML:momentOfTime">
		<attribute name="name" type="string" />   <!-- XXX replace by regular expression -->
	</extension>
	</complexContent>
	</complexType>
</element>

<!-- register:
     name: machine readable, language independant name
     style: some register signs can be rendered with a square or a circle around.
  -->
<!-- element name="register" equivClass="sharedSymbol" -->
<element name="register" substitutionGroup="MusiXML:sharedSymbol">
	<complexType>
	<complexContent>
	<extension base="MusiXML:momentOfTime">
		<sequence>
			<element   ref="MusiXML:description" minOccurs="0" maxOccurs="unbounded" />
		</sequence>
		<attribute name="pipeLen" type="string" /> 
		<attribute name="style" type="NMTOKEN" default="empty" /> <!-- XXX replace by (none|square|circle) "none" -->
	</extension>
	</complexContent>
	</complexType>
</element>




<!-- ================================================================================= -->
<!-- threadSymbol and equivalent classes                                               -->
<!-- ================================================================================= -->

<!-- a threadSymbol is an element that may occur as child of thread -->
<element name="threadSymbol" abstract="true" type="MusiXML:momentOfTime" />

<!-- element name="barRef" equivClass="threadSymbol" -->
<element name="barRef" substitutionGroup="MusiXML:threadSymbol" >
	<complexType>
	<complexContent>
	<extension base="MusiXML:Bar">
		<attribute name="barID" type="IDREF" />
	</extension>
	</complexContent>
	</complexType>
</element>


<!-- con:
     context definition: one tag for key and clef.
     the reason to put key and clef together is that there are clefs like S
     which define clef and key together.
     vis indicates whether a clef or a key (or nothing) is visually rendered.
     NB: it is allowed to set the context without rendering. 
     cname, coct: name of a clef. Some, like "G" 
     TODO: allow an additional parameter for octave shifts.
     clefLine: allows to assign a "G" key to a line different from 2
     kacc: key accidentals
     kname: key name
	 * examples:
	 * kacc=0 & name = "C"   -> c Major
	 * kacc=0 & name = "a"   -> a Minor
	 * kacc=0 & name = ... -> church keys
	 sign1 ... sign7:
	 * acc and name can't represent the examples in Gardner Read: Music Notation Chapter 9 page 141ff (second edition)
	 * so you can provide seven independant note names instead of
	 * counting sharps or flats with kacc

  -->
<!-- element name="con" equivClass="threadSymbol" type="Con" -->
<element name="con" substitutionGroup="MusiXML:threadSymbol" type="MusiXML:Con" >
</element>

<!-- chord:
     each note is encapsulated by a chord. This makes programming easier.
  -->
<!-- element name="chord" equivClass="threadSymbol" -->
<element name="chord" substitutionGroup="MusiXML:threadSymbol">
	<complexType>
	<complexContent>
	<extension base="MusiXML:lasting">
		<sequence>
			<element   ref="MusiXML:note" minOccurs="1" maxOccurs="unbounded" />
		</sequence>
	</extension>
	</complexContent>
	</complexType>
</element>


<!-- note:
  -->
<element name="note">
	<complexType>
	<complexContent>
	<extension base="MusiXML:lasting">
		<attribute name="name" type="string" /> <!-- XXX %noteName; -->
		<attribute name="oct" type="NMTOKEN" /> <!-- XXX replace by (S|s|K|g|k|1|2|3|4|5) -->
		<attribute name="chord" type="string" /> <!-- XXX %chordString; -->
	</extension>
	</complexContent>
	</complexType>
</element>


<!-- beam:
     defines an ID that groups chords/notes together
  -->
<!-- element name="beam" equivClass="threadSymbol" type="momentOfTime" -->
<element name="beam" substitutionGroup="MusiXML:threadSymbol" type="MusiXML:momentOfTime">
</element>

<!-- slur:
     groups notes left and (right) together
     if tie = "false", right mus be provided
  -->
<!-- element name="slur" equivClass="threadSymbol" -->
<element name="slur" substitutionGroup="MusiXML:threadSymbol" >
	<complexType>
	<complexContent>
	<extension base="MusiXML:momentOfTime">
		<attribute name="left" type="IDREF" use="required" />
		<attribute name="right" type="IDREF"  />
		<attribute name="tie" type="boolean" />
	</extension>
	</complexContent>
	</complexType>
</element>



<!-- ================================================================================= -->
<!-- general elements bibdata, description and LocalTextType                           -->
<!-- ================================================================================= -->

<!-- bibdata is referred several times and provides an aothors name and internationalized text
     it is a referred element instead of a complex type since its name 
     should not be changed for readability of the instance
  -->
<element name="bibdata">
	<complexType>
	<complexContent>
	<extension base="MusiXML:core">
		<sequence>
		<element name="localText" type="MusiXML:LocalTextType" maxOccurs="unbounded" />  <!-- XXX change name for readability -->
		</sequence>
		<attribute name="author" type="string" />
	</extension>
	</complexContent>
	</complexType>
</element>


<element name="description">
	<complexType>
	<complexContent>
	<extension base="MusiXML:core">
		<sequence>
		<element name="localText" type="MusiXML:LocalTextType" />  <!-- XXX change name for readability -->
		</sequence>
		<attribute name="align" type="string" default="right" /> <!-- XXX (left|right|bottom|top) "right" -->
	</extension>
	</complexContent>
	</complexType>
</element>


<!-- LocalTextType is referred several times and provides internationalized text -->
<complexType name="LocalTextType">
	<simpleContent>
	<extension base="string">
	<!-- no coreattrs -->
		<attribute ref="xml:lang" />
	</extension>
	</simpleContent>
</complexType>




<!-- ================================================================================= -->
<!-- Test                                                                              -->
<!-- ================================================================================= -->

</schema>
