14-08.pdf

(268 KB) Pobierz
XML Schema
14
XML Schema jest przedmiotem gorących dyskusji programistów korzystających z języka XML.
Ostatnie rozdziały dotyczyły głównie sposobów manipulowania danymi XML za pomocą Javy;
teraz zostanie przedstawiona XML Schema. Schematy XML to temat względnie nowy, a obsługa
tej technologii ze strony klas i interfejsów Javy powstawała powoli.
Mimo trudności związanych z korzystaniem z XML Schema bezpośrednio z poziomu Javy,
specyfikacja ta jest na tyle ważna, że zostanie jej poświęcony cały rozdział. Najpierw zastanowimy
się, czy jest to technologia stabilna i czy stanowi dobry wybór w porównaniu z definicjami DTD.
Potem przyjrzymy się, jak XML Schema odwzorowuje się na język Java oraz jak relacja ta może
wpłynąć na sposób składowania zawartości XML.
Definicje DTD
stosować czy nie?
Niemal każdy programista lub twórca zawartości XML słyszał o schematach XML; wciąż jednak
niewiele osób jest do końca przekonanych, że „nadszedł już czas” tej technologii. Wątpliwości
wynikają po części ze zmian i z małej „dojrzałości” specyfikacji XML; w większym stopniu są
jednak związane z faktem, że definicje DTD są już dobrze znane. Wielu programistów XML wciąż
zawęża dokumenty wyłącznie za pomocą DTD, nie bacząc na wzrastającą popularność XML Schema.
Przed podjęciem decyzji o zaadaptowaniu nowej technologii trzeba rozważyć wszelkie za i przeciw.
Stabilność specyfikacji XML Schema
Jednym z największych problemów schematów XML są ciągłe zmiany wprowadzane w ich spe-
cyfikacji (patrz
http://www.w3.org/TR/xmlschema-1/
oraz
http://www.w3.org/TR/xmlschema-2/).
W ciągu sześciu miesięcy (od sierpnia 1999 do marca 2000 r.) opublikowano trzy wersje spe-
cyfikacji; fakt ten sam w sobie nie jest niczym dziwnym, ale tutaj liczy się jeszcze coś innego
— poczynione zmiany były bardzo istotne. Po wprowadzeniu kolejnej wersji schematy zgodne
z poprzednimi stawały się praktycznie bezużyteczne — to nie mogło się podobać. Co więcej,
w miarę upływu czasu specyfikacja XML Schema wydawała się coraz bardziej złożona, co jeszcze
bardziej pogarszało nastroje programistów.
C:\Users\a_czajka\Dropbox\Informatyka\książki
informatyczne\Java i XML\14-08.DOC
strona
351
352
Rozdział 14. XML Schema
Ale mimo całej tej „nieprzychylnej prasy”, specyfikacja XML Schema wydaje się obecnie przy-
najmniej tak ważna, jak sam XML. Konsorcjum W3C zawsze zresztą ostrzegało, że dopóki nie
zostanie opublikowana finalna wersja specyfikacji, zmiany będą nieuniknione. Co ciekawe, osoby
narzekające na częste zmiany to często ci sami, którzy domagają się wprowadzenia pewnych
zmian! Innymi słowy, częste zmiany w specyfikacji nie usprawiedliwiają jeszcze zaniechania
korzystania z XML Schema. Niemal wszystkie zmiany, również te mniej istotne, przyczyniają się
do zwiększenia przejrzystości i użyteczności specyfikacji.
Lepsze sposoby zawężenia dokumentu
Chyba nie byłoby możliwe opisywanie schematów bez podkreślenia (już nie po raz pierwszy w tej
książce) prostoty zawężania za pomocą XML Schema. Trudno znaleźć kogokolwiek (nawet wśród
tych zatwardziałych zwolenników DTD), kto odmówiłby tej specyfikacji elastyczności i prostoty,
z jaką określa się zawężenia danych. Co więcej, ta właśnie cecha usuwa w cień ważniejsze pod
względem merytorycznym aspekty schematów! Prawda jest taka, że twórca dowolnej aplikacji,
w której konieczne jest określenie ścisłych typów danych i zakresów,
musi
korzystać z XML Sche-
ma. To pozwoli oszczędzić całe dni, jeśli nie tygodnie, wytężonej pracy.
Oprócz tradycyjnych zawężeń, XML Schema umożliwia budowanie zawężeń modelu zawartości
dla ogólnych formatów danych. Zawężenia takie mogą być potem współużytkowane i wykorzysty-
wane przez inne schematy poprzez XLink lub XPointer. Definicje DTD, same w sobie nie będące
dokumentami XML, mają w tym zakresie bardzo ograniczone możliwości. W przypadku dużych
aplikacji definicje DTD rozrośnięte do tysięcy wierszy to nic nadzwyczajnego. Takie podejście do da-
nych trudno nazwać obiektowym, nie mówiąc już o trudnościach w sprawdzaniu poprawności danych.
Definicje DTD
problemy z przestrzeniami nazw
Czytelnik wie już, że przetwarzanie dokumentu XML wykorzystującego przestrzenie nazw i wy-
magającego sprawdzenia poprawności może sprawić poważne kłopoty, jeśli wybrane zostały de-
finicje DTD. Przypomnijmy sobie ten kod:
DOMParser parser = new DOMParser();
// Włączamy obsługę przestrzeni nazw.
parser.setFeature("http://xml.org/sax/features/namespaces", true);
// Włączamy sprawdzanie poprawności.
parser.setFeature("http://xml.org/sax/features/validation", true);
// Przetwarzamy.
parser.parse();
// Pobieramy wyniki.
Document doc = parser.getDocument();
Po kompilacji tego kodu (wewnątrz jakiejś aplikacji) wykonanie spowoduje następujący błąd kry-
tyczny (przykład z Apache Xerces; inne parsery powinny zwrócić podobne komunikaty):
org.xml.sax.SAXParseException: Document root element "JavaXML:Ksiazka", must
match DOCTYPE root "JavaXML:Ksiazka".
at org.apache.xerces.framework.XMLParser.reportError
(XMLParser.java:1318)
at org.apache.xerces.validators.dtd.DTDValidator
.reportRecoverableXMLError(DTDValidator.java:1602)
C:\Users\a_czajka\Dropbox\Informatyka\książki
informatyczne\Java i XML\14-08.DOC
strona
352
Podobieństwo do Javy
at org.apache.xerces.validators.dtd
.DTDValidator.footElementSpecified(DTDValidator.java:576)
at org.apache.xerces.framework.XMLParser
.scanAttributeName(XMLParser.java:2076)
at org.apache.xerces.framework.XMLDocumentScanner
.scanElement(XMLDocumentScanner.java, Compiled Code)
at org.apache.xerces.framework
.XMLDocumentScanner$ContentDispatcher.dispatch
(XMLDocumentScanner.java, Compiled Code)
at org.apache.xerces.framework.XMLDocumentScanner
.parseSome(XMLDocumentScanner.java, Compiled Code)
at org.apache.xerces.framework
.XMLParser.parse(XMLParser.java:1208)
at org.apache.xerces.framework
.XMLParser.parse(XMLParser.java:1247)
353
Błąd wynika z faktu, że definicje DTD ignorują przestrzenie nazw; nie ignoruje ich natomiast me-
chanizm obsługujący element główny i konstrukcje znajdujące się wewnątrz niego. Ta rozbieżność
powoduje konflikty pomiędzy sprawdzaniem poprawności i przetwarzaniem przestrzeni nazw. Do-
kumenty XML często wymagają wykonania i jednego, i drugiego — co jeszcze bardziej zwiększa
atrakcyjność schematów. Co więcej, XML Schema łatwo „przekłada się” na język Java i możliwo-
ści przyszłej integracji są bardzo interesujące.
Podobieństwo do Javy
W miarę stabilizacji specyfikacji XML Schema zwiększyło się podobieństwo schematów do defi-
nicji klas i interfejsów Javy. XML Schema — choć to przecież tylko ścisły zestaw zawężeń — bar-
dzo przypomina kod, jaki piszemy w Javie, definiując klasę lub interfejs. Schemat określa zestaw
danych, jakie dozwolone są w danym dokumencie XML; klasa lub interfejs określają metody
i zmienne reprezentowane przez dany egzemplarz klasy. Podobnie jak program w Javie musi tylko
„znać” definicję, aby korzystać z egzemplarza (bez znajomości detali implementacyjnych, takich
jak adres w pamięci czy zawartość), aplikacja w XML-u musi tylko „znać” zawężenia dokumentu
(zdefiniowane w XML Schema), aby móc z takiego dokumentu korzystać.
Być może to podobieństwo nie wydaje się Czytelnikowi zbyt istotne; jednak to właśnie ta cecha
może w ogromnym stopniu przyczynić się do powszechnego stosowania XML-a w nowych apli-
kacjach oraz w nowych implementacjach starych technologii. Tutaj zostaną opisane tylko niektóre
z tych ważnych zastosowań; Czytelnik sam będzie potrafił „dopowiedzieć” sobie pozostałe i prze-
łożyć tę wiedzę na własne aplikacje.
Równoważność
Istotną cechą XML Schema jest
równoważność elementów.
W XML 1.0 oraz w definicjach DTD
jeden typ elementu musiał być odwzorowany na jeden element. Innymi słowy, jeśli dwa elementy
współużytkowały identyczną zawartość, oba musiały zostać jawnie zdefiniowane:
<!ELEMENT element1 (element2, element3*)>
<!ATTLIST element1
atrybut1 CDATA #REQUIRED
atrybut2 (cos|tam) "cos"
>
<!ELEMENT takiJakElement1 (element2, element3*)>
C:\Users\a_czajka\Dropbox\Informatyka\książki
informatyczne\Java i XML\14-08.DOC
strona
353
354
<!ATTLIST takiJakElement1
atrybut1 CDATA #REQUIRED
atrybut2 (cos|tam) "cos"
>
Rozdział 14. XML Schema
Widać, że jest tutaj dużo nadmiarowości; ponadto taki zapis podatny jest na błędy — jeśli defini-
cja jednego elementu zostanie zmieniona, a drugiego nie. XML Schema, wprowadzając typy, roz-
wiązuje ten problem:
<complexType name="takiJakTyp">
<attribute name="atrybut1" type="string" minOccurs="1" />
<attribute name="atrybut2" default="cos">
<simpleType base="string">
<enumeration value="cos" />
<enumeration value="tam" />
</simpleType>
</attribute>
</complexType>
<element name="element1" type="takiJakTyp" />
<element name="takiJakElement1" type="takiJakTyp" />
Dzięki temu mechanizmowi wystarczy zdefiniować typ elementu i potem stosować go dla różnych
elementów. Jest to podobne do języka Java, w którym definiuje się klasę, a następnie tworzy różne
jej egzemplarze. Ale XML Schema ma jeszcze inne ciekawe cechy. Oto fragment dokumentu XML
reprezentującego fakturę transportową:
<faktura>
<produkt>
<nazwa>Waza ceramiczna</nazwa>
<ilosc>400</ilosc>
<jakosc>doskonała</jakosc>
</produkt>
<produkt>
<nazwa>Naczynie z kryształu</nazwa>
<ilosc>150</ilosc>
<jakosc>dobra</jakosc>
</produkt>
</faktura>
Zarówno dostawca, jak i producent może chcieć dopisać dodatkowe informacje dotyczące produk-
tów w fakturze, np. może chcieć poinformować o pochodzeniu kryształowych naczyń albo o tym,
że dwie wazy się stłukły:
<faktura>
<produkt>
<nazwa>Waza ceramiczna</nazwa>
<ilosc>400</ilosc>
<jakosc>doskonała</jakosc>
<komentarz>2 wazy stłuczone w czasie transportu</komentarz>
</produkt>
<produkt>
<nazwa>Naczynie z kryształu</nazwa>
<ilosc>150</ilosc>
<jakosc>dobra</jakosc>
<komentarz>Naczynia zakupione w Wenecji, Włochy</komentarz>
</produkt>
</faktura>
C:\Users\a_czajka\Dropbox\Informatyka\książki
informatyczne\Java i XML\14-08.DOC
strona
354
Podobieństwo do Javy
355
Problem polega na tym, że źródło komentarzy nie jest jednoznaczne — mógł je dołączyć dostaw-
ca, producent lub pośrednik. Sprawę rozwiązuje zmiana nazw elementów:
<faktura>
<produkt>
<nazwa>Waza ceramiczna</nazwa>
<ilosc>400</ilosc>
<jakosc>doskonała</jakosc>
<komentarzDostawcy>2 wazy stłuczone w czasie
transportu</komentarzDostawcy>
</produkt>
<produkt>
<nazwa>Naczynie z kryształu</nazwa>
<ilosc>150</ilosc>
<jakosc>dobra</jakosc>
<komentarzPosrednika>Naczynia zakupione w Wenecji,
Włochy</komentarzPosrednika>
</produkt>
</faktura>
To zwiększa przejrzystość dokumentu, ale powoduje pewne zagmatwanie schematu:
<element name="komentarzPosrednika" type="string" />
<element name="komentarzDostawcy" type="string" />
<element name="komentarzProducenta" type="string" />
<element name="faktura">
<complexType>
<element name="produkt" maxOccurs="*">
<complexType>
<element name="nazwa" type="string" />
<element name="ilosc" type="string" />
<element name="jakosc" type="string" />
<element ref="komentarzPosrednika" minOccurs="0" />
<element ref="komentarzDostawcy" minOccurs="0" />
<element ref="komentarzProducenta" minOccurs="0" />
</complexType>
</element>
</complexType>
</element>
Zdefiniowano tutaj trzy różne elementy opisujące komentarze. Każdy z nich może wystąpić zero
lub więcej razy w elemencie
produkt.
Nie ma w tym nic błędnego, ale nieco niemądre wydaje
się pozwalanie na wystąpienie każdego z tych trzech elementów, bo przecież każdy z nich zawiera
taki sam typ danych; komentarz obsługiwany jest zawsze jako dane tekstowe. W Javie problem
można byłoby rozwiązać definiując klasę
Komentarz,
a następnie rozszerzając ją na
Komen-
tarzPosrednika, KomentarzDostawcy
i
KomentarzProducenta.
To pozwoliłoby na
wystąpienie w elemencie
produkt
jednego lub więcej typów
Komentarz
(w XML-u
komen-
tarz).
Na szczęście twórcy XML Schema myśleli podobnie i dzięki temu w schematach mamy
słowo kluczowe
equivClass.
Definiuje się pewien element, a potem inne elementy jako rów-
noważne z tym pierwszym. Te równoważne elementy mogą potem zostać podstawione w miejsce
elementu bazowego, określanego mianem
wzoru
(ang.
exemplar).
Takie rozwiązanie bardzo uprasz-
cza schemat:
<element
<element
<element
<element
name="komentarz" type="string" />
name="komentarzPosrednika" type="string"
equivClass="comment"
/>
name="komentarzDostawcy" type="string"
equivClass="comment"
/>
name="komentarzProducenta" type="string"
equivClass="comment"
/>
C:\Users\a_czajka\Dropbox\Informatyka\książki
informatyczne\Java i XML\14-08.DOC
strona
355
Zgłoś jeśli naruszono regulamin