Well, there are a lot of other XML FAQs out there, so the first thing to
do would be to point to those... but, yeah, that thought has occurred to
me. Certainly that's how the XSL FAQ was assembled.
The most elegant solution (least effort for any one person, though
conversely least credit to any one person) would be to find a Wiki
somewhere that's willing to host this FAQ, and build it up collaboratively.
I used the <xsd:unique> at collection level to inspect the children
for distinctness:
Here is my final solution that works in case anyone is interested, my
code is spread over several include files so I'll just paste each with
the file name in upper case preceeding that files contents: (3 files
follow, the test file is last and makes ref to the songs.xsd file, and
songs.xsd includes by ref my global types)
SONGS.XSD
------------------------
<?xml version="1.0"?>
<xs:schema xmlns:xs="
http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:include schemaLocation="types.xsd" />
<xs:element name="Songs" type="typeSongs">
<xs:unique name="keyTitle">
<xs:selector xpath="Song"/>
<xs:field xpath="Title"/>
</xs:unique>
</xs:element>
</xs:schema>
TYPES.XSD
------------------------
<?xml version="1.0"?>
<xs:schema xmlns:xs="
http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<!-- Simple Types -->
<xs:simpleType name="typeTitle">
<xs:restriction base="xs:string">
<xs:maxLength value="100"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="typeFilePath">
<xs:restriction base="xs:string">
<xs:whiteSpace value="preserve"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="typeFitPage">
<xs:restriction base="xs:string">
<xs:enumeration value="HEIGHT"/>
<xs:enumeration value="WIDTH"/>
<xs:enumeration value="Height"/>
<xs:enumeration value="Width"/>
<xs:enumeration value="height"/>
<xs:enumeration value="width"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="typeRating">
<xs:restriction base="xs:integer">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="5"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="typeVolume">
<xs:restriction base="xs:integer">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="100"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="typeBalance">
<xs:restriction base="xs:integer">
<xs:minInclusive value="-100"/>
<xs:maxInclusive value="100"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="typeTimeSignature">
<xs:restriction base="xs:string">
<xs
attern value="[123456789][/][123456789]"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="typeKey">
<xs:restriction base="xs:string">
<xs:enumeration value="A Maj"/>
<xs:enumeration value="A# Maj"/>
<xs:enumeration value="Bb Maj"/>
<xs:enumeration value="B Maj"/>
<xs:enumeration value="B# Maj"/>
<xs:enumeration value="C Maj"/>
<xs:enumeration value="C# Maj"/>
<xs:enumeration value="Db Maj"/>
<xs:enumeration value="D Maj"/>
<xs:enumeration value="D# Maj"/>
<xs:enumeration value="Eb Maj"/>
<xs:enumeration value="E Maj"/>
<xs:enumeration value="E# Maj"/>
<xs:enumeration value="F Maj"/>
<xs:enumeration value="F# Maj"/>
<xs:enumeration value="Gb Maj"/>
<xs:enumeration value="G Maj"/>
<xs:enumeration value="G# Maj"/>
<xs:enumeration value="Ab Maj"/>
<xs:enumeration value="A Min"/>
<xs:enumeration value="A# Min"/>
<xs:enumeration value="Bb Min"/>
<xs:enumeration value="B Min"/>
<xs:enumeration value="B# Min"/>
<xs:enumeration value="C Min"/>
<xs:enumeration value="C# Min"/>
<xs:enumeration value="Db Min"/>
<xs:enumeration value="D Min"/>
<xs:enumeration value="D# Min"/>
<xs:enumeration value="Eb Min"/>
<xs:enumeration value="E Min"/>
<xs:enumeration value="E# Min"/>
<xs:enumeration value="F Min"/>
<xs:enumeration value="F# Min"/>
<xs:enumeration value="Gb Min"/>
<xs:enumeration value="G Min"/>
<xs:enumeration value="G# Min"/>
<xs:enumeration value="Ab Min"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="typeMessage">
<xs:restriction base="xs:string">
<xs:whiteSpace value="preserve"/>
<xs:maxLength value="500"/>
</xs:restriction>
</xs:simpleType>
<!-- Complex (1 level) Types -->
<xs:complexType name="typeSongData">
<xs:sequence>
<xs:element name="Title" type="typeTitle"/>
<xs:element name="Audio" type="typeFilePath"/>
<xs:element name="Sheet" type="typeFilePath"/>
<xs:element name="Page" type="xs
ositiveInteger" minOccurs="0"
maxOccurs="1"/>
<xs:element name="Composers" type="xs:string" minOccurs="0"
maxOccurs="1"/>
<xs:element name="FitPage" type="typeFitPage" minOccurs="0"
maxOccurs="1"/>
<xs:element name="StartAt" type="xs:time" minOccurs="0"
maxOccurs="1"/>
<xs:element name="Keywords" type="xs:string" minOccurs="0"
maxOccurs="1"/>
<xs:element name="GeneralRating" type="typeRating" minOccurs="0"
maxOccurs="1"/>
<xs:element name="DifficultyRating" type="typeRating" minOccurs="0"
maxOccurs="1"/>
<xs:element name="RehearsalRating" type="typeRating" minOccurs="0"
maxOccurs="1"/>
<xs:element name="TimeSignature" type="typeTimeSignature"
minOccurs="0" maxOccurs="1"/>
<xs:element name="Key" type="typeKey" minOccurs="0" maxOccurs="1"/>
<xs:element name="TempoBPM" type="xs
ositiveInteger" minOccurs="0"
maxOccurs="1"/>
<xs:element name="Volume" type="typeVolume" minOccurs="0"
maxOccurs="1"/>
<xs:element name="Balance" type="typeBalance" minOccurs="0"
maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<!-- Complex (2 level) Types -->
<xs:complexType name="typeSong">
<xs:sequence>
<xs:element name="Song" type="typeSongData"/>
</xs:sequence>
</xs:complexType>
<!-- Complex Collection Types -->
<xs:complexType name="typeSongs">
<xs:sequence>
<xs:element name="Song" type="typeSongData" minOccurs="0"
maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:schema>
SONGS.XML (this test file will fail with a duplicate Title)
------------------------------------------------------------------------------------
<Songs xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="Schema/songs.xsd">
<Song>
<Title>One</Title>
<Audio>hw1.wav</Audio>
<Sheet>testcutepdf.pdf</Sheet>
<Page>2</Page>
<Composers>Jobim</Composers>
<Keywords>Latin,Cuban,Slow</Keywords>
<GeneralRating>3</GeneralRating>
<DifficultyRating>3</DifficultyRating>
<RehearsalRating>3</RehearsalRating>
</Song>
<Song>
<Title>a song</Title>
<Audio>hw1.wav</Audio>
<Sheet>testcutepdf.pdf</Sheet>
<Page>2</Page>
<FitPage>width</FitPage>
</Song>
<Song>
<Title>Route 66 Hal Leonard Best of Swing 13</Title>
<Audio>hw1.wav</Audio>
<Sheet>testcutepdf.pdf</Sheet>
<Page>2</Page>
<FitPage>width</FitPage>
</Song>
<Song>
<Title>the song</Title>
<Audio>hw1.wav</Audio>
<Sheet>testcutepdf.pdf</Sheet>
<Page>2</Page>
<FitPage>width</FitPage>
</Song>
<Song>
<Title>Two</Title>
<Audio>Route 66 Hal Leonard Best of Swing 13.wma</Audio>
<Sheet>IACReference.pdf</Sheet>
<Page>1</Page>
<FitPage>height</FitPage>
<StartAt>00:00:03</StartAt>
<Keywords>swing,road</Keywords>
<GeneralRating>4</GeneralRating>
<DifficultyRating>4</DifficultyRating>
<RehearsalRating>4</RehearsalRating>
<TimeSignature>4/4</TimeSignature>
<Key>F Maj</Key>
<TempoBPM>120</TempoBPM>
<Volume>100</Volume>
<Balance>0</Balance>
</Song>
<Song>
<Title>Three</Title>
<Audio>hw2.wav</Audio>
<Sheet>IACReference.pdf</Sheet>
<Page>11</Page>
</Song>
<Song>
<Title>Four</Title>
<Audio>hw1xxxx.wav</Audio>
<Sheet>testcutepdfXXXX.pdf</Sheet>
<Page>1</Page>
</Song>
<Song>
<Title>Five</Title>
<Audio>hw1.wav</Audio>
<Sheet>testcutepdf.pdf</Sheet>
<Page>1</Page>
</Song>
<Song>
<Title>Six</Title>
<Audio>hw2.wav</Audio>
<Sheet>nabble_javascript_error.pdf</Sheet>
<Page>1</Page>
</Song>
<Song>
<Title>a song</Title>
<Audio>hw1.wav</Audio>
<Sheet>testcutepdf.pdf</Sheet>
<Page>2</Page>
<FitPage>width</FitPage>
</Song>
</Songs>