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
)
zdefiniowanego w tym samym schemacie. 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 w danej grupie studenci nie powtarzali się.
Definiowanie kluczy i referencji jest możliwe także w DTD, jednak w bardzo ograniczony sposób.
Atrybuty mogą posiadać typ ID
. Wartością takiego atrybutu może być tylko nazwa
(m.in. musi zaczynać się od litery). Dla danej nazwy elementu tylko jeden atrybut może posiadać
typ ID. W całym dokumencie wszystkie atrybuty o typie ID
muszą posiadać unikalne wartości.
Atrybuty mogą posiadać typ IDREF
. Wartością takiego atrybutu może być tylko nazwa.
Nazwa ta musi występować gdzieś w dokumencie jako wartość atrybutu i tyie ID
.
Jak widać technika ta jest bardzo ograniczona. M.in. kluczami nie mogą być elementy, identyfikatorami mogą być tylko nazwy, identyfikatory muszą być unikalne w skali całego dokumentu.
Typy ID
i IDREF
wsytępują w XML Schema dla zachowania kompatybilności
z DTD, ale, o ile nie jest to konieczne, nie należy ich używać, a do definiowania kluczy i referencji
należy stosować key
i keyref
.
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,