2009-05-08 4 views
25

Ich definiere ein Benutzerelement mit XSD. In diesem Beispiel hat ein Benutzer einen Namen, eine E-Mail-Adresse und eine oder mehrere Nationalitäten. Ich habe versucht:Mittlerer Weg zwischen XSD alle und XSD Sequenz

Das ist jedoch illegal. Anscheinend können Elemente in einem "All" nur einmal vorkommen (oder gar nicht). Ich könnte das beheben, indem ich All in Sequence ändere, aber dann müssten die Leute die Eigenschaften in der richtigen Reihenfolge eingeben, was mir eigentlich egal ist.

Gibt es eine Kombination dieser beiden? Nicht nach http://www.w3schools.com/Schema/schema_complex_indicators.asp, aber vielleicht ist es versteckt (oder meine unerfahrenen Augen sehen es nicht).

Intuitiv habe ich auch versucht:

<xs:all> 
    <xs:element name="name" blabla /> 
    <xs:element name="email" blabla /> 
    <xs:sequence> 
    <xs:element name="nationality" minOccurs="1" maxOccurs="unbounded" /> 
    </xs:sequence> 
</xs:all> 

Aber das ist leider ungültig.


Dies ist die aktuelle, real, Stück XSD:

<!-- user --> 
    <xs:complexType name="user"> 
    <xs:sequence> 
     <xs:element name="firstname" type="xs:string" minOccurs="1" maxOccurs="1" /> 
     <xs:element name="appendix" type="xs:string" minOccurs="0" maxOccurs="1" /> 
     <xs:element name="lastname" type="xs:string" minOccurs="1" maxOccurs="1" /> 
     <xs:element name="address" type="xs:string" minOccurs="1" maxOccurs="1" /> 
     <xs:element name="zipcode" type="xs:string" minOccurs="1" maxOccurs="1" /> 
     <xs:element name="city" type="xs:string" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="username" type="xs:string" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="email" type="xs:string" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="country" type="country" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="nationality" type="xs:string" minOccurs="1" maxOccurs="unbounded"/> 
    </xs:sequence> 
    </xs:complexType> 

Antwort

3

Ihr Code sollte in XSD 1.1 gültig sein. Für XSD 1.0 müssen Sie eine Problemumgehung finden.

+26

Wie kann man XSD 1.1 verwenden, umsetzen, aktivieren, erstellen, verdecken, migrieren, instanziieren, finden oder tun? –

+3

Könnten Sie den Unterschied zwischen XSD 1.1 und XSD 1.0 angeben, der ihn in 1.1 gültig und in 1.0 ungültig macht? –

+0

In der 1.1-Spezifikation sehe ich keine Hinweise auf Einschränkungen, die das XML des OP illegal machen. Leider kann ich die 1.0 Spezifikation nicht finden, um vergleichen zu können. Meine Vermutung ist, dass Sie die Version auf den Bibliotheken überprüfen müssen, die Ihr XML/XSD analysieren werden, um zu wissen, ob Sie irgendwelche der Tricks unten benötigen. –

21

Könnten Sie drehen Ihre „Nationalität“ thingie in seine eigene complex und dann diese neuen komplexen Typ in Ihrem xs verwenden: alle ?

<xs:complexType name="NationalityType"> 
    <xs:sequence> 
    <xs:element name="nationality" minOccurs="1" maxOccurs="unbounded" /> 
    </xs:sequence> 
</xs:complexType> 

<xs:all> 
    <xs:element name="name" blabla /> 
    <xs:element name="email" blabla /> 
    <xs:element name="nationalities" type="NationalityType" /> 
</xs:all> 

ich das nicht alles bei der Hand zu testen, so ist dies wirklich nur aus der Spitze von meinem Kopf ..... Versuchen Sie es einfach!

EDIT: getestet es nun - es funktioniert, die nur geringe Preis zu zahlen ist, dass Ihr XML etwas wie folgt aussehen wird:

<....> 
    <email>......</email> 
    <nationalities> 
    <nationality>ABC</nationality> 
    <nationality>CDE</nationality> 
    </nationalities> 
    <name>.....</name> 
</.....> 

So erhalten Sie einen zusätzlichen Knoten, der die willkürliche enthalten lange Liste von <nationality> Artikel.

Marc

+4

Diese Antwort ist die einzige richtige. Was Sie brauchen, ist eine Vielzahl von Nationalitäten. Alle anderen Methoden sind nur Hacks, die die Prinzipien von XML brechen. –

0

Oder da „USER“ wird sich mit mehreren untergeordneten Elemente gesetzt werden, warum setzen Sie ihn nicht als komplexer Typ up? So etwas sollte funktionieren.

<xs:complexType> 
    <xs:sequence> 
    <xs:element name="Name" type="xs:string" /> 
    <xs:element name="Password" type="xs:string" /> 
    <xs:element minOccurs="1" maxOccurs="unbounded" name="Nationality" type="xs:string" /> 
    </xs:sequence> 
</xs:complexType> 
+1

Es ist bereits ein komplexer Typ. Ich habe die echte XSD zu der Frage hinzugefügt, also können Sie es auch sehen :) –

0

xs:choice funktioniert nicht? Wenn nicht, wickle das einfach in eine Sequenz oder umgekehrt.

+0

Huh? Wie würde das helfen? Bitte geben Sie ein Beispiel. –

7

Ich denke, was Sie suchen, würde gegen die Absicht von XML gehen. Es wäre seltsam scheint ein gültiges XML-Fragment wie diese zu haben:

<user> 
    <nationality/> 
    <name/> 
    <nationality/> 
    <email/> 
    <nationality/> 
</user> 

Es klingt wie Sie für so etwas wie du fragen, was vorgeschlagen marc_s:

:

<user> 
    <name/> 
    <email/> 
    <nationality/> 
    <nationality/> 
    <nationality/> 
<user> 

, die in geschoben zu werden braucht

<user> 
    <name/> 
    <email/> 
    <nationalities> 
    <nationality/> 
    <nationality/> 
    <nationality/> 
    </nationalities> 
<user> 
1

Für XSD 1.0 funktioniert der Vorschlag von leppie.

Die XSD

<?xml version='1.0' encoding='UTF-8'?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name='user'> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="name" type="xs:string" /> 
     <xs:element name="email" type="xs:string" /> 
     <xs:choice minOccurs='0' maxOccurs='unbounded'> 
      <xs:element name="nationality" /> 
     </xs:choice> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

Eine Probe XML-Dokument, das zum Beispiel

<user> 
    <name>Name</name> 
    <email>[email protected]</email> 
    <nationality>Italian</nationality> 
    <nationality>Japanese</nationality> 
    <nationality>Alien</nationality> 
</user> 

und Validierung gegen das Schema validiert mit xmllint

xmllint --noout --schema test.xsd test.xml 
test.xml validate 
+0

Es gibt keine Notwendigkeit in "Wahl" in Beispiel, das Sie zur Verfügung gestellt haben. Soweit Sie das Element 'sequence' verwenden, kann es maxOccurs = "unbounded" haben. Aber die Reihenfolge legt die Reihenfolge der Elemente fest - das war das Problem in der ersten Frage. –

+0

Bei einer positiven Anmerkung zeigt diese Antwort, dass die Modellgruppenelemente 'all',' sequence' und 'choice' verschachtelt werden können. In ähnlicher Weise können in 1.1 Gruppen definiert und referenziert werden, siehe http://www.w3.org/TR/xmlschema11-1/#cModel_Group_Definitions, die vermeiden würden, ein neues 'container'-Element hinzuzufügen, wie es die Antwort von marc_s tut. –

20

Kommen Sie einfach über die ein ähnliches Problem (Ich wollte in beliebiger Reihenfolge eine beliebige Anzahl von jedem Element haben) und löste es mit einer Folge von Entscheidungen. Im oben genannten Beispiel:

<?xml version='1.0' encoding='UTF-8'?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name='user'> 
    <xs:complexType> 
     <xs:sequence minOccurs="0" maxOccurs="unbounded"> 
     <xs:choice> 
      <xs:element name="name" type="xs:string" /> 
      <xs:element name="email" type="xs:string" /> 
      <xs:element name="nationality" /> 
     </xs:choice> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

Dies Sie eine beliebige Anzahl von Namen, E-Mail und Nationalität in beliebiger Reihenfolge haben können.

+6

Dies würde jedoch mehrere Elemente innerhalb der ? –