2009-10-21 11 views
9

Ich versuche ein Schema zu entwickeln, das einige vorhandene XML-Dateien validiert, die ich geerbt habe. Ich möchte, dass das Schema so viel wie möglich von der Validierungsarbeit ausführt. Die Herausforderung besteht darin, dass Attribute und Elemente von den Werten anderer Attribute abhängig sind.Erstellen eines XML-Schemas mit Attributen und Elementen, die von anderen Attributen abhängig sind

Die echten Daten sind ziemlich abstrakt, also habe ich ein paar einfache Beispiele erstellt. Lassen Sie uns sagen, dass ich die folgenden XML-Dateien haben:

<?xml version="1.0" encoding="UTF-8"?> 
<Creature type="human" nationality="British"> 
    <Address>London</Address> 
</Creature> 

<?xml version="1.0" encoding="UTF-8"?> 
<Creature type="animal" species="Tiger"> 
    <Habitat>Jungle</Habitat> 
</Creature> 

Wenn die „Art“ der Kreatur ist „menschlich“, ich werde eine „Nationalität“ Attribut haben und eine „Adresse“ untergeordnetes Element. Wenn der "Typ" der Kreatur "Tier" ist, habe ich ein "Spezies" -Attribut und ein "Habitat" -Kindelement. Für die Zwecke dieses Beispiels wäre ein "Mensch" mit einer "Art" oder einem "Habitat" ungültig - ebenso wie ein "Tier" mit einer "Nationalität" oder "Adresse".

Wenn "Kreatur" nicht das Wurzelelement ist, könnte ich wahrscheinlich zwei verschiedene "Kreatur" -Wahlen unterhalb des Wurzelelements haben, aber ich sehe nicht, wie ich das schaffen kann, wenn "Kreatur" das Wurzelelement ist .

Gibt es überhaupt ein Schema für diese Dateien, die nur gültigen Dokumenten entsprechen würden? Wenn ja, wie würde ich darüber gehen?

Antwort

7

Sie können das Attribut xsi: type für diesen Zweck verwenden (Sie müssen den xsi: type aus dem Namespace der XMLSchema-Instanz anstelle Ihres eigenen Namespace verwenden, sonst wird es nicht funktionieren).

Im Schema deklarieren Sie einen Basistyp, der als abstrakt deklariert ist, und erstellen zusätzliche komplexe Typen für jeden Subtyp (mit den für diesen Typ spezifischen Elementen/Attributen).

Beachten Sie, dass während dieser Lösung, es besser wäre, verschiedene Elementnamen für jeden Typ zu verwenden (der xsi: type geht irgendwie gegen den Strich, da es jetzt das Typattribut in Kombination mit dem Elementnamen ist definiert den Typ und nicht nur den Namen des Elements).

zB:

<?xml version="1.0"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

<xs:element name="Creature" type="CreatureType"> 
</xs:element> 

    <xs:complexType name="CreatureType" abstract="true"> 
    <!-- any common validation goes here --> 
    </xs:complexType> 

    <xs:complexType name="Human"> 
    <xs:complexContent> 
     <xs:extension base="CreatureType"> 
     <xs:sequence maxOccurs="1"> 
      <xs:element name="Address"/> 
     </xs:sequence> 
     <xs:attribute name="nationality" type="xs:string"/> 
     </xs:extension> 
    </xs:complexContent> 
    </xs:complexType> 

    <xs:complexType name="Animal"> 
    <xs:complexContent> 
     <xs:extension base="CreatureType"> 
     <xs:sequence maxOccurs="1"> 
      <xs:element name="Habitat"/> 
     </xs:sequence> 
     <xs:attribute name="species" type="xs:string"/> 
     </xs:extension> 
    </xs:complexContent> 
    </xs:complexType> 

</xs:schema> 

Dieses Schema diese beiden validieren:

<?xml version="1.0" encoding="UTF-8"?> 
<Creature xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:type="Human" 
      nationality="British"> 
    <Address>London</Address> 
</Creature> 

<?xml version="1.0" encoding="UTF-8"?> 
<Creature xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:type="Animal" 
      species="Tiger"> 
    <Habitat>Jungle</Habitat> 
</Creature> 

aber nicht dieses:

<?xml version="1.0" encoding="UTF-8"?> 
<Creature xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:type="SomeUnknownThing" 
      something="something"> 
    <Something>Something</Something> 
</Creature> 

oder dieses:

<?xml version="1.0" encoding="UTF-8"?> 
<Creature xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:type="Human" 
      species="Tiger"> 
    <Habitat>Jungle</Habitat> 
</Creature> 
+1

Vielen Dank für die sehr präzise Antwort und das hervorragende Beispiel in Ihrer Lösung. Sie haben mir gerade Stunden der Internetsuche erspart –

+1

Großartiges Beispiel! Könnten Sie bitte erklären, warum 'xsi: type' funktioniert, während 'type' nicht in den XML-Dateien enthalten ist? – Praetorian

+0

Ausgezeichnetes Paradigma! Aber in meiner XML-Level-Spezifikation * möchte ich die Spezifikation angeben, und nicht XML-Schema (ich bevorzuge "Typ" und nicht "xsi: type"). Also, ist das eine XML-Schema-Schwäche? – Chameleon

Verwandte Themen