2009-01-06 10 views
17

To jest pytanie schematu XML.XSD - Jak opisać nieuporządkowany zestaw typów elementów, w którym pierwszy element musi pojawić się jako pierwszy w sekwencji?

Wiem, że element xsd:all nie może pojawić się w sekwencji (musi to być element najwyższego poziomu tego typu).

Oznacza to, że nie można korzystać z następujących powodów:

<xsd:complexType name="Application"> 
    <xsd:sequence> 
    <xsd:element ref="Name"></xsd:element> 
    <xsd:all> 
     <xsd:element ref="ADD"></xsd:element> 
     <xsd:element ref="DELETE"></xsd:element> 
    </xsd:all> 
    </xsd:sequence> 
</xsd:complexType> 

Moje pytanie brzmi: w jaki sposób zadeklarować „Dodaj” i „DELETE” elementy powyżej w dowolnej kolejności (nieuporządkowanej zestawie), ale nadal upewnij się, że element "Imię" będzie pierwszym i zawsze się pojawi. (Pomyśl o sytuacji, w której mam nie tylko "DODAJ" i "USUŃ", ale około 10 lub więcej nieuporządkowanych zestawów elementów: DODAJ, USUŃ, EDYTUJ itd.)

WAŻNA UWAGA: ADD i DELETE mogą być wyświetlane tylko raz, ale ich kolejność nie ma znaczenia:

<Application> 
    <NAME> 
    <DELETE> 
    <ADD> 
</Application> 

lecz nie:

<Application> 
    <NAME> 
    <DELETE> 
    <ADD> 
    <DELETE> <!--cannot appear twice--> 
</Application> 

Odpowiedz

17

Jeśli rozumiem Twoją prośbę jesteś na dobrej drodze, jedyną rzeczą, której brakuje jest maxOccurs = „nieograniczona” na twój wybór.

stworzyłem następujący schemat:

<?xml version="1.0"?> 
<xs:schema targetNamespace="http://someNamespace" xmlns="http://someNamespace" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="Root" type="Application"> 
    </xs:element> 

    <xs:complexType name="Application"> 
    <xs:sequence> 
     <xs:element ref="Name"></xs:element> 
     <xs:choice maxOccurs="unbounded"> 
     <xs:element ref="ADD"></xs:element> 
     <xs:element ref="DELETE"></xs:element> 
     </xs:choice> 
    </xs:sequence> 
    </xs:complexType> 

    <xs:element name="Name"/> 
    <xs:element name="ADD"/> 
    <xs:element name="DELETE"/> 
</xs:schema> 

I to działało dobrze dla

<ns0:Root xmlns:ns0="http://someNamespace"> 
    <ns0:Name /> 
    <ns0:ADD /> 
    <ns0:ADD /> 
    <ns0:DELETE /> 
    <ns0:ADD /> 
    <ns0:DELETE /> 
    <ns0:DELETE /> 
</ns0:Root> 

ale nie dla

<ns0:Root xmlns:ns0="http://someNamespace"> 
    <ns0:ADD /> 
    <ns0:ADD /> 
    <ns0:DELETE /> 
    <ns0:ADD /> 
    <ns0:DELETE /> 
    <ns0:DELETE /> 
</ns0:Root> 
+0

Bardzo dziękuję za odpowiedź. Dokładnie podniosłem moje pytanie powyżej. Miałem na myśli, że ADD i DELETE nie powinny pojawić się 0 lub 1 razy, ale ich kolejność nie ma znaczenia. "all" nie może być użyty w tym przypadku, ponieważ element obowiązkowy NAME nie może być oznaczony jako "all". Czy masz jakieś inne rozwiązanie? Dziękujemy – ogee

+0

Działa tylko z atrybutem maxOccurs = "nieograniczony" dla znacznika wyboru – Pooya

3

nie wierzę, można to zrobić bez wyliczania każda kombinacja ADD, DELETE itd. Ogólnie mówiąc nieuporządkowane listy nie grają dobrze, ani z DTD, ani sc hemas.

+3

opisuje nieuporządkowaną listę – lbalazscs

+0

@lbalazscs - Z pytania "WAŻNA UWAGA: ADD i DELETE może pojawić się tylko raz, ale ich kolejność nie ma znaczenia: ". maxOccurs = "unbounded" nie dostarczy tego. – Alohci

+0

Alhoci, tak, OP chciał nieuporządkowanego SET, ale nieuporządkowane LISTY są nadal możliwe. Dodałem ten komentarz, ponieważ zostałem wprowadzony w błąd przez twoją odpowiedź (miałem inny problem, gdzie elementy mogły się pojawić w dowolnym momencie), tylko po to, aby odkryć później, że nieuporządkowane listy są absolutnie możliwe. – lbalazscs

1

Możesz implementować nieuporządkowane listy używając typu sekwencji xs:choice.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
<xs:element name="Application"/> 
    <xs:complexType> 
    <xs:element name="NAME"> 
    <xs:sequence> 
    <xs:choice minOccurs="0" maxOccurs="unbounded"> 
     <xs:element name="ADD" type="xs:string"/> 
     <xs:element name="DELETE" type="xs:string"/> 
    </xs:choice> 
    </xs:element> 
    </xs:sequence> 
    </xs:complexType> 
</xs:element> 
</xs:schema> 

W ten sposób można ograniczyć użytkownikowi korzystanie z dowolnego tagu chcą wewnątrz elementu <NAME/> ale pozwalają im korzystać <ADD/> i <DELETE/> tak często, jak im się podoba.

+0

Czy w tym przypadku jest konieczne ""? – LarsH

+1

@LarsH: Tak, ponieważ xs: choice pozwala tylko wybrać jeden z wymienionych elementów. xs: sequence tutaj tworzy nieograniczony/powtarzalny wybór ADD lub DELETE. Jednak nie spełnia wymagań PO, aby nie dopuszczać więcej niż jednego wystąpienia ADD i DELETE każdego naraz. –

4

Przykro mi, że trudziłeś się z tym problemem przez 7 lat bez odpowiedzi.

Zamierzam pomóc, ponownie analizując twoje założenia.

Traktując "Imię" jako część danych, która musi nadejść jako pierwsza i wymagając, aby była ona dzieckiem Aplikacji, a następnie mówiąc ogólnie, że nie obchodzi Cię kolejność rodzeństwa, tworząc dla siebie dezorientującą sytuację. Dlaczego imię jest rodzajem ADD i DELETE, jeśli przestrzega różnych zasad i służy innym celom? Gdybyś musiał modelować to w dowolnej innej strukturze danych, nie umieszczałbyś "Nazwa" na liście rzeczy obok "ADD" i "DELETE". Powiedziałbyś dwie rzeczy: Aplikacja ma Nazwę, a także listę poleceń, takich jak DODAJ i USUŃ.

Ponieważ Nazwa jest czymś specjalnym w porównaniu z ADD i DELETE, powinna być modelowana oddzielnie od innych tagów.

Można więc ustawić nazwę jako atrybut aplikacji i zachować jako elementy podrzędne Dodaj i usuń, lub zachować nazwę jako element podrzędny, ale następnie otaczać ADD i DELETE za pomocą znacznika zastępczego/grupy, takiego jak polecenia . Tag Commands byłby jedynym rodzeństwem Name.

Oto schemat obsługujący nazwę jako atrybut z dowolną liczbą poleceń w dowolnej kolejności. "Nazwa jako Attribute.xsd":

<?xml version="1.0"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="Application" type="Application_Type" /> 
    <xs:complexType name="Application_Type"> 
      <xs:all> 
       <xs:element minOccurs="0" ref="ADD"/> 
       <xs:element minOccurs="0" ref="DELETE"/> 
       <xs:element minOccurs="0" ref="THIRD"/> 
       <xs:element minOccurs="0" ref="FOURTH"/> 
      </xs:all> 
      <xs:attribute name="Name"/> 
    </xs:complexType> 
    <xs:element name="ADD"/> 
    <xs:element name="DELETE"/> 
    <xs:element name="THIRD"/> 
    <xs:element name="FOURTH"/> 
</xs:schema> 

Przykład XML:

<?xml version="1.0" encoding="UTF-8"?> 
<Application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="text" xsi:noNamespaceSchemaLocation="Name as Attribute.xsd"> 
    <THIRD>text</THIRD> 
    <ADD>text</ADD> 
    <FOURTH>text</FOURTH> 
    <DELETE>text</DELETE> 
</Application> 

A oto jeden z tych poleceń zagnieżdżonych wewnątrz znacznika zastępczego. "Polecenia Grouping.xsd":

<?xml version="1.0"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="Application" type="Application_Type"/> 
    <xs:complexType name="Application_Type"> 
     <xs:sequence> 
      <xs:element ref="Name"/> 
      <xs:element name="Commands" type="Commands_Type"/> 
     </xs:sequence> 
    </xs:complexType> 
    <xs:complexType name="Commands_Type"> 
     <xs:all> 
      <xs:element minOccurs="0" ref="ADD"/> 
      <xs:element minOccurs="0" ref="DELETE"/> 
      <xs:element minOccurs="0" ref="THIRD"/> 
      <xs:element minOccurs="0" ref="FOURTH"/> 
     </xs:all> 
    </xs:complexType> 
    <xs:element name="Name"/> 
    <xs:element name="ADD"/> 
    <xs:element name="DELETE"/> 
    <xs:element name="THIRD"/> 
    <xs:element name="FOURTH"/> 
</xs:schema> 

Przykład XML:

<?xml version="1.0" encoding="UTF-8"?> 
<Application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Commands Grouping.xsd"> 
    <Name>text</Name> 
    <Commands> 
     <THIRD>text</THIRD> 
     <ADD>text</ADD> 
     <FOURTH>text</FOURTH> 
     <DELETE>text</DELETE> 
    </Commands> 
</Application> 

Jedna uwaga na temat jednego z nich jest to, że wiadomości z zerowymi polecenia są wciąż aktualne przesłanie. Być może jest to w porządku, ale jeśli jest to problem, być może ta walidacja należy do warstwy aplikacji, a nie do XSD.