<xsd:schema xmlns:xsd="http://www.w3.org/1999/XMLSchema"
            targetNamespace="http://gerd.castan.org/MusiXML"
            xmlns:MusiXML="http://gerd.castan.org/MusiXML">

<!-- update 11. April 2000: key/keyref example for stRef -->

<!-- oracle schema parser doesn't like annotations:
<xsd:annotation>
	<xsd:documentation>
	MusiXML schema v0.9 for music notation.
	Experimental implementation
	Copyright 1999 - 2000 Gerd Castan.
	</xsd:documentation>
</xsd: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 -->
<xsd:element name="work">
	<xsd:complexType base="core" derivedBy="extension">
		<xsd:element ref="bibdata" minOccurs="0" />

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

		<xsd:element name="filter" minOccurs="1" maxOccurs="1" >
			<xsd:complexType base="core" derivedBy="extension">

				<xsd:element name="extract" minOccurs="0" maxOccurs="*" >
					<xsd:complexType base="core" derivedBy="extension">
						<xsd:element name="paragraph" minOccurs="1" maxOccurs="*" >
							<xsd:complexType base="core" derivedBy="extension">
								<attribute name="type" type="string"  />   <!-- XXX type: "score" minOccurs="1"  -->
								<xsd:element ref="bibdata" minOccurs="0" maxOccurs="1" />
								<xsd:element name="bracket" minOccurs="0" maxOccurs="1">
									<xsd:complexType base="core" derivedBy="extension">
										<attribute name="type" type="string"  />   <!-- XXX (bracket|brace)    "bracket"  -->
										<attribute name="start" type="IDREF"  />   <!-- XXX minOccurs="1"  -->
										<attribute name="end" type="IDREF"  />   <!-- XXX minOccurs="1"  -->
									</xsd:complexType>
								</xsd:element>
								<xsd:element name="break" minOccurs="0" maxOccurs="*">
									<xsd:complexType base="core" derivedBy="extension">
										<attribute name="level" type="NMTOKEN" />   <!-- XXX (dontBreak|lineBreak|pageBreak)    "lineBreak"  -->
										<attribute name="man_pg" type="integer" /> 
										<attribute name="man_ln" type="integer" /> 
										<attribute name="aut_pg" type="integer" /> 
										<attribute name="aut_ln" type="integer" /> 
									</xsd:complexType>
								</xsd:element>
								<xsd:element name="stRef" minOccurs="0" maxOccurs="*">
									<xsd:complexType base="core" derivedBy="extension">
										<attribute name="src" type="IDREF"  />   <!-- XXX minOccurs="1"  -->
									</xsd:complexType>
								</xsd:element>
							</xsd:complexType>
						</xsd:element>
					</xsd:complexType>
				</xsd:element> <!-- extract -->
				
				<xsd:element name="staff" minOccurs="0" maxOccurs="*" >
					<xsd:complexType base="core" derivedBy="extension">
						<xsd:attribute name="name" type="NMTOKEN" /> <!-- new key, replacement for id in DTD -->
						<xsd:element name="thRef" minOccurs="0" maxOccurs="*" >
							<xsd:complexType base="core" derivedBy="extension">
								<attribute name="src" type="IDREF"  />   <!-- XXX minOccurs="1"  -->
								<attribute name="lines" type="integer" /> <!-- XXX "5" -->
								<attribute name="stem" type="NMTOKEN" /> <!-- XXX (auto|up|down)     "auto" -->
								<attribute name="voice" type="string" /> 
							</xsd:complexType>
						</xsd:element>
						<xsd:element name="conRef" minOccurs="0" maxOccurs="*" >
							<xsd:complexType base="Con" derivedBy="extension">
								<attribute name="src" type="IDREF"  />   <!-- XXX minOccurs="1"  -->
							</xsd:complexType>
						</xsd:element>
					</xsd:complexType>
				</xsd:element> <!-- staff -->
			</xsd:complexType>


<!-- oracles XML Schema 0.9 doesn't recognize key and keyref 
			<key name="stRef">
				<selector>extract/staff</selector>
				<field>@name</field>
			</key>
			<keyref refer="stRef">
				<selector>extract/paragraph/stRef</selector>
				<field>@src</field>
			</keyref>
-->

			
		</xsd:element> <!-- filter -->
	</xsd:complexType>	

</xsd:element> <!-- work -->



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

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



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

<!-- everything child of masterThread and thread is derived by momentOfTime -->
<xsd:complexType name="momentOfTime" base="core" derivedBy="extension">
	<attribute name="t" type="string" />   <!-- XXX replace string by regular expression for mFraction -->
</xsd:complexType>

<!-- XXX chord and note are derived by lasting -->
<xsd:complexType name="lasting" base="momentOfTime" derivedBy="extension">
	<attribute name="dots" type="integer" />   <!-- XXX restrict -->
	<attribute name="dur" type="string" />   <!-- XXX %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="articulation" />
</xsd: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 -->
<xsd:complexType name="Bar" base="momentOfTime" derivedBy="extension">
<!--
<Line 64, Column 25>: XSD-2027: (Error) Invalid element 'simpleType' in 'attribute'
	<attribute name="type">
		<simpleType base="NMTOKEN">
			<enumeration value="standard"/>
			<enumeration value="invisible"/>
			<enumeration value="tactus"/>
			<enumeration value="double"/>
			<enumeration value="fat"/>
			<enumeration value="fatthin"/>
		</simpleType>
	</attribute>
-->

	<attribute name="type" type="NMTOKEN" />
	<attribute name="leftRepeat" type="integer" />
	<attribute name="rightRepeat" type="integer" />
	<attribute name="count" type="boolean" />
</xsd:complexType>


<xsd:complexType name="Con" base="momentOfTime" derivedBy="extension">
	<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 -->
</xsd:complexType>




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

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

<xsd:element name="bar" equivClass="masterSymbol" type="Bar" />




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

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

<xsd:element name="dynamics" equivClass="sharedSymbol" >
	<xsd:complexType base="momentOfTime" derivedBy="extension">
		<attribute name="name" type="string" />   <!-- XXX replace string enum -->
	</xsd:complexType>
</xsd: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.
  -->
<xsd:element name="repeat" equivClass="sharedSymbol" >
	<xsd:complexType base="momentOfTime" derivedBy="extension">
		<attribute name="sign" type="NMTOKEN" />   <!-- XXX replace by (empty|segno|dalsegno|coda|tocoda|start_klammer|end_klammer|dacapo|fine|dcalfinesenzarep|dcalfine|dcsenzarep|vi|de) "empty"  -->
		<element name="localText" type="LocalTextType" minOccurs="0" maxOccurs="1" />
	</xsd:complexType>
</xsd:element>


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

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




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

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

<xsd:element name="barRef" equivClass="threadSymbol" >
	<xsd:complexType base="Bar" derivedBy="extension">
		<attribute name="barID" type="IDREF" />
	</xsd:complexType>
</xsd: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

  -->
<xsd:element name="con" equivClass="threadSymbol" type="Con" >
</xsd:element>

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


<!-- note:
  -->
<xsd:element name="note">
	<xsd:complexType base="lasting" derivedBy="extension">
		<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; -->
	</xsd:complexType>
</xsd:element>


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

<!-- slur:
     groups notes left and (right) together
     if tie = "false", right mus be provided
  -->
<xsd:element name="slur" equivClass="threadSymbol" >
	<xsd:complexType base="momentOfTime" derivedBy="extension">
		<attribute name="left" type="IDREF" minOccurs="0" />   <!-- XXX minOccurs should be 1, but the parser throws a really strange exception if I do this -->
		<attribute name="right" type="IDREF"  />
		<attribute name="tie" type="boolean" />
	</xsd:complexType>
</xsd: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
  -->
<xsd:element name="bibdata" minOccurs="0" maxOccurs="1">
	<xsd:complexType base="core" derivedBy="extension">
		<!-- xsd:attribute name="author" type="xsd:string" / -->
		<xsd:attribute name="author" type="string" />
		<xsd:element name="localText" type="LocalTextType" maxOccurs="*" />  <!-- XXX change name for readability -->
	</xsd:complexType>
</xsd:element>


<xsd:element name="description" minOccurs="0" maxOccurs="1">
	<xsd:complexType base="core" derivedBy="extension">
		<xsd:attribute name="align" type="string" /> <!-- XXX (left|right|bottom|top) "right" -->
		<xsd:element name="localText" type="LocalTextType" />  <!-- XXX change name for readability -->
	</xsd:complexType>
</xsd:element>


<!-- LocalTextType is referred several times and provides internationalized text -->
<xsd:complexType name="LocalTextType" base="string">
	<!-- no coreattrs -->
	<xsd:attribute name="xml:lang" type="string" /> <!-- XXX a LanguageCode, as per [RFC1766] -->
	<xsd:attribute name="lang" type="string" />
</xsd:complexType>



</xsd:schema>
