XML – ćwiczenia 5: XML Schema

Przypominamy, że standard XML Schema zdefiniowany jest w trzech rekomendacjach:

Klucze i referencje

Wartości unikalne i klucze

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).

Przykład 1.

<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>

Zadanie 1.

Do schematu dla "sklepu" z poprzednich zajęć dodaj więzy wymuszające:

  • unikalność id towarów w katalogu
  • unikalność nazw towarów w katalogu
  • unikalność towarów w obrębie każdego zamówienia

To the "shop" schema from previous classes, add contraints enforcing the following:

  • identifiers of articles are unique,
  • names of articles are unique,
  • articles within orders are unique.

Zakres obowiązywania

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.

Zadanie 2.

Do zamówienia dodaj pola (atrybuty lub elementy) numer i rok. Wymuś, aby para tych wartości była unikalna dla zamówień (ale np. w różnych latach mógł występować ten sam numer).


Add new fields to order elements: year and number. Enforce such pairs of vlues to be unique for orders (but, for example, the same number can be used in different years).

Referencje

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ć.

Przykład 2.

<xs:keyref name="grupy_studenci_ref" refer="studenci_key">
	<xs:selector xpath="grupy/grupa/student"/>
	<xs:field xpath="@ref"/>
</xs:keyref>

Zadanie 3.

Wewnątrz zamówień nie umieszczaj całych elementów towar. Zamiast tego odwołuj się do towarów po ich id. Użyj więzu integralności keyref, aby wymusić, że id użyte w odwołaniu jest identyfikatorem istniejącego towaru.


In orders, refer to articles using their id and do not copy the content of article element within orders. Use keyref constraint to enforce that the id used in article reference is a valid article identifier.

Modyfikowanie typów

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

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.

Typ złożony z typu prostego

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.

Przykład 3.

<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

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 4.

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

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.

Przykład 5.

<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.

Zadanie 4.

Użyj rozszerzenia, aby zdefiniować typy dla towarów z określonych kategorii, dla których podane są specyficzne cechy, np. rozdzielczość dla aparatów fotograficznych, itp.


Use complex type extension to define types for more specific categories of articles and to give them some additional properties, for example resolution for cameras...


Valid XHTML 1.1Valid CSS