1 Polsko-Japońska Wyższa Szkoła Technik KomputerowychTechnologie Internetu wykład 9: XML Schema Piotr Habela Polsko-Japońska Wyższa Szkoła Technik Komputerowych 1
2 W poprzednim odcinku… Zastosowanie definicji typów dokumentów;Rozwiązania DTD (Document Type Definition): Definicja zewnętrzna lub wewnętrzna; Rodzaje odwołań do zasobów zewnętrznych; Elementy proste (znakowe, puste, dowolne); Modele zawartości elementowej (liczności, wybór, sekwencje); Deklaracje elementów: dostępne typy oraz wartości domyślne; Rodzaje encji (entities) w XML; Rola przestrzeni nazwowych (namespaces); Ograniczenia DTD. XML Schema: Rozbudowany system typów; Obsługa przestrzeni nazwowych. 2
3 Plan wykładu Budowa dokumentu XML Schema:Najważniejsze możliwości XML Schema; Deklarowanie atrybutów i zawartości elementowej; Typy wbudowane XML Schema; Tworzenie typów pochodnych: poprzez ograniczenia i poprzez rozszerzenia; Sposoby organizowania podelementów; Ograniczenia unikalności; … Język XPath: Sposoby nawigacji; Skróty; Predykaty; Dostępne operacje. 3
4 XML Schema – podstawowe informacjeInstance document oznacza dokument zbudowany zgodnie z daną specyfikacją schematu. Dokument-wystąpienie nie musi obowiązkowo odwoływać się do swojej specyfikacji schematu. Schematy XML Schema są zwykle umieszczane w odrębnych plikach – zwyczajowo z rozszerzeniem .xsd. Ten skrót jest również używany do oznaczenia przestrzeni nazwowej (namespace), obejmującej standardowe elementy XML Schema. Definicja schematu zawarta jest w elemencie-korzeniu XML o nazwie schema:
5 Składniki definicji schematuObok deklaracji elementów i atrybutów, istnieje możliwość globalnego zdefiniowania: własnego typu prostego. Wówczas zawartością definicji typu jest ograniczenie któregoś z wbudowanych typów prostych (zob. dalej):
6 Kompozycyjność definicji schematówDeklaracje atrybutów mogą występować w ramach definicji typu złożonego albo w ramach definicji elementu. Deklaracje elementów mogą występować globalnie, w ramach definicji typu złożonego albo w ramach definicji innego elementu. Definicje typów mogą wystąpić globalnie (z nadaniem nazwy atrybutem name) albo wewnątrz deklaracji opisywanego przezeń elementu (anonimowo, celem jednorazowego wykorzystania w miejscu definicji); Zwróćmy uwagę na to kluczowe rozróżnienie: Definicje typów tworzą nowe typy dostępne do wykorzystania; Deklaracje elementów określają nazwy i typy elementów i atrybutów, które mogą pojawić się w odpowiednich miejscach dokumentu. 6
7 Definicje typów a elementy złożoneDefinicja typu – umieszczona w korzeniu schematu: można się doń potem odnosić w deklaracjach elementów w sposób analogiczny jak dla atrybutów prostych => czytelniejsze deklaracje oraz ponowne użycie definicji typów; Definicja typu złożonego: konstruowana elementem xsd:complexType; może zawierać deklaracje elementów, atrybutów oraz referencji do elementów; nie może być użyta w deklaracjach atrybutów; Deklaracja elementu poprzez podanie typu: Podanie w atrybucie type nazwy globalnie zdefiniowanego typu; Deklaracja poprzez referencję: powoduje wstawienie do bieżącej deklaracji globalnie zadeklarowanego elementu o podanej nazwie:
8 Deklarowanie zawartości elementowejZarówno w definicjach globalnych typów jak i w deklaracjach elementów złożonych, podelementy definiujemy wewnątrz elementu xsd:complexType. Ograniczenia na liczbę wystąpień podelementów: domyślnie dolną a zarazem górną granicą liczności jest „dokładnie 1”; liczności te można modyfikować za pomocą atrybutów: elementu minOccurs i maxOccurs, których wartościami muszą być liczby naturalne. Wartością specjalną dla atrybutu maxOccurs może być ponadto ”unbounded”. Deklaracje liczności nie są dozwolone dla elementów globalnych. 8
9 Deklarowanie atrybutówAtrybuty (poza globalnymi) deklarujemy wewnątrz elementu xsd:complexType. Mogą posiadać wyłącznie typy proste. Występowanie atrybutu określone jest atrybutem (tj. atrybutem w elemencie xsd:attribute) use, mogący przybierać wartość: ”optional”, ”required” lub ”prohibited”. Domyślną deklaracją (przy pominięciu) jest ”optional”. Domyślną wartość atrybutu można przypisać stosując atrybut defalut. Atrybut use musi wówczas przybrać wartość ”optional”. Wymuszenie stałej wartości atrybutu osiągamy poprzez zastosowanie w jego deklaracji atrybutu fixed=”wartość”. Wówczas, jeśli atrybut jest opcjonalny, wymagana jest albo jego nieobecność w wystąpieniu albo jego wystąpienie ze zgodną wartością. Atrybut default stosuje się też w deklaracjach elementów. Tu jednak podstawienie wystąpi tylko wtedy, gdy w dokumencie dany element pojawi się bez zawartości (jeśli nie wystąpi w ogóle, to do podstawienia nie dojdzie). 9
10 Typy wbudowane Specyfikacja określa wiele wbudowanych typów prostych. Część z nich zdefiniowano poprzez nałożenie restrykcji na definicje bardziej podstawowe. Niektóre typy wbudowane: string, normalizedString, token, byte, unsignedByte positiveInteger, negativeInteger, nonPositiveInteger, nonNegativeInteger integer, long, decimal, float, boolean base64Binary -> każde 6 bitów kodowane symbolem alfanumerycznym; time - np. 13:20:00.000, 13:20: :00 dateTime - np T13:20: :00 duration - np. P1Y2M3DT10H30M12.3S date (oraz ich wycinki) - np anyURI - np. language - np. en-US, pl ID, IDREF, IDREFS, NOTATION… 10
11 Definiowanie typów pochodnych przez ograniczeniaTworzeniu pochodnych typów prostych poprzez nakładanie ograniczeń służy element xsd:restriction, umieszczany wewnątrz elementu xsd:simpleType. Element restriction zawiera atrybut base, określający typ bazowy definicji. Może zawierać szereg podelementów, określanych jako constraining facets (aspekty ograniczające). Np. dla typów liczbowych można użyć elementów xsd:maxExclusive i xsd:minInclusive z atrybutem value=”warośćLiczbowa”. Np.
12 Inne aspekty ograniczające (1)Dla atrybutów xsd:string i pochodnych można sformułować wzorzec przy użyciu wyrażeń regularnych: umieszczamy podelement xsd:pattern z atrybutem value=”wyrażenieRegularne”. Np. "\d{3}-[A-Z]{2}" oznacza trzy cyfry dziesiętne, myślnik oraz dwie wielkie litery.
13 Inne aspekty ograniczające (2)Kolejną możliwością jest podanie dozwolonych wartości danego typu w postaci wyliczenia (enumeration). Służą temu podelementy xsd:enumeration z atrybutami value:
14 Właściwości aspektów ograniczającychŁączenie aspektów ograniczających: aspekty wzorca współistniejące dla danej definicji z typem wyliczeniowym są traktowane alternatywnie (suma logiczna); inne kombinacje aspektów ograniczających stanowią warunek w postaci iloczynu logicznego. Blokowanie właściwości aspektów – uniemożliwi redefinicję danego ograniczenia w typie pochodnym: fixed=”true”; Ograniczenia można też stosować do typów złożonych. W tym wypadku wyprowadzanie poprzez zawężenie liczby wystąpień wymaga ponownego podania całej ich zawartości. Jednakże korzyścią pozostaje w takim wypadku zgodność typologiczna z nadtypem. 14
15 Typy pochodne – pozostałe możliwościRozszerzenia: przypominają specjalizację klas w językach programowania. Składnia analogiczna jak w wypadku ograniczeń. Zamiast xsd:constraint stosuje się xsd:extension:
16 Organizacja podelementówPodelementy mogą być grupowane (za pomocą znaczników zwanych compositors) w kompozycje trzech rodzajów: Sekwencja: wszystkie podelementy muszą wystąpić dokładnie w podanej kolejności:
17 Zawartość prosta z atrybutamiMusimy użyć complexType (a nie simpleType), gdyż ten pierwszy nie pozwala na zdefiniowanie atrybutów. Wewnątrz complexType umieszczamy:
18 Grupy elementów i atrybutówOgraniczają nadmiarowość definicji schematu. Zastosowanie (ograniczenie nadmiarowości i uczynienie schematów bardziej przejrzystymi) odpowiada encjom parametrycznym z DTD. Do zadeklarowania grupy stosowane są elementy odpowiednio:
19 Ograniczenia unikalności (1)W wypadku DTD jedynym (mało elastycznym) środkiem zapewnienia unikalności było użycie typu ID. Ograniczenia unikalności deklaruje się na końcu deklaracji elementu, którego dotyczą, albo w elementach nadrzędnych (najczęściej umieszczane są w końcu elementu korzenia (xsd:schema). Postać ograniczenia:
20 Ograniczenia unikalności (2)Selektory i pola wskazujemy używając atrybutu xpath. Jak sugeruje nazwa, identyfikuje on zawartość dokumentu XML w sposób określony specyfikacją XPath. Jak zobaczymy, ograniczenia na miejsce występowania deklaracji unikalności wynikają właśnie z założeń specyfikacji XPath. Podobne do ograniczenia xsd:key jest xsd:unique. To drugie odróżnia się dopuszczalnością pustych elementów (i niepowtarzalność sprawdza się wówczas tylko pośród niepustych elementów). Zarówno ograniczenie unikalności jak i ograniczenie klucza mogą dotyczyć wartości złożonych. Integralność referencyjna – określa zależność klucza obcego. Przedmiotem odwołania musi być wartość zadeklarowana jako klucz. Deklarowane za pomocą elementu keyref:
21 Definiowanie list Zawartością elementu a także atrybutu może być kolekcja wartości typu prostego, rozdzielona znakami białymi. Tego rodzaju zawartość deklaruje się jako listę (list) określonego typu bazowego. Listy nie mogą składać się z innych list. Deklaracje – za pomocą elementu xsd:list:
22 Wariantowe definicje typów (unie)Dopuszczalne wartości typów prostych można definiować jako sumę wartości dopuszczanych przez dwa lub więcej typów. Deklaracji takich typów służą unie (unions). Wewnątrz elementu
23 Synonimy oraz byty abstrakcyjneAby dla definicji danego elementu umożliwić tworzenie jego wystąpień pod różnymi nazwami (synonimy lub wersje językowe), stosowane są tzw. grupy substytucji (substitutionGroups).
24 Sposoby budowy schematów - podsumowaniePoprzez zagnieżdżanie: definicje potrzebnych typów tworzone anonimowo na potrzeby poszczególnych deklaracji. Płaski katalog elementów: elementy tworzące hierarchię są deklarowane globalnie, zaś w ich docelowych miejscach występowania w schemacie stosuje się odwołania do tych globalnych deklaracji. Definiowanie typów: globalnie są definiowane nazwane typy, wykorzystywane następnie w deklaracjach elementów i atrybutów. Metoda najskuteczniej ogranicza nadmiarowość, choć wprowadza pewien narzut, wobec czego nadaje się szczególnie dla bardziej rozbudowanych schematów. 24
25 XPath – nawigacja w strukturze dokumentu25
26 XPath - charakterystykaJęzyk deklaratywny służący wskazywaniu elementów, atrybutów, lub całych fragmentów dokumentu XML. Posiada zwięzłą nie-XML-ową składnię, przyjętą w celu umożliwienia umieszczania wyrażeń XPath w wartościach atrybutów oraz w URI. Typy zwracanych wartości: boolean; number (liczba zmiennoprzecinkowa); string; node-set (zbiór węzłów). Ścieżka (ciąg określający) XPath jest zbudowana z tzw. kroków (step), oddzielonych symbolem „/”. Krok może reprezentować: element, atrybut lub funkcję. Poszczególne kroki zawężają obszar przeszukiwania. 26
27 Kontekst wyrażenia XPathWyrażenia danego kroku działają w kontekście określanym przez kroki poprzednie. Na kontekst składają się: Bieżący węzeł (tzw. context node); Dwie dodatnie liczby naturalne (pozycja kontekstu - context position oraz rozmiar kontekstu - context size); Wiązania zmiennych; Biblioteka dostępnych funkcji; Zadeklarowane przestrzenie nazwowe widoczne w zakresie wyrażenia. Można podawać alternatywne ścieżki w postaci tzw. wzorca (pattern). Poszczególne ścieżki są wówczas porozdzielane symbolami „|”. 27
28 Relacje pomiędzy węzłamiXPath operuje na drzewie węzłów XML, czyli na strukturze hierarchicznej. Węzłem jest element XML wraz z jego zawartością. Można wyróżnić następujące zależności pomiędzy węzłami: rodzic (parent) – dziecko (child) => pomiędzy elementem nadrzędnym a jego podelementem; rodzeństwo (sibling): poprzednik-następnik => określa kolejność występowania elementów tego samego poziomu; przodek (ancestor) – potomek (descendant): rozszerzenie relacji rodzic-dziecko na zależności pośrednie; 28
29 Kierunki nawigacji Dostępne są następujące słowa kluczowe - operatory stosowane do selekcji elementów (zwane osiami (?) (axes)): self – aktualny węzeł (zwany kontekstem: context node); parent – rodzic aktualnego węzła; (Tylko dwa powyższe zwracają wyniki nie będące nigdy kolekcjami.) child – bezpośrednie podelementy; descendant – całe drzewo podelementów poniżej aktualnego; descendant-or-self – j.w. plus aktualny węzeł; ancestor – przodkowie aktualnego węzła; ancestor-or-self – j.w. plus aktualny węzeł; following-sibling – kolejne węzły na tym samym poziomie hierarchii; preceding-sibling – wcześniejsze węzły na tym samym poziomie; following – wszystkie węzły zdefniowane za węzłem aktualnym w dokumencie (bez potomków i węzłów atrybutów oraz przestrzeni nazwowych); preceding – wszystkie węzły zdefiniowane przed węzłem aktualnym (bez przodków i węzłów atrybutów oraz przestrzeni nazwowych); 29
30 Budowa kroku XPath Składnia pojedynczego kroku jest następująca:kierunek (axis); podwójny dwukropek: “::” symbol „*” albo nazwa elementu, albo funkcja: node() text() comment() processing-instruction() <- może zawierać nazwę szukanej instrukcji przetwarzania; dowolna liczba predykatów umieszczonych w nawiasach kwadratowych: „[ ]” Przykłady kroków: child::* child::section[position()=2] ancestor::processing-instruction() 30
31 Skróty dla typowych kroków XPathPełna postać Skrót parent::node() .. /descendant-or-self::node() // self::node() . attribute:: @ [position()=2] [2] (Symbol „/” oznacza korzeń dokumentu.) Ponadto child jest kierunkiem domyślnym i wobec tego może być pominięty. Zatem zapisowi: /descendant-or-self::node()/child::para odpowiadać może //child::para a w konsekwencji //para. 31
32 Wykorzystanie skrótówUwaga: Globalne wyszukiwania mogą być w swej skróconej postaci nieco mylące. Np. ścieżka /descendant::para[1] zwróci „pierwszy z brzegu” element para, zaś //para[1] zwróci wszystkie elementy para występujące jako pierwsze podelementy swoich rodziców. Ważną rolę odgrywa również skrót “.”, będący odpowiednikiem self::node(). Wraz ze skrótem „//” pozwala na zwięzłe sformułowanie wyrażenia przeszukującego gałęzie począwszy od bieżącego elementu: self::node()/descendant-or-self::node()/child::para odpowiada .//para Podobnie, krok „..” jest skrótem od parent::node(). Np.. ../tytul zastępuje parent::node()/child::title (selekcjonuje potomne elementy tytul). 32
33 Predykaty wyszukiwaniaPredykaty zmieniają pozycję kontekstu i rozmiar kontekstu. Występują opcjonalnie, umieszczane wewnątrz nawiasów kwadratowych celem zawężenia zwróconego zbioru elementów. Muszą zwracać wartość logiczną. Dostępne operatory logiczne: = != > >= < <= and or not Dostępne operatory arytmetyczne: + - * div mod Np. //produkt[cena*1.22 < 1000] Jak już wspomniano można wyszukiwać węzły wg ich pozycji, podając predykat np. [position()=2], skracalny do postaci [2] (możliwe także inne porównania, np. „>=”). 33
34 Operacje stosowalne w predykatach XPath (1)Operacje na łańcuchach tekstowych: concat(łańcuch1, łańcuch2, …) contains(łańcuch, wzorzec) normalize-space(łańcuch) starts-with(łańcuch, wzorzec) string-length(łańcuch) substring(łańcuch, od, do), substring-after(łańcuch, wzorzec), substring-before(łańcuch, wzorzec), translate(łańcuch, stare, nowe), string(…) => konwersja na string; 34
35 Operacje stosowalne w predykatach XPath (2)Operacje na liczbach: ceiling(liczba), floor(liczba), round(liczba), sum(zbiór_węzłów), number(…) -> konwersja; Operacje na wartościach logicznych: false(), true(), not(); boolean(…) -> konwersja; Operacje na węzłach: count(zbiór_węzłów) last() position() id(identyfikator) -> wyszukanie węzła według indentyfikatora; local-name(element), name(element), namespace-uri(element). 35
36 Ograniczenia języka XPathNie można wyszukiwać łańcuchów rozciągających się poprzez kilka elementów; Niemożność wskazania na znaczniki początkowy i końcowy; Niemożność wyszukiwanie encji i sekcji CDATA; Niemożność wskazywania punktów lub zakresów w tekście. Specyfikacja XPointer, przyjmująca nieco inny model dokumentu, uzupełnia te braki. 36