Julia: XML-Schema

Hallo Forum,

ich habe eine Frage bezüglich Constraints in XML-Schema.

Ich habe ein Schema anhand einer XML-Datei erstellt.

<?xml version="1.1" encoding="UTF-8"?>

<library xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
	 xsi:noNamespaceSchemaLocation='library.xsd'>

  <book>
    <author-ref>J.K.Rowling</author-ref>
    <title>Harry Potter und der Stein der Weisen</title>
    <language>de</language>
    <year>1998</year>
  </book>

  <book>
    <author-ref>J.K.Rowling</author-ref>>
    <title>Harry Potter und die Kammer des Schreckens</title>
    <language>de</language>
    <year>1999</year>
  </book>

  <book>
    <author-ref>T.Pratchett</author-ref>
    <title>The Colour of Magic</title>
    <year>1983</year>
  </book>

  <book>
    <author-ref>T.Pratchett</author-ref>
    <author-ref>N.Gaiman</author-ref>
    <title>Good Omens: The Nice and Accurate Prophecies...</title>
    <language>en</language>
  </book>

  <author id="J.K.Rowling">
    <last-name>Rowling</last-name>
    <first-name>Joanne K.</first-name>
  </author>

  <author id="N.Gaiman">
    <last-name>Gaiman</last-name>
    <first-name>Neil</first-name>
  </author>

  <author id="T.Pratchett">
    <last-name>Pratchett</last-name>
    <first-name>Terry</first-name>
  </author>

</library>

<?xml version="1.1" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="library" type="libraryType"/>


  <xsd:element name="book" type="bookType">
      <xsd:unique name="AuthorUnique">
        <xsd:selector xpath=".//book"/>
        <xsd:field xpath=".//book/author-ref"/>
    </xsd:unique>
  </xsd:element>
  <xsd:element name="author" type="authorType">
      <xsd:key name="AuthorIdUnique">
        <xsd:selector xpath=".//author"/>
        <xsd:field xpath=".//author/@id"/>
    </xsd:key>
  </xsd:element>

  <xsd:complexType name="libraryType">
    <xsd:sequence>
      <xsd:element type="bookType" name="book" minOccurs="0" maxOccurs="unbounded"/>
      <xsd:element type="authorType" name="author" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="bookType" mixed="true">
    <xsd:sequence>
      <xsd:element type="xsd:string" name="author-ref" maxOccurs="unbounded"/>
      <xsd:element type="xsd:string" name="title"/>
      <xsd:element type="xsd:string" name="language" minOccurs="0"/>
      <xsd:element type="xsd:integer" name="year" minOccurs="0"/>
    </xsd:sequence>
 </xsd:complexType>

  <xsd:complexType name="authorType">
    <xsd:sequence>
      <xsd:element type="xsd:string" name="last-name"/>
      <xsd:element type="xsd:string" name="first-name"/>
    </xsd:sequence>
    <xsd:attribute type="xsd:string" name="id" use="required"/>
   </xsd:complexType>
</xsd:schema>

Anschließend muss ich noch bestimmte Constraints hinzufügen. Und zwar:

  1. Die Werte der author-ref-Unterelemente jedes Buches sind paarweise verschieden. Realisiere das mit xsd:unique.

  2. Das id-Attribut der author-Elemente enthält für jeden Autor einen eindeutigen Wert. Realisiere das mit xsd:key.

Irgendetwas habe ich dabei aber falsch gemacht, denn wenn ich zum Testen die XML-Datei fehlerhaft mache (z.B. gleiche author-ref angebe oder mehrere Autoren mit demselben ID) kriege ich beim Validierungstest immer noch die Meldung "The XML document is valid", was in diesem Fall natürlich nicht wahr ist.

Ich vermute, dass ich XPath irgendwie falsch angegeben habe aber ich habe schon alles mögliche ausprobiert und verzweifele langsam.

Kann mir vielleicht jemand einen Hinweis geben, was ich falsch mache?

Schönen Dank im Voraus!

Julia

  1. Hallo Forum,

    kann mir wirklich keiner helfen? Oder ist die Frage zu langweilig?

    Gruß Julia

  2. Hallo Julia,

    auf eine alleinige Lösung mit xsd:unique, xsd:key, xsd:keyref bin ich zunächst nicht gekommen.

    Hier ein alternativer Lösungsversuch mit xsd:unique für author/@id, wobei zusätzlich der Typ xsd:ID zum Einsatz kommt und Erweiterung mit xsd:assert aus XML Schema 1.1, was mächtigere XPath-Ausdrücke vor allem unter Nutzung von XPath-Funktionen erlaubt:

    <?xml version="1.1" encoding="UTF-8"?>
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
      xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1">
      <xsd:element name="library" type="libraryType"/>
    
      <xsd:element name="book" type="bookType"/>
    
      <xsd:element name="author" type="authorType">
        <xsd:unique name="AuthorUnique">
          <xsd:selector xpath="author"/>
          <xsd:field xpath="@id"/>
        </xsd:unique>
      </xsd:element>
    
      <xsd:complexType name="libraryType">
        <xsd:sequence>
          <xsd:element type="bookType" name="book" minOccurs="0" maxOccurs="unbounded"/>
          <xsd:element type="authorType" name="author" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:sequence>
      </xsd:complexType>
    
      <xsd:complexType name="bookType" mixed="true">
        <xsd:sequence>
          <xsd:element type="xsd:string" name="author-ref" maxOccurs="unbounded"/>
          <xsd:element type="xsd:string" name="title"/>
          <xsd:element type="xsd:string" name="language" minOccurs="0"/>
          <xsd:element type="xsd:integer" name="year" minOccurs="0"/>
        </xsd:sequence>
        <xsd:assert test="count(distinct-values(author-ref)) = count(author-ref)"/>
      </xsd:complexType>
    
      <xsd:complexType name="authorType">
        <xsd:sequence>
          <xsd:element type="xsd:string" name="last-name"/>
          <xsd:element type="xsd:string" name="first-name"/>
        </xsd:sequence>
        <xsd:attribute type="xsd:ID" name="id" use="required"/>
      </xsd:complexType>
    </xsd:schema>
    
    
    

    Damit lassen sich keine author-Elemente mit mehrfachem Vorkommen derselben ID verwenden und falls mehrere author-ref-Kindelemente unterhalb von book vorkommen, müssen deren Inhalte verschiedene Autoren sein.

    BTW: Die XML-Version 1.1 ist für XML/XSD keine Bedingung, 1.0 reicht.

    Grüße,
    Thomas

    1. Hallo Thomas,

      vielen Dank für Deine Antwort!

      So wie es da steht hat es bei mir nicht ganz funktioniert (auch gültige Dokumente wurden als ungültig angezeigt), aber Dein Tipp mit "xsd:assert" hat mich schon sehr viel weiter gebracht, danke!

      Schönen Gruß

      Julia

      1. Hallo Julia,

        ganz klar kam nicht heraus, was letztlich gültig sein sollte. Mein Schema hat zumindest bzgl. der genannten Einschränkungen zu Deinem XML-Dokument gepasst. Validiert habe ich im <oXygen/> XML Editor.

        Grüße,
        Thomas