2009-05-08 10 views
25

Definiuję element użytkownika z XSD. W tym przykładzie użytkownik ma nazwę, adres e-mail i jedną lub więcej narodowości. Próbowałem:Środkowy sposób między XSD all a XSD sequence

<xs:all> 
    <xs:element name="name" blabla /> 
    <xs:element name="email" blabla /> 
    <xs:element name="nationality" minOccurs="1" maxOccurs="unbounded" /> 
</xs:all> 

Jest to jednak nielegalne. Podobno elementy wewnątrz "Wszystkie" mogą wystąpić tylko raz (lub wcale). Mogę to naprawić, zmieniając Wszystko na Sekwencję, ale wtedy ludzie będą musieli wprowadzić właściwości w dokładnej kolejności, której naprawdę nie obchodzi.

Czy jest dostępna kombinacja tych dwóch? Nie według http://www.w3schools.com/Schema/schema_complex_indicators.asp, ale może jest ukryty (lub moje niedoświadczone oczy go nie widzą).

intuicją, próbowałem też:

<xs:all> 
    <xs:element name="name" blabla /> 
    <xs:element name="email" blabla /> 
    <xs:sequence> 
    <xs:element name="nationality" minOccurs="1" maxOccurs="unbounded" /> 
    </xs:sequence> 
</xs:all> 

Ale to niestety nieprawidłowy.


Oto aktualny, rzeczywisty, kawałek XSD:

<!-- user --> 
    <xs:complexType name="user"> 
    <xs:sequence> 
     <xs:element name="firstname" type="xs:string" minOccurs="1" maxOccurs="1" /> 
     <xs:element name="appendix" type="xs:string" minOccurs="0" maxOccurs="1" /> 
     <xs:element name="lastname" type="xs:string" minOccurs="1" maxOccurs="1" /> 
     <xs:element name="address" type="xs:string" minOccurs="1" maxOccurs="1" /> 
     <xs:element name="zipcode" type="xs:string" minOccurs="1" maxOccurs="1" /> 
     <xs:element name="city" type="xs:string" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="username" type="xs:string" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="email" type="xs:string" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="country" type="country" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="nationality" type="xs:string" minOccurs="1" maxOccurs="unbounded"/> 
    </xs:sequence> 
    </xs:complexType> 

Odpowiedz

3

Twój kod powinien być poprawny w XSD 1.1. W przypadku XSD 1.0 musisz znaleźć obejście.

+26

Jak używać, wprowadzać, włączać, tworzyć, ukrywać, migrować, tworzyć, znajdować lub wykonywać XSD 1.1? –

+3

Czy możesz podać różnicę między XSD 1.1 a XSD 1.0, która sprawia, że ​​jest ważna w wersji 1.1 i nieprawidłowa w wersji 1.0? –

+0

W specyfikacji 1.1 nie widzę żadnej wzmianki o ograniczeniu niezgodności XML OP. Niestety, nie mogę znaleźć specyfikacji 1.0, aby móc porównać. Domyślam się, że musisz sprawdzić wersję na bibliotekach, które będą analizować twój XML/XSD, aby wiedzieć, czy potrzebujesz któregokolwiek z poniższych trików. –

21

można po prostu włączyć „narodowości” thingie do własnej complexType a następnie użyć tego nowego typu złożonego wewnątrz firmy xs: all ?

<xs:complexType name="NationalityType"> 
    <xs:sequence> 
    <xs:element name="nationality" minOccurs="1" maxOccurs="unbounded" /> 
    </xs:sequence> 
</xs:complexType> 

<xs:all> 
    <xs:element name="name" blabla /> 
    <xs:element name="email" blabla /> 
    <xs:element name="nationalities" type="NationalityType" /> 
</xs:all> 

Nie mam nic na rękę, aby to przetestować, więc to jest naprawdę tylko z mojej głowy ..... spróbuj!

EDIT: testowany go teraz - to działa, tylko drobne cena za to, że XML będzie musiał wyglądać następująco:

<....> 
    <email>......</email> 
    <nationalities> 
    <nationality>ABC</nationality> 
    <nationality>CDE</nationality> 
    </nationalities> 
    <name>.....</name> 
</.....> 

więc masz dodatkowy węzeł, który będzie zawierał arbitralne długa lista pozycji <nationality>.

Marc

+4

Ta odpowiedź jest jedyną poprawną. Potrzebujesz tablicy narodowości. Wszystkie inne metody są po prostu hackami, które łamią zasady XML. –

0

Albo, ponieważ „USER” zostanie utworzona z wielu elementów podrzędnych, dlaczego nie ustawić go jako typ złożony? Coś takiego powinno zadziałać.

+1

To już jest typ złożony. Dodałem prawdziwy XSD do pytania, więc możesz go też zobaczyć :) –

0

xs:choice nie będzie działać? Jeśli nie, po prostu włóż to w sekwencję lub odwrotnie.

+0

Huh? Jak by to pomogło? Proszę podać przykład. –

7

Myślę, że to, czego szukasz, byłoby sprzeczne z intencją XML. Byłoby dziwne, posiadać ważny fragment XML tak:

<user> 
    <nationality/> 
    <name/> 
    <nationality/> 
    <email/> 
    <nationality/> 
</user> 

Brzmi jak pytasz o coś podobnego co marc_s zaproponował:

<user> 
    <name/> 
    <email/> 
    <nationality/> 
    <nationality/> 
    <nationality/> 
<user> 

który musi się zepchnięci na:

<user> 
    <name/> 
    <email/> 
    <nationalities> 
    <nationality/> 
    <nationality/> 
    <nationality/> 
    </nationalities> 
<user> 
1

Dla XSD 1.0 sugestia od leppie działa.

XSD

<?xml version='1.0' encoding='UTF-8'?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name='user'> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="name" type="xs:string" /> 
     <xs:element name="email" type="xs:string" /> 
     <xs:choice minOccurs='0' maxOccurs='unbounded'> 
      <xs:element name="nationality" /> 
     </xs:choice> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

Przykładowy dokument XML, który sprawdza poprawność przeciwko schematu

<user> 
    <name>Name</name> 
    <email>[email protected]</email> 
    <nationality>Italian</nationality> 
    <nationality>Japanese</nationality> 
    <nationality>Alien</nationality> 
</user> 

i walidacji np stosując xmllint

xmllint --noout --schema test.xsd test.xml 
test.xml validate 
+0

Nie ma potrzeby "wyboru" w podanym przykładzie. O ile użyjesz elementu "sequence" w środku, może on mieć maxOccurs = "unbounded". Ale kolejność narzuca porządek elementów wewnątrz - to był problem w początkowym pytaniu. –

+0

W pozytywnym tonie ta odpowiedź pokazuje, że elementy grupy modeli "all", "sequence" i "choice" mogą być zagnieżdżane. Podobnie, przynajmniej w 1.1, można zdefiniować grupy i odnieść się do nich, patrz http://www.w3.org/TR/xmlschema11-1/#cModel_Group_Definitions, które pozwoliłyby uniknąć dodania nowego elementu "container", tak jak robi to odpowiedź marc_s. –

20

Wystarczy natknąć się na podobny problem (chciałem mieć dowolną liczbę każdego elementu w dowolnej kolejności) i rozwiązać go z serią wyborów. Na powyższym przykładzie:

<?xml version='1.0' encoding='UTF-8'?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name='user'> 
    <xs:complexType> 
     <xs:sequence minOccurs="0" maxOccurs="unbounded"> 
     <xs:choice> 
      <xs:element name="name" type="xs:string" /> 
      <xs:element name="email" type="xs:string" /> 
      <xs:element name="nationality" /> 
     </xs:choice> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

Pozwala to na dowolną liczbę nazwisk, adresów e-mail i narodowości w dowolnej kolejności.

+6

To jednak pozwoliłoby na wiele elementów wewnątrz ? –