Próbuję utworzyć XSD i próbuję napisać definicję z następującym wymaganiem:
- Zezwalaj, aby określony element podrzędny pojawiał się dowolną liczbę razy (od 0 do nieograniczonych)
- Pozwól elementom podrzędnym być w dowolnej kolejności
Rozejrzałem się i znalazłem różne rozwiązania, takie jak to :
<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>
Ale z tego, co rozumiem, xs: wybór nadal pozwala na wybór tylko jednego elementu. Stąd ustawienie MaxOccurs na nieograniczony w ten sposób powinno tylko oznaczać, że „dowolny” z elementów podrzędnych może pojawić się wiele razy. Czy to jest dokładne?
Jeśli powyższe rozwiązanie jest nieprawidłowe, jak mogę osiągnąć to, co wskazałem powyżej w moim wymaganiu?
EDYCJA : A co, jeśli wymagania są następujące?
- Element child1 child2 może pojawić się dowolną liczbę razy (od 0 do nieograniczonego)
- Elementy w dowolnej kolejności
- Elementy child3 i child4 powinny pojawić się dokładnie raz.
Na przykład ten xml jest prawidłowy:
<foo>
<child1> value </child1>
<child1> value </child1>
<child3> value </child3>
<child2> value </child2>
<child4> value </child4>
<child1> value </child1>
</foo>
ale to nie jest (brakujące dziecko3)
<foo>
<child1> value </child1>
<child1> value </child1>
<child2> value </child2>
<child4> value </child4>
<child1> value </child1>
</foo>
Alternatywne sformułowanie pytania dodanego w późniejszej edycji wydaje się nadal pozostawać bez odpowiedzi: jak sprecyzować, że wśród elementów potomnych elementu musi być jeden nazwany
child3
, jeden nazwanychild4
i jakakolwiek nazwana liczbachild1
lubchild2
, bez ograniczenia kolejności w które pojawiają się dzieci.Jest to łatwo definiowalny język regularny, a model treści, którego potrzebujesz, jest izomorficzny z wyrażeniem regularnym definiującym zestaw ciągów, w których cyfry „3” i „4” występują dokładnie raz, a cyfry „1” i „2” 'występują dowolną liczbę razy. Jeśli nie jest oczywiste, jak to napisać, warto pomyśleć o rodzaju skończonej maszyny stanowej, którą można by zbudować, aby rozpoznawać taki język. Miałoby co najmniej cztery różne stany:
Bez względu na stan automatu można odczytać „1” i „2”; nie zmieniają stanu maszyny. W stanie początkowym akceptowana będzie również wartość „3” lub „4”; w stanach pośrednich dopuszcza się tylko „4” lub „3”; w ostatecznym stanie ani „3”, ani „4” nie są akceptowane. Struktura wyrażenia regularnego jest najłatwiejsza do zrozumienia, jeśli najpierw zdefiniujemy wyrażenie regularne dla podzbioru naszego języka, w którym występuje tylko „3” i „4”:
Aby umożliwić wystąpienie „1” lub „2” dowolną liczbę razy w danym miejscu, możemy wstawić
(1|2)*
(lub[12]*
jeśli nasz język regex akceptuje tę notację). Wstawiając to wyrażenie we wszystkich dostępnych lokalizacjach, otrzymujemyPrzełożenie tego na model treści jest proste. Podstawowa struktura jest odpowiednikiem wyrażenia regularnego
(34)|(43)
:Wstawienie opcji równej zero lub więcej
child1
ichild2
jest proste:Jeśli chcemy nieco zminimalizować masę, możemy zdefiniować nazwaną grupę dla powtarzających się wyborów
child1
ichild2
:W XSD 1.1 niektóre ograniczenia na
all
-groups zostały zniesione, więc możliwe jest bardziej zwięzłe zdefiniowanie tego modelu zawartości:Ale jak widać na podanych wcześniej przykładach, te zmiany w
all
-grupach w rzeczywistości nie zmieniają ekspresyjnej siły języka; uściślają jedynie definicje niektórych rodzajów języków.źródło
Oto, co w końcu zadziałało:
źródło
Nie. Wybór następuje indywidualnie dla każdego „powtórzenia” tego,
xs:choice
co następuje z powodumaxOccurs="unbounded"
. Dlatego kod, który opublikowałeś, jest poprawny i faktycznie będzie robił, co chcesz, tak jak napisałeś.źródło
Powinieneś zauważyć, że następujący schemat pozwala na to, co zaproponowałeś.
Umożliwi to utworzenie takiego pliku, jak:
Co wydaje się pasować do twojego pytania.
źródło
minOccurs
imaxOccurs
są ograniczone do 1 dla dzieci w wiekuxs:all
.Jeśli żadne z powyższych nie działa, prawdopodobnie pracujesz nad transakcją EDI, w której musisz zweryfikować swój wynik ze schematem HIPPA lub innym złożonym xsd w tym zakresie. Wymóg jest taki, że powiedzmy, że istnieje 8 segmentów REF i każdy z nich musi pojawić się w dowolnej kolejności, a także nie wszystkie są wymagane, co oznacza, że możesz mieć je w następującej kolejności: 1 REF, 3 REF, 2 REF, 9 REF. W sytuacji domyślnej odbieranie EDI nie powiedzie się, ponieważ domyślnym typem złożonym jest
Sytuacja jest nawet złożona, gdy wywołujesz swój element przez odwołanie, a wtedy ten element w swoim pierwotnym miejscu jest sam w sobie dość złożony. na przykład:
Rozwiązanie:
Tutaj zwykłe zastąpienie „sekwencji” słowem „wszystko” lub użycie „wyboru” kombinacjami min / maks nie zadziała!
Najpierw zastąp
"xs:sequence" with "<xs:all>"
Teraz, musisz dokonać pewnych zmian w miejscu, z którego odwołujesz się do elementu, przejdź do:*** Teraz w powyższym segmencie dodaj punkt wyzwalania na końcu, jak ten trigger_field = "REF01 _... pełna nazwa .." trigger_value = "38" Zrób to samo dla innych segmentów REF, w których wartość wyzwalania będzie inna, jak powiedzmy "18 ”,„ XX ”,„ YY ”itd., Aby informacje o Twoim rekordzie wyglądały teraz następująco:
b:recordinfo structure="delimited" field.........Biztalk/2003" trigger_field="REF01_...complete name.." trigger_value="38">
Dzięki temu każdy element będzie wyjątkowy, ponieważ wszystkie segmenty REF (powyższy przykład) mają taką samą strukturę jak REF01, REF02, REF03. Podczas walidacji walidacja struktury jest w porządku, ale nie pozwala na powtórzenie wartości, ponieważ próbuje szukać pozostałych wartości w samym REF. Dodanie wyzwalaczy sprawi, że wszystkie będą unikalne i przejdą w dowolnej kolejności i sytuacjach sytuacyjnych (np. Użyj 5 z 9, a nie wszystkich 9/9).
Mam nadzieję, że ci to pomoże, bo spędziłem nad tym prawie 20 godzin.
Powodzenia
źródło