2008-09-19 20 views
18

Ich versuche, einen Teil eines Schemas einzurichten, das wie eine "Sequenz" ist, wobei alle untergeordneten Elemente optional sind, aber mindestens eins der Elemente muss vorhanden sein, und es könnte mehr als eine von ihnen geben.XML-Schemakonstrukt für "eines oder mehrere dieser Elemente, muss aber mindestens eins sein"

versuchte ich folgendes tun, aber XMLSpy beschwert sich, dass DateConstant "> und < element name = "DateConstant "Das Inhaltsmodell element name = die Elemente < enthält"" >, die nicht eindeutig bestimmt werden kann.":

<xs:choice> 
     <xs:sequence> 
      <xs:element name="DateConstant"/> 
      <xs:element name="TimeConstant"/> 
     </xs:sequence> 
     <xs:element name="DateConstant"/> 
     <xs:element name="TimeConstant"/> 
    </xs:choice> 

Kann dies (und wenn ja, wie) getan werden?

Einige Erklärung: Ich möchte nur eines von jedem Element mit dem gleichen Namen erlauben. Es kann einen "DateConstant" und/oder einen "TimeConstant" geben, aber keines von beiden. Die Antwort von Gizmo entspricht meinen Anforderungen, ist aber für eine größere Anzahl von Elementen unpraktisch. Hursts Antwort erlaubt zwei oder mehr Elemente mit dem gleichen Namen, die ich nicht möchte.

Antwort

21

Try this:

<xs:choice> 
    <xs:sequence> 
    <xs:element name="Elem1" /> 
    <xs:element name="Elem2" minOccurs="0" /> 
    <xs:element name="Elem3" minOccurs="0" /> 
    </xs:sequence> 
    <xs:sequence> 
    <xs:element name="Elem2" /> 
    <xs:element name="Elem3" minOccurs="0" /> 
    </xs:sequence> 
    <xs:element name="Elem3" /> 
</xs:choice> 

tut so, Sie zwingen, entweder das erste Element zu wählen und dann der Rest ist optional, entweder das zweite Element und der Rest ist optional, entweder das dritte Element.

Dies sollte tun, was Sie wollen, hoffe ich.

Natürlich könnten Sie die Untersequenzen in Gruppen einfügen, um zu vermeiden, ein Element in jeder Sequenz zu duplizieren, wenn Sie feststellen, dass Sie einen vermissen.

13

Nach dem technischen Artikel auf MSDN Titel Legendes XML Schema bei http://msdn.microsoft.com/en-us/library/aa468557.aspx#understandxsd_topic5 Sie die Vorteile von Einschränkungen wie minOccurs auf die Wahl Definition (Compositor) selbst übernehmen kann:

„Mit Einschränkungen Auftreten auf einem Compositor gilt für die gesamte Gruppe als Ganzes "

(Siehe das komplexere Beispiel, das verschachtelte komplexe Typen und das AuthorType-Beispiel verwendet)

Sie haben Ihre Anforderung als "mindestens eines der Elemente muss vorhanden sein, und es könnte mehr als einer von ihnen sein". Daher schlage ich vor, Sie versuchen, die folgenden:

<xs:choice minOccurs="1" maxOccurs="unbounded"> 
    <xs:element name="DateConstant" type="..."/> 
    <xs:element name="TimeConstant" type="..."/> 
</xs:choice> 
+0

Dies funktioniert nicht. Wenn ein Element fehlt, während das eine vorhanden ist, wird kein Fehler auftreten. – yegor256

1

@hurst,

Leider haben Sie es versäumt, die ursprüngliche Frage zu verstehen. Das Platzieren von minOccurs = "1" auf der Auswahl wird automatisch erfüllt, wenn ALLE Elemente, die minOccurs = "0" enthalten, als Optionen enthalten sind.

So haben Sie die "mindestens eine", die vom ursprünglichen Poster benötigt wird, nicht berücksichtigt, weil keine Elemente 1 Vorkommen von zwei vollständig optionalen Elementen korrekt erfüllen.

Bis jetzt kann ich keine Lösung finden, da minOccur/maxOccur beide auf die Gruppe bezogen sind, in der sie definiert sind und sich NICHT auf eine Gesamtanzahl von Knoten beziehen.Sie können das Element choice auch nicht mehrmals verwenden, um dasselbe Element zu definieren, oder es wird "mehrdeutig". Ich habe einige Beispiele gesehen, die Referenzen anstelle von Elementen eines bestimmten Typs verwenden, aber ich glaube, das scheitert an dem Microsoft XSD-Parser.

<xs:choice minOccurs="1" maxOccurs="1"> 
    <xs:sequence minOccurs="1" maxOccurs="1"> 
    <xs:element name="Elem1" minOccurs="1" maxOccurs="1" /> 
    <xs:element name="Elem2" minOccurs="0" maxOccurs="1" /> 
    </xs:sequence> 
    <xs:sequence > 
    <xs:element name="Elem2" minOccurs="1" maxOccurs="1" /> 
    </xs:sequence> 
</xs:choice> 

Hier können Sie sehen, dass Sie entweder die erste Folge haben (die Elem1 haben muss, aber kann Elem2 haben optional), oder Sie haben die zweite Sequenz (die Elem2 MUSS).

Sie haben nun "eines oder mehrere" dieser 2 Elemente. Natürlich wird dies exponentiell komplexer, je mehr Optionen Sie haben, da Sie zusätzliche Optionen für alle möglichen Kombinationen bereitstellen müssen.

+1

Nur ein Quatsch: Es ist nicht "exponentiell komplexer", nur quadratisch. Aber es ist umständlich. Ich wünschte, es wäre etwas einfacher. – user3697176