Ich versuche, eine XSD zu erstellen und die Definition mit der folgenden Anforderung zu schreiben:
Ich sah mich um und fand verschiedene Lösungen wie this :
<xs:element name="foo">
<xsl:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="child1" type="xs:int"/>
<xs:element name="child2" type="xs:string"/>
</xs:choice>
</xs:complexType>
</xs:element>
Aber nach meinem Verständnis erlaubt xs: choice immer noch nur die Auswahl einzelner Elemente. Daher sollte das Festlegen von "MaxOccurs" auf "unbounded" nur bedeuten, dass "eines" der untergeordneten Elemente mehrmals auftreten kann. Ist das genau?
Wenn die obige Lösung falsch ist, wie kann ich das erreichen, was ich oben in meiner Anforderung angegeben habe?
[~ # ~] edit [~ # ~] : Was ist, wenn die Anforderung wie folgt lautet?
Diese XML ist zum Beispiel gültig:
<foo>
<child1> value </child1>
<child1> value </child1>
<child3> value </child3>
<child2> value </child2>
<child4> value </child4>
<child1> value </child1>
</foo>
aber das ist nicht (vermisst child3)
<foo>
<child1> value </child1>
<child1> value </child1>
<child2> value </child2>
<child4> value </child4>
<child1> value </child1>
</foo>
In dem Schema, das Sie in Ihrer Frage haben, child1
oder child2
kann in beliebiger Reihenfolge und beliebig oft vorkommen. Das klingt nach dem, wonach Sie suchen.
Edit: Wenn nur einer von ihnen beliebig oft vorkommen soll, muss der Unbegrenzte stattdessen auf die Elemente klicken:
Edit: Feste Eingabe in XML.
Edit: Großgeschriebenes O in maxOccurs
<xs:element name="foo">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element name="child1" type="xs:int" maxOccurs="unbounded"/>
<xs:element name="child2" type="xs:string" maxOccurs="unbounded"/>
</xs:choice>
</xs:complexType>
</xs:element>
Die alternative Formulierung der in einer späteren Bearbeitung hinzugefügten Frage scheint noch unbeantwortet zu sein: Wie kann angegeben werden, dass unter den untergeordneten Elementen eines Elements eines mit dem Namen child3
, eines mit dem Namen child4
vorhanden sein muss? und eine beliebige Nummer mit dem Namen child1
oder child2
, ohne Einschränkung für die Reihenfolge, in der die untergeordneten Elemente angezeigt werden.
Dies ist eine direkt definierbare reguläre Sprache, und das von Ihnen benötigte Inhaltsmodell ist isomorph zu einem regulären Ausdruck, der den Satz von Zeichenfolgen definiert, in denen die Ziffern '3' und '4' jeweils genau einmal vorkommen, sowie die Ziffern '1' und '2 'beliebig oft vorkommen. Wenn es nicht offensichtlich ist, wie man das schreibt, kann es hilfreich sein, darüber nachzudenken, welche Art von Finite-State-Maschine Sie erstellen würden, um eine solche Sprache zu erkennen. Es hätte mindestens vier verschiedene Zustände:
Unabhängig davon, in welchem Zustand sich der Automat befindet, können "1" und "2" gelesen werden. Sie ändern den Status der Maschine nicht. Im Ausgangszustand wird auch '3' oder '4' akzeptiert; in den Zwischenzuständen wird nur '4' oder '3' akzeptiert; Im Endzustand wird weder '3' noch '4' akzeptiert. Die Struktur des regulären Ausdrucks ist am einfachsten zu verstehen, wenn wir zuerst einen regulären Ausdruck für die Teilmenge unserer Sprache definieren, in der nur '3' und '4' vorkommen:
(34)|(43)
Damit "1" oder "2" an einem bestimmten Ort beliebig oft vorkommen kann, können wir (1|2)*
(oder [12]*
) einfügen, wenn unsere Regex-Sprache diese Notation akzeptiert. Wenn wir diesen Ausdruck an allen verfügbaren Stellen einfügen, erhalten wir
(1|2)*((3(1|2)*4)|(4(1|2)*3))(1|2)*
Die Übersetzung in ein Inhaltsmodell ist unkompliziert. Die Grundstruktur entspricht dem regulären Ausdruck (34)|(43)
:
<xsd:complexType name="paul0">
<xsd:choice>
<xsd:sequence>
<xsd:element ref="child3"/>
<xsd:element ref="child4"/>
</xsd:sequence>
<xsd:sequence>
<xsd:element ref="child4"/>
<xsd:element ref="child3"/>
</xsd:sequence>
</xsd:choice>
</xsd:complexType>
Das Einfügen einer Null-oder-Mehr-Auswahl von child1
und child2
ist einfach:
<xsd:complexType name="paul1">
<xsd:sequence>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="child1"/>
<xsd:element ref="child2"/>
</xsd:choice>
<xsd:choice>
<xsd:sequence>
<xsd:element ref="child3"/>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="child1"/>
<xsd:element ref="child2"/>
</xsd:choice>
<xsd:element ref="child4"/>
</xsd:sequence>
<xsd:sequence>
<xsd:element ref="child4"/>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="child1"/>
<xsd:element ref="child2"/>
</xsd:choice>
<xsd:element ref="child3"/>
</xsd:sequence>
</xsd:choice>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element ref="child1"/>
<xsd:element ref="child2"/>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
Wenn wir den Umfang ein wenig minimieren möchten, können wir eine benannte Gruppe für die wiederholten Auswahlmöglichkeiten von child1
und child2
definieren:
<xsd:group name="onetwo">
<xsd:choice>
<xsd:element ref="child1"/>
<xsd:element ref="child2"/>
</xsd:choice>
</xsd:group>
<xsd:complexType name="paul2">
<xsd:sequence>
<xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
<xsd:choice>
<xsd:sequence>
<xsd:element ref="child3"/>
<xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element ref="child4"/>
</xsd:sequence>
<xsd:sequence>
<xsd:element ref="child4"/>
<xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element ref="child3"/>
</xsd:sequence>
</xsd:choice>
<xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
In XSD 1.1 wurden einige Einschränkungen für all
- Gruppen aufgehoben, sodass dieses Inhaltsmodell präziser definiert werden kann:
<xsd:complexType name="paul3">
<xsd:all>
<xsd:element ref="child1" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element ref="child2" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element ref="child3"/>
<xsd:element ref="child4"/>
</xsd:all>
</xsd:complexType>
Wie jedoch aus den oben angegebenen Beispielen hervorgeht, ändern diese Änderungen an all
-Gruppen nicht die Ausdruckskraft der Sprache. Sie machen nur die Definition bestimmter Arten von Sprachen prägnanter.
Das hat bei mir endlich geklappt:
<xsd:element name="bar">
<xsd:complexType>
<xsd:sequence>
<!-- Permit any of these tags in any order in any number -->
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="child1" type="xsd:string" />
<xsd:element name="child2" type="xsd:string" />
<xsd:element name="child3" type="xsd:string" />
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
Aber nach meinem Verständnis erlaubt xs: choice immer noch nur die Auswahl einzelner Elemente. Daher sollte das Festlegen von "MaxOccurs" auf "unbounded" nur bedeuten, dass "eines" der untergeordneten Elemente mehrmals auftreten kann. Ist das genau?
Nein. Die Auswahl erfolgt individuell für jede "Wiederholung" von xs:choice
das kommt vor wegen maxOccurs="unbounded"
. Daher ist der von Ihnen veröffentlichte Code korrekt und wird tatsächlich das tun, was Sie geschrieben haben möchten.
Sie sollten feststellen, dass das folgende Schema das zulässt, was Sie vorgeschlagen haben.
<xs:element name="foo">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:choice>
<xs:element maxOccurs="unbounded" name="child1" type="xs:unsignedByte" />
<xs:element maxOccurs="unbounded" name="child2" type="xs:string" />
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
Auf diese Weise können Sie eine Datei wie die folgenden erstellen:
<?xml version="1.0" encoding="utf-8" ?>
<foo>
<child1>2</child1>
<child1>3</child1>
<child2>test</child2>
<child2>another-test</child2>
</foo>
Welches scheint zu Ihrer Frage zu passen.
Wenn keines der oben genannten Verfahren funktioniert, arbeiten Sie wahrscheinlich an einer EDI) - Transaktion, bei der Sie Ihr Ergebnis anhand eines HIPPA-Schemas oder eines anderen komplexen xsd validieren müssen Dort müssen 8 REF-Segmente und eines von ihnen in einer beliebigen Reihenfolge erscheinen und es sind auch nicht alle erforderlich. Dies bedeutet, dass Sie diese in der folgenden Reihenfolge haben können: 1. REF, 3. REF, 2. REF, 9. REF. Unter Standardbedingungen EDI Receive schlägt fehl, da der komplexe Standardtyp ist
<xs:sequence>
<xs:element.../>
</xs:sequence>
Die Situation ist sogar komplex, wenn Sie Ihr Element durch eine Abkühlung aufrufen und dieses Element dann an seiner ursprünglichen Stelle selbst ziemlich komplex ist. beispielsweise:
<xs:element>
<xs:complexType>
<xs:sequence>
<element name="REF1" ref= "REF1_Mycustomelment" minOccurs="0" maxOccurs="1">
<element name="REF2" ref= "REF2_Mycustomelment" minOccurs="0" maxOccurs="1">
<element name="REF3" ref= "REF3_Mycustomelment" minOccurs="0" maxOccurs="1">
</xs:sequence>
</xs:complexType>
</xs:element>
Lösung:
Hier funktioniert es nicht, einfach "Sequenz" durch "Alle" zu ersetzen oder "Auswahl" mit Min/Max-Kombinationen zu verwenden!
Ersetzen Sie als erstes "xs:sequence" with "<xs:all>"
Nun müssen Sie einige Änderungen an der Stelle vornehmen, an der Sie auf das Element verweisen. Gehen Sie zu:
<xs:annotation>
<xs:appinfo>
<b:recordinfo structure="delimited" field.........Biztalk/2003">
*** Fügen Sie nun im obigen Segment den Triggerpunkt am Ende wie folgt hinzu. Trigger_field = "REF01 _... complete name .." trigger_value = "38" Machen Sie dasselbe für andere REF-Segmente, bei denen der Triggerwert unterschiedlich ist, wie z. B. "18 "," XX "," YY "usw., so dass Ihre Datensatzinformationen jetzt wie folgt aussehen: b:recordinfo structure="delimited" field.........Biztalk/2003" trigger_field="REF01_...complete name.." trigger_value="38">
Dies macht jedes Element einzigartig. Grund dafür ist, dass alle REF-Segmente (obiges Beispiel) dieselbe Struktur wie REF01, REF02, REF03 haben. Und während der Validierung ist die Strukturvalidierung in Ordnung, lässt die Werte jedoch nicht wiederholen, da versucht wird, im ersten REF selbst nach verbleibenden Werten zu suchen. Das Hinzufügen von Triggern macht sie alle einzigartig und sie werden in jeder Reihenfolge und in situativen Fällen bestanden (z. B. verwenden Sie 5 von 9 und nicht alle 9/9).
Hoffe es hilft dir, denn ich habe fast 20 Stunden damit verbracht.
Viel Glück