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.
W szczególności selektorem może być jedynie zbiór elementów, a polami całe elementy i atrybuty, nie można uzywać 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.
<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>
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
.
Przykład schematu i dokumentu.
Do schematu uczelnia.xsd dodaj listę przedmiotów i sal.
Niech numer sali będzie jej kluczem, a przedmioty niech mają sztuczny klucz jako atrybut. Dodatkowo nazwy przedmiotów niech będą unikalne.
Zdefiniuj element 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).
W grupach dodaj referencje do przedmiotów i podelementy termin-zajec
.
XML Schema pozwala na tworzenie typów na podstawie innych, już zdefiniowanych typów deriving types. 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 listę pracowników.
Do informacji o przedmiocie oraz o grupie dodaj referencję do prowadzącego,