2010-02-18 17 views
92

Próbuję utworzyć XSD i próbuje napisać definicję z następującymi wymaganiami:XSD - jak dopuszczać elementy w dowolnej kolejności dowolną liczbę razy?

  • Pozostawić element podrzędny określony pojawiać się dowolną liczbę razy (od 0 do nieograniczona)
  • Zezwalaj elementy dziecka do w dowolnej kolejności

Rozejrzałem się i znalazłem różne rozwiązania jak 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> 

Ale z tego co rozumiem xs: wybór nadal pozwala tylko na wybór jednego elementu. Dlatego ustawienie MaxOccurs tak nieograniczone powinno oznaczać tylko, że "dowolna" elementów podrzędnych może pojawić się wiele razy. Czy to jest dokładne?

Jeśli powyższe rozwiązanie jest nieprawidłowe, w jaki sposób mogę osiągnąć to, co wskazałem powyżej w moim wymaganiu?

EDYTOWANIE: Co się dzieje, jeśli wymaganie jest następujące?

  • Element child1 child2 może pojawić się dowolny liczbę razy (od 0 do nieograniczona)
  • Elements być w dowolnej kolejności
  • Elementy child3 i child4 powinien pojawić się dokładnie raz.

Na przykład ten XML jest poprawny:

<foo> 
<child1> value </child1> 
<child1> value </child1> 
<child3> value </child3> 
<child2> value </child2> 
<child4> value </child4> 
<child1> value </child1> 
</foo> 

ale to nie jest (brakuje child3)

<foo> 
<child1> value </child1> 
<child1> value </child1> 
<child2> value </child2> 
<child4> value </child4> 
<child1> value </child1> 
</foo> 

Odpowiedz

48

w schemacie masz w swoim pytaniu child1 lub child2 puszka pojawiają się w dowolnej kolejności, dowolną liczbę razy. To brzmi jak to, czego szukasz.

Edit: jeśli chciał tylko jeden z nich pojawiać się nieograniczoną liczbę razy, nieograniczona musiałby iść na elementach zamiast:

Edit: Fixed typu XML.

Edit: Skapitalizowana O w 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> 
+0

zasadzie tak, szukam elementów child1, child2 pojawić się w dowolnej kolejności, dowolną ilość razy .. odpowiedź podałeś tutaj działa tylko dla pojedynczego elementu, prawda? czy to też rozwiązuje moje wymagania? – jvtech

+0

Schemat w pytaniu spełnia twoje wymagania; alternatywny schemat w mojej odpowiedzi dotyczy jednego elementu. Mam nadzieję, że to wyczyści! :) – xcut

+0

@Pavel, @xcut, Dzięki za wyjaśnienia, zobacz edytowane wymagania .. jakieś przemyślenia? – jvtech

3

Należy zauważyć, że następujący schemat pozwala co masz zaproponował.

<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> 

To pozwoli na utworzenie pliku, takie jak:

<?xml version="1.0" encoding="utf-8" ?> 
<foo> 
    <child1>2</child1> 
    <child1>3</child1> 
    <child2>test</child2> 
    <child2>another-test</child2> 
</foo> 

co wydaje się dopasować swoje pytanie.

+0

'minOccurs' i' maxOccurs' są ograniczone do 1 dla dzieci z 'xs: all'. –

+0

Pavel: Dzięki ... Znalazłem to po dwukrotnym sprawdzeniu mojego wpisu, a następnie zredagowałem, aby usunąć xs: all –

8

Ale z tego co rozumiem xs: wybór nadal pozwala tylko na wybór jednego elementu.Dlatego ustawienie MaxOccurs tak nieograniczone powinno oznaczać tylko, że "dowolna" elementów podrzędnych może pojawić się wiele razy. Czy to jest dokładne?

nr Wybór dzieje się indywidualnie dla każdego „powtórzenie” z xs:choice że występuje z powodu maxOccurs="unbounded". W związku z tym kod, który wysłałeś, jest poprawny i faktycznie zrobi to, co chcesz, w formie pisemnej.

+0

Twój komentarz z odpowiedzią dostarczoną przez @Alan wyjaśnia wszystko ładnie. – bor

45

To co ostatecznie pracował dla mnie:

<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> 
+5

W rzeczywistości chodzi o użycie xsd: wybór z kwantyfikatorami tivo

+6

Myślę, że warto zauważyć, że powyższy przykład działa nawet bez elementu sekwencji zawierającego wybór- element. –

87

Alternatywą sformułowanie pytania dodana w późniejszym edycji wydaje nadal będzie bez odpowiedzi: jak określić, że wśród dzieci elementu, musi istnieć jeden o nazwie child3, o nazwie child4, i dowolnej liczbie o nazwie child1 lub child2, bez ograniczeń w kolejności, w jakiej pojawiają się dzieci.

Jest to prosty do zdefiniowania język regularny, a wymagany model zawartości jest izomorficzny względem wyrażenia regularnego, definiującego zestaw ciągów znaków, w których cyfry "3" i "4" występują dokładnie jeden raz, a cyfry "1". "i" 2 "występują dowolną liczbę razy. Jeśli nie jest to oczywiste, jak to napisać, może pomóc zastanowić się, jaki rodzaj maszyny skończonej zbudujesz, aby rozpoznać taki język. Byłoby mieć co najmniej cztery różne stany:

  • początkowy stan, w którym ani „3” ani „4” zaobserwowano
  • stan pośredni, w którym „3” zostało widziałem, ale nie „4”
  • stan pośredni, w którym „4” zaobserwowano, ale nie „3”
  • stanu końcowego, w którym zarówno „3” i „4” zostały zaobserwowane

Bez względu na to w jakim stanie automat jest włączony, można odczytać "1" i "2"; nie zmieniają stanu maszyny. W stanie początkowym będą również akceptowane "3" lub "4"; w stanach pośrednich akceptowane są tylko "4" lub "3"; w stanie końcowym nie przyjmuje się "3" ani "4". Struktura wyrażenia regularnego najłatwiej jest zrozumieć, jeśli najpierw zdefiniować regex dla podzbioru naszym języku, w którym tylko „3” i „4” występują:

(34)|(43) 

Aby zezwolić na „1” lub „2” występować dowolną liczbę razy w danej lokalizacji, możemy wstawić (1|2)* (lub [12]*, jeśli nasz język wyrażeń akceptuje tę notację). Wstawienie tego wyrażenia we wszystkich dostępnych lokalizacjach powoduje, że otrzymujemy

(1|2)*((3(1|2)*4)|(4(1|2)*3))(1|2)* 

Przetłumaczenie tego na model zawartości jest proste. Podstawowa struktura jest równoważna regex (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> 

Wkładanie zero-or-większy wybór child1 i child2 jest prosta:

<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> 

Jeśli chcemy zminimalizować większość trochę, my można zdefiniować grupę nazwaną dla powtarzających się wyborów child1 i child2:

<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> 

W XSD 1.1, niektóre z ograniczeń all -grupy zostały zniesione, więc jest to możliwe do zdefiniowania tego modelu treści bardziej zwięźle:

<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> 

Ale jak widać z przykładów podanych wcześniej te zmiany do all -grupy zrobić w rzeczywistości nie zmieniają ekspresyjnej siły języka; powodują, że definicja niektórych rodzajów języków jest bardziej zwięzła.

+1

Podoba mi się XSD 1.0 xs: wszystkie alternatywy. – TWiStErRob

+8

+1. Jest to doskonała odpowiedź i zasługuje na znacznie więcej awansów. –

+1

Świetna odpowiedź! Bardzo lubię takie wyjaśnienia. Ujawnia całą logikę i uzasadnienie osiągnięcia celu. Teraz nie tylko wiem, jak rozwiązać ten problem, ale nauczyłem się nowego podejścia do rozwiązywania podobnych problemów. Wyjaśnienie tego przy pomocy skończonej automatyzacji stanów jest bardzo dobrym pomysłem. – egelev

1

Jeśli żadna z powyższych nie działa, prawdopodobnie pracujesz nad trasracją EDI, w której musisz zweryfikować swój wynik w oparciu o schemat HIPPA lub inny złożony xsd. Wymagane jest, aby powiedzieć, że istnieje 8 segmentów REF i którekolwiek z nich musi pojawić się w dowolnej kolejności, a także, że nie wszystkie są wymagane, oznacza to, że możesz je mieć w następującej kolejności: 1. REF, 3rd REF, 2nd REF, 9 REF. Pod domyślnie sytuacja EDI odbierać zawiedzie, beacause domyślnego typu złożonego jest

<xs:sequence> 
    <xs:element.../> 
</xs:sequence> 

Sytuacja jest skomplikowana nawet gdy dzwonisz swoją elementu przez refrence i wtedy ten element w swoim pierwotnym miejscu jest dość skomplikowane sama. na przykład:

<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> 

Rozwiązanie:

Tutaj po prostu zastąpienie "sekwencji" z "all" lub za pomocą "Wybór" z min/max kombinacji nie będzie działać!

Pierwszą rzeczą zastąpić "xs:sequence" with "<xs:all>" Teraz trzeba dokonać pewnych zmian w której odnosimy się z elementu, Tam przejdź do:

<xs:annotation> 
    <xs:appinfo> 
    <b:recordinfo structure="delimited" field.........Biztalk/2003"> 

*** Teraz w powyższym segmencie dodać punkt aktywacji w koniec jak to trigger_field = "REF01 _... pełna nazwa .." trigger_value = "38" Zrób to samo dla innych segmentów REF, gdzie wartość wyzwalacza będzie inna niż powiedz "18", "XX", "YY" itd. dzięki temu informacje o rekordach wyglądają teraz następująco: b:recordinfo structure="delimited" field.........Biztalk/2003" trigger_field="REF01_...complete name.." trigger_value="38">


To sprawi, że każdy element będzie unikalny, ponieważ wszystkie segmenty REF (powyższy przykład) mają taką samą strukturę jak REF01, REF02, REF03. Podczas walidacji sprawdzanie poprawności struktury jest w porządku, ale nie pozwala na powtórzenie wartości, ponieważ próbuje wyszukać pozostałe wartości w samym pierwszym REF. Dodanie wyzwalaczy sprawi, że wszystkie będą unikalne i przejdą w dowolnej kolejności i sytuacyjnych przypadkach (np. Użyj 5 na 9, a nie wszystkie 9/9).

Mam nadzieję, że to pomaga, bo spędziłem prawie 20 godzin na ten temat.

Powodzenia

Powiązane problemy