360 likes | 526 Views
Technologie Internetu wykład 9: XML Schema Piotr Habela Polsko-Japońska Wyższa Szkoła Technik Komputerowych. W poprzednim odcinku…. Zastosowanie definicji typów dokumentów; Rozwiązania DTD ( Document Type Definition ): Definicja zewnętrzna lub wewnętrzna;
E N D
Technologie Internetu wykład 9:XML Schema Piotr Habela Polsko-Japońska Wyższa Szkoła Technik Komputerowych 1
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
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
XML Schema – podstawowe informacje • Instance 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: <xsd:schema> … </xsd:schema> • Deklaracja elementu oraz atrybutu (lokalnie wewnątrz odpowiednich elementów lub globalnie, celem wielokrotnego użycia): <xsd:element name=“nazwaElementu“ type=”typElementu” /> <xsd:attribute name=“nazwaAtrybutu“ type=”typAtrybutu” /> 4
Składniki definicji schematu • Obok 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): <xsd:simpleType name="IdentProduktu"> . . . </xsd:simpleType> • … oraz typu złożonego. W tym wypadku wewnątrz mogą znaleźć się deklaracje podelementów oraz atrybutów. <xsd:complexType name="DaneAdresowe"> . . . </xsd:complexType> 5
Kompozycyjność definicji schematów • Deklaracje 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
Definicje typów a elementy złożone • Definicja 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: <xsd:element ref="adres" minOccurs="0"/> 7
Deklarowanie zawartości elementowej • Zaró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
Deklarowanie atrybutów • Atrybuty (poza globalnymi) deklarujemy wewnątrz elementu xsd:complexType. • Mogą posiadać wyłącznie typy proste. • Występowanie atrybutu określone jest atrybutem (tj. atrybutemw 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
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.000-05:00 • dateTime - np. 1999-05-31T13:20:00.000-05:00 • duration - np. P1Y2M3DT10H30M12.3S • date (oraz ich wycinki) - np. 1999-05-31 • anyURI - np. http::/www.w3c.org/ • language - np. en-US, pl • ID, IDREF, IDREFS, NOTATION… 10
Definiowanie typów pochodnych przez ograniczenia • Tworzeniu 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. <xsd:simpleType name="numerWewnetrzny"> <xsd:restriction base="xsd:integer"> <xsd:minInclusive value="10000"/> <xsd:maxInclusive value="99999"/> </xsd:restriction> </xsd:simpleType> 11
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. <xsd:simpleType name="kodProduktu"> <xsd:restriction base="xsd:string"> <xsd:pattern value="\d{3}-[A-Z]{2}"/> </xsd:restriction> </xsd:simpleType> • Wyrażenia regularne posiadają bardzo bogate możliwości. M. in. można odwoływać się do różnych kategorii znaków Unicode. 12
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: <xsd:restriction base="xsd:string"> <xsd:enumeration value=„PLN"/> <xsd:enumeration value=„USD"/> </xsd:restriction> • Dla typów liczbowych można określać łączną liczbę cyfr oraz liczbę cyfr po przecinku: xsd:totalDigits, xsd:fractionDigits • Można określać długość albo jej limity: maksymalny i minimalny: length, albo maxLength i minLength Dla typu string oznaczać to będzie liczbę znaków (np. kody walut), dla typów binarnych – liczbę oktetów, zaś dla list – ich rozmiar. 13
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
Typy pochodne – pozostałe możliwości • Rozszerzenia: przypominają specjalizację klas w językach programowania. • Składnia analogiczna jak w wypadku ograniczeń. Zamiast xsd:constraint stosuje się xsd:extension: <xsd:extension base=”typBazowy”> . . . </xsd:extension> • Wprowadzone w ramach rozszerzenia podelementy muszą być w wystąpieniach dołączane na końcu. • Blokowanie wyprowadzeń (deklaracje atrybutem final): Można zabronić wyprowadzania typów, umieszczając w ich definicji atrybut final z wartością ”#restriction”, ”#extension” lub ”#all”. 15
Organizacja podelementów • Podelementy 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: <xsd:sequence> . . . </xsd:sequence> • Wybór: musi wystąpić dokładnie jeden z wymienionych podelmentów: <xsd:choice> . . . </xsd:choice> • Zbiór: wszystkie zawarte elementy muszą wystąpić, jednakże ich kolejność jest dowolna <xsd:all> . . . </xsd:all> • Kompozycje choice i sequence mogą być wzajemnie zagnieżdżane. Można też określać dla nich liczności (minOccurs i maxOccurs). • Ograniczenia kompozycji all: • Tutaj dozwoloną licznością jest tylko 1 (domyślnie) albo 0..1. • Nie można zagnieżdżać w nim innych kompozycji. • Nie może też być zagnieżdżany w innej kompozycji. • Stosowanie w rozszerzeniach – tylko gdy element bazowy jest pusty. 16
Zawartość prosta z atrybutami • Musimy użyć complexType (a nie simpleType), gdyż ten pierwszy nie pozwala na zdefiniowanie atrybutów. Wewnątrz complexType umieszczamy: <xsd:simpleContent> . . . </xsd:simpleContent> • Zawartość prosta takiego elementu musi zostać wprowadzona poprzez rozszerzenie (xsd:extension), atrybutem base: base=”nazwaTypuProstego”. Wówczas z typu bazowego pochodzi określenie zawartości elementu (np. xsd:string), zaś rozszerzenie wprowadza potrzebne nam atrybuty. 17
Grupy elementów i atrybutów • Ograniczają 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: <xsd:group> … </xsd:group> oraz <xsd:attributeGroup> ... </xsd:attributeGroup>, posiadające atrybut name. • Odwołaniom do takich grup służą te same elementy występujące w postaci elementów pustych z atrybutem ref. 18
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: <xsd:key name=”nazwaNaszegoKlucza”> <xsd:selector xpath=”elementwRamachKtoregoZapewniamyUnikalnosc” /> <xsd:field xpath=”poleKlucza”/> <!-- atrybut lub podelement --> … <!-- klucz może być złożony --> </xsd:key> 19
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: <xsd:keyref refer=”nazwaKlucza”> . . . </xsd:keyref> • Atrybut refer określa, do jakiego klucza odwołują się referencje. • Selektor i pole (lub pola) są deklarowane analogicznie jak w wypadku kluczy i wartości unikalnych. 20
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: <xsd:list itemType=”nazwaTypuZawartosci” /> • Listy mogą składać się jedynie z wartości (jednego) typu prostego. 21
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 <xsd:union> . . . </xsd:union> umieszczane są dwie lub więcej definicje typu; • Jeśli zaś potrzebne typy zostały już zadeklarowane globalnie, można się odwołać do ich nazw w atrybucie memberTypes: <xsd:union memberTypes=”nazwaTypu1 nazwaTypu2”/> • W efekcie uzyskujemy nowy typ prosty mogący przybierać wartość zgodną z dowolnym z wymienionych typów. • Przykład zastosowania w XML Schema: atrybut maxOccurs 22
Synonimy oraz byty abstrakcyjne • Aby 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). <xsd:element name=”znizka” type=”xsd:decimal” /> <xsd:element name=”upust” substitutionGroup=”znizka” type=”xsd:decimal” /> • Elementy służące tylko jako podstawa dla grupy substytucji oraz typy służące wyłącznie jako podstawa dla definicji innych (poprzez rozszerzenie lub ograniczenie), możemy zadeklarować jako abstrakcyjne. Stosujemy w tym celu dla nich atrybut abstract: abstract=”true”. 23
Sposoby budowy schematów - podsumowanie • Poprzez 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
XPath - charakterystyka • Ję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
Kontekst wyrażenia XPath • Wyraż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 positionoraz 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
Relacje pomiędzy węzłami • XPath 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
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
Budowa kroku XPath Składnia pojedynczego kroku jest następująca: • kierunek (axis); • podwójny dwukropek: “::” • symbol „*” albonazwa elementu, albofunkcja: • 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
Skróty dla typowych kroków XPath Peł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::paraodpowiadać może //child::para a w konsekwencji //para. 31
Wykorzystanie skrótów • Uwaga: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 odparent::node(). Np..../tytulzastępujeparent::node()/child::title(selekcjonuje potomne elementy tytul). 32
Predykaty wyszukiwania • Predykaty 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
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
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
Ograniczenia języka XPath • Nie 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