Przypominamy, że standard XML Schema zdefiniowany jest w trzech rekomendacjach:
XML Schema pozwala wymusić, by pewne wartości w dokumencie były unikalne.
Do wymuszania unikalności służą elementy schematu: unique
i key
.
Opisy w rekomendacji: Primer,
Structures.
Podelement selector
określa zakres, w jakim wartości mają być unikalne.
Podelement field
określa wartość, która ma być unikalna. Może być wiele podelementów
field
– wówczas unikalna musi być krotka wartości (i ona stanowi wartość klucza).
Zakres oraz wartości określa się za pomocą wyrażeń XPath, przy czym
nie wszystkie wyrażenia są tu dopuszczalne,
m.in. nie można używać predykatów
ani osi innych niż child
i attribute
.
Wyrażenie w selector
wskazuje w dokumencie zbiór elementów. Dla każdego z tych elementów
wartość wyrażenia z każdego field
musi wyliczyć się do dokładnie jednego elementu lub atrybutu
z prostym typem zawartości. Dla key
każda z tych wartości dodatkowo musi być niepusta.
Krotki wartości z field
, które mają wszystkie wartości niepuste, muszą być parami różne
(w obrębie jednego klucza).
<xs:unique name="studenci_unique"> <xs:selector xpath="studenci/student"/> <xs:field xpath="imie"/> <xs:field xpath="nazwisko"/> </xs:unique> <xs:key name="studenci_key"> <xs:selector xpath="studenci/student"/> <xs:field xpath="nr-indeksu"/> </xs:key>
W XML Schema można także wymusić, aby pewne wartości w dokumencie były równe wartościom występującym w innym miejscu dokumentu.
Mówiąc precyzyjnie, można określić, że pewna wartość (krotka wartości) jest referencją do klucza (key
lub unique
). Krotność klucza i referencji muszą się zgadzać.
<xs:keyref name="grupy_studenci_ref" refer="studenci_key"> <xs:selector xpath="grupy/grupa/student"/> <xs:field xpath="@ref"/> </xs:keyref>
termin-zajec
zawierający informacje o sali,
w jakiej zajęcia się odbywają (referencja), oraz terminie zajęć (dzień tygodnia,
godziny rozpoczęcia i zakończenia).termin-zajec
.
Elementy key
, unique
i keyref
umieszcza się wewnątrz
element
i obowiązują one dla zawartości tego elementu. Jeśli element ten w dokumencie
występuje wielokrotnie, to dla każdego egzemplarza klucze i referencje działają niezależnie.
Wymuś, aby wewnątrz grupy studenci nie powtarzali się.
XML Schema pozwala na tworzenie typów na podstawie innych, już zdefiniowanych typów. Dzięki temu schematy mogą być bardziej strukturalne i rozszerzalne.
Możliwe jest rozszerzanie typów złożonych oraz zawężanie typów złożonych i prostych. Warto zaznaczyć, że rozszerzanie i zawężanie nie są tu operacjami przeciwnymi. Rozszerza się strukturę, np. o nowe podelementy, a zawęża dopuszczalny zbiór wartości, poprzez dodawanie lub wzmacnianie ograniczeń.
Przykłady w ramkach pochodzą z rekomendacji Primer, poza tym jeden przykład, do zadań.
Zawężanie typów prostych było omówione na poprzednich zajęciach. Z zawężaniem typów prostych wiąże się pojęcie facet.
Aby zawartość elementu była typu prostego, ale element ten posiadał atrybuty, należy utworzyć typ złożony z prostą zawartością.
Opis w rekomendacji: nieformalny i formalny.
<xsd:element name="internationalPrice"> <xsd:complexType> <xsd:simpleContent> <xsd:extension base="xsd:decimal"> <xsd:attribute name="currency" type="xsd:string"/> </xsd:extension> </xsd:simpleContent> </xsd:complexType> </xsd:element>
Rozszerzanie typów złożonych bardzo przypomina dziedziczenie klas w obiektowych językach programowania. Do typu podstawowego można dodać kolejne podelementy i atrybuty, tak jak do klas dodaje się pola i metody.
Model typu podstawowego i model z rozszerzenia są ustawiane jeden po drugim w sekwencji.
Opis w rekomendacji: nieformalny i formalny.
Przykład z rekomendacji.
<complexType name="Address"> <sequence> <element name="name" type="string"/> <element name="street" type="string"/> <element name="city" type="string"/> </sequence> </complexType> <complexType name="UKAddress"> <complexContent> <extension base="ipo:Address"> <sequence> <element name="postcode" type="ipo:UKPostcode"/> </sequence> <attribute name="exportCode" type="positiveInteger" fixed="1"/> </extension> </complexContent> </complexType>
Daje to nastepujący wynikowy model zawartości:
<complexType name="UKAddress"> <sequence> <!-- content model of Address --> <element name="name" type="string"/> <element name="street" type="string"/> <element name="city" type="string"/> <!-- appended element declaration --> <element name="postcode" type="ipo:UKPostcode"/> </sequence> <!-- appended attribute declaration --> <attribute name="exportCode" type="positiveInteger" fixed="1"/> </complexType>
Zawężanie typów złożonych polega na nałożeniu na typ dodatkowych ograniczeń lub wzmocnieniu istniejących.
Opis w rekomendacji: nieformalny i formalny.
<complexType name="PurchaseOrderType"> <sequence> <element name="shipTo" type="ipo:Address"/> <element name="billTo" type="ipo:Address"/> <element ref="ipo:comment" minOccurs="0"/> <element name="items" type="ipo:Items"/> </sequence> <attribute name="orderDate" type="date"/> </complexType> <complexType name="RestrictedPurchaseOrderType"> <complexContent> <restriction base="ipo:PurchaseOrderType"> <sequence> <element name="shipTo" type="ipo:Address"/> <element name="billTo" type="ipo:Address"/> <element ref="ipo:comment" minOccurs="1"/> <element name="items" type="ipo:Items"/> </sequence> </restriction> </complexContent> </complexType>
Przykłady innych możliwych ograniczeń w tabeli.
Stwórz typ PracownikTyp
jako rozszerzenie (lub zawężenie...) typu OsobaTyp
,
w którym atrybut email
jest obowiązkowy oraz występuje dodatkowy sztuczny identyfikator.
Zdefiniuj element pracownik
o tym typie. Do dokumentów dodaj sekwencję pracowników.
Do informacji o przedmiocie oraz o grupie dodaj referencję do prowadzącego (pracownika),