Wstęp

advertisement
POLSKO-JAPOŃSKA WYŻSZA SZKOŁA TECHNIK
KOMPUTEROWYCH
PRACA MAGISTERSKA
Nr ................
Język zapytań dla XML oparty na podejściu stosowym
Studenci
Rafał Hryniów
Tomasz Pieciukiewicz
Nr albumu
829
871
prof. dr hab. Kazimierz Subieta
Bazy Danych i Inżynieria Oprogramowania
Inżynierii Oprogramowania
20.05.2001
15.06.2002
Promotor
Specjalność
Katedra
Data zatwierdzenia tematu
Data zakończenia pracy
Podpis promotora pracy
Podpis kierownika katedry
....................................
.........................................
Język zapytań dla XML oparty na podejściu stosowym
Streszczenie
Niniejsza praca przedstawia zaimplementowany przez autorów język zapytań do XML oparty na
podejściu stosowym. Obszary, których dotyczy praca to: języki zapytań, XML i narzędzia
wspomagające tworzenie repozytoriów dokumentów.
We wstępie autorzy przedstawiają cel powstania niniejszej pracy oraz motywacje stojące za jego
wyborem. Opisują też podział pracy pomiędzy autorów.
W rozdziale dotyczącym stanu sztuki autorzy przedstawiają standardy i technologie dotyczące
poszczególnych obszarów, których dotyczy praca, jak również wskazują niedostatki istniejących
rozwiązań i kroki, jakie należy podjąć w celu ich wyeliminowania.
W rozdziale dotyczącym narzędzi i teorii znajdują się informacje dotyczące narzędzi użytych
podczas tworzenia implementacji języka zapytań, jak również zwięzły opis teorii, na której opiera się
główny element niniejszej pracy.
Rozdział omawiający rezultaty pracy opisuje składnię i semantykę stworzonego języka oraz API
udostępniane użytkownikowi.
Kolejny rozdział zawiera szczegółowy opis implementacji i zastosowanych rozwiązań
technicznych, użyte struktury danych, jak również zastosowane algorytmy.
W ostatnim rozdziale można znaleźć informacje na temat trudności napotkanych podczas
realizacji pracy. Autorzy wskazują również potencjalne obszary zastosowań stworzonego języka
zapytań, jak również możliwości jego dalszego rozwoju.
Strona 2
Język zapytań dla XML oparty na podejściu stosowym
Spis Treści
I.
WSTĘP ......................................................................................................................................................... 5
II.
STAN SZTUKI ............................................................................................................................................ 7
1.
REPOZYTORIA............................................................................................................................................ 7
1.1.
Zastosowanie repozytoriów ............................................................................................................. 7
1.2.
Informacje o dokumentach przechowywanych w repozytoriach ..................................................... 7
1.3.
Podstawowe założenia repozytoriów ............................................................................................... 8
1.4.
Uchwyty ........................................................................................................................................... 9
1.5.
Struktura Repozytorium................................................................................................................... 9
1.6.
Repository Access Protocol ........................................................................................................... 10
1.7.
Inne podejścia ............................................................................................................................... 10
1.8.
Dostrzeżone braki.......................................................................................................................... 10
1.9.
Proponowane rozwiązanie ............................................................................................................ 11
2.
XML (EXTENSIBLE MARKUP LANGUAGE) .............................................................................................. 11
2.1.
Geneza XML .................................................................................................................................. 12
2.2.
Własności XML ............................................................................................................................. 12
2.3.
Znaczenie XML.............................................................................................................................. 13
2.4.
XML – Zastosowanie ..................................................................................................................... 14
2.5.
Technologie i standardy powiązane z XML................................................................................... 16
3.
JĘZYKI ZAPYTAŃ ..................................................................................................................................... 22
3.1.
Języki zapytań w systemach relacyjnych ....................................................................................... 22
3.2.
Języki zapytań w systemach obiektowych ...................................................................................... 23
3.3.
Języki zapytań dla XML................................................................................................................. 24
3.4.
Próba oceny przydatności istniejących rozwiązań ........................................................................ 31
3.5.
Proponowane rozwiązanie ............................................................................................................ 32
III.
NARZĘDZIA I TEORIE ZASTOSOWANE PODCZAS REALIZACJI PRACY ......................... 34
JĘZYK JAVA ............................................................................................................................................. 34
4.1.
Co to jest Java ............................................................................................................................... 34
4.2.
Java a inne języki programowania ................................................................................................ 35
4.3.
Java a XML ................................................................................................................................... 36
4.4.
Dlaczego właśnie Java? ................................................................................................................ 36
5.
PARSER XERCES I STANDARD DOM ...................................................................................................... 37
5.1.
Standard DOM .............................................................................................................................. 37
5.2.
Parser XERCES ............................................................................................................................ 38
6.
NARZĘDZIA WSPOMAGAJĄCE TWORZENIE PARSERÓW ............................................................................. 38
6.1.
JFLEX ........................................................................................................................................... 38
6.2.
CUP ............................................................................................................................................... 39
7.
TEORIA STOSOWYCH JĘZYKÓW ZAPYTAŃ ................................................................................................ 39
7.1.
Podejście stosowe .......................................................................................................................... 39
7.2.
Podejście stosowe a języki zapytań ............................................................................................... 42
7.3.
Podejście stosowe na tle innych teorii........................................................................................... 43
7.4.
Podejście stosowe a XML .............................................................................................................. 44
4.
IV.
OMÓWIENIE REZULTATÓW PRACY .......................................................................................... 45
OMÓWIENIE JĘZYKA ZAPYTAŃ DLA XML STANOWIĄCEGO ZASADNICZY REZULTAT PRACY ................... 45
8.1.
Składania języka ............................................................................................................................ 45
8.2.
Stos rezultatów .............................................................................................................................. 47
8.3.
Semantyka języka zapytań dla XML .............................................................................................. 47
8.4.
Linki i sposób ich użycia ............................................................................................................... 56
9.
OMÓWIENIE API UDOSTĘPNIANEGO PRZEZ SYSTEM ................................................................................ 58
9.1.
Klasa edu.t2r.magisterka.QueryExecutor ..................................................................................... 58
9.2.
Klasa edu.t2r.magisterka.ReferenceManager ............................................................................... 59
9.3.
Klasy klasa edu.t2r.magisterka.parser i edu.t2r.magisterka.Lexer ............................................... 60
9.4.
Klasa edu.t2r.magisterka.LinkManager ........................................................................................ 60
9.5.
Metody służące do operacji na węzłach XML ............................................................................... 61
8.
V.
OMÓWIENIE IMPLEMENTACJI......................................................................................................... 62
Strona 3
Język zapytań dla XML oparty na podejściu stosowym
10.
10.1.
10.2.
10.3.
10.4.
11.
11.1.
11.2.
11.3.
11.4.
11.5.
11.6.
11.7.
12.
12.1.
12.2.
12.3.
12.4.
13.
13.1.
13.2.
14.
14.1.
14.2.
14.3.
15.
15.1.
15.2.
15.3.
VI.
ROZWIĄZANIA IMPLEMENTACYJNE – STRUKTURY DANYCH ................................................................ 62
Skład obiektów .............................................................................................................................. 62
Stos środowisk i rezultatów ........................................................................................................... 62
Bindery .......................................................................................................................................... 63
Zarządzanie referencjami .............................................................................................................. 63
ROZWIĄZANIA IMPLEMENTACYJNE – IMPLEMENTACJA OPERATORÓW ALGEBRAICZNYCH .................. 65
Operatory arytmetyczne ................................................................................................................ 65
Operatory działające na łańcuchach tekstowych .......................................................................... 66
Operatory logiczne ........................................................................................................................ 67
Operatory porównań ..................................................................................................................... 69
Operatory działające na kolekcjach .............................................................................................. 71
Operatory zmiany nazwy ............................................................................................................... 72
Złączenia ....................................................................................................................................... 74
ROZWIĄZANIA IMPLEMENTACYJNE – IMPLEMENTACJA OPERATORÓW NIE-ALGEBRAICZNYCH ........... 75
Operatory selekcji ......................................................................................................................... 75
Kwantyfikatory .............................................................................................................................. 76
Złączenia ....................................................................................................................................... 77
Inne operatory ............................................................................................................................... 78
ROZWIĄZANIA IMPLEMENTACYJNE – OPERACJE ELLIPSE I $ ................................................................ 79
Implementacja operacji ................................................................................................................. 79
O czym należy pamiętać przy rozszerzaniu funkcjonalności języka o operacje aktualizacji ......... 80
ROZWIĄZANIA IMPLEMENTACYJNE – IMPLEMENTACJA LINKÓW ......................................................... 80
Zebranie informacji o węzłach z identyfikatorami ........................................................................ 80
Obsługa linków w trakcie wykonywania zapytań .......................................................................... 80
O czym należy pamiętać przy rozszerzaniu funkcjonalności języka o operacje aktualizacji ......... 80
ROZWIĄZANIA IMPLEMENTACYJNE – INTERPRETACJA ZAPYTAŃ......................................................... 81
Konstrukcja skanera ...................................................................................................................... 81
Konstrukcja parsera ...................................................................................................................... 82
Konstrukcja drzewa rozbioru gramatycznego ............................................................................... 85
ZAKOŃCZENIE .................................................................................................................................. 88
16.
16.1.
16.2.
17.
17.1.
17.2.
18.
18.1.
18.2.
19.
TRUDNOŚCI PRZY REALIZACJI PRACY.................................................................................................. 88
Wpływ DOM na sposób realizacji pracy ....................................................................................... 88
Inne napotkane trudności .............................................................................................................. 88
WADY I ZALETY PRZYJĘTEGO ROZWIĄZANIA ...................................................................................... 89
Zalety przyjętego rozwiązania ....................................................................................................... 89
Wady przyjętego rozwiązania ........................................................................................................ 89
POTENCJALNE ZASTOSOWANIA PRACY ............................................................................................... 89
Możliwości wykorzystania rezultatu pracy w konstrukcji repozytorium dokumentów .................. 89
Możliwości wykorzystania pracy w konstrukcji aplikacji .............................................................. 90
MOŻLIWOŚCI ROZWOJU PRACY ........................................................................................................... 90
Strona 4
Język zapytań dla XML oparty na podejściu stosowym
I. Wstęp
W dotychczasowym toku studiów magistranci dostrzegli brak dobrych rozwiązań dotyczących
dwóch istotnych zdaniem autorów zagadnień:
 Brak opartego na mocnych podstawach teoretycznych i łatwo rozszerzalnego języka
zapytań dla XML
 Brak języka zapytań umożliwiającego łatwe wyszukiwanie żądanych informacji w
repozytoriach dokumentów.
Znane jest wiele języków zapytań do XML jednak ich podstawy teoretyczne oraz wygoda
użytkowania pozostawiają wiele do życzenia. W przypadku repozytoriów języki zapytań języki
wydają się być jedyną dziedziną pominięta przez autorów prac związanych z tą dziedziną.
Podstawową motywacją autorów było ukazanie siły podejścia stosowego dla języków zapytań
poprzez implementację prototypowego języka zapytań dla XML. Autorzy często odczuwają potrzebę
korzystania z niewielkich repozytoriów dokumentów, nie są jednak usatysfakcjonowani obecnie
istniejącymi rozwiązaniami w zakresie wyszukiwania informacji w repozytoriach.
Celem pracy jest stworzenie generycznego narzędzia, które da podstawy dla dalszych prac nad
tworzeniem systemów repozytoriów, wyszukiwarek, systemów zarządzania wersjami, itp. W tym celu
autorzy zamierzają stworzyć język zapytań dla dokumentów XML, który zdecydowanie usprawni
proces tworzenia takich systemów.
Proponowanym rozwiązaniem jest język zapytań dla XML zbudowany w oparciu o podejście
stosowe dla języków zapytań opracowane przez Kazimierza Subietę ([3]).
W toku prac zastosowano następujące narzędzia:
 Java – jako język programowania użyty do implementacji prototypu języka zapytań dla
XML
 Xerces – parser dokumentów XML, zgodny ze standardem DOM 2.0
 JFlex – generator skanerów użyty przy konstrukcji parsera dla stworzonego języka
zapytań.
 CUP – generator parserów LALR(1) użyty przy konstrukcji parsera dla stworzonego
języka zapytań.
Rezultatem pracy jest język zapytań stworzony w oparciu o podejście stosowe, umożliwiający
wykonywanie zapytań na wielu dokumentach XML jednocześnie.
Udowodniono, że podejście stosowe dobrze nadaje się do języka zapytań dla dokumentów
XML. Ponadto stworzono generyczne narzędzie umożliwiające tworzenie systemów, w których
potrzebny jest język zapytań, a duży serwer bazodanowy jest z pewnych przyczyn nieodpowiedni.
Jako, że praca ta była tworzona w zespole dwuosobowym, konieczne był podział pracy między
obu członków zespołu. Podział pracy był następujący:
 Rafał Hryniów:
o
Implementacja zarządzania referencjami
o
Implementacja stosu środowisk i binderów
o
Implementacja operatorów nie-algebraicznych
o
Implementacja operacji shallow ($)
Strona 5
Język zapytań dla XML oparty na podejściu stosowym
o
Stan sztuki, opis narzędzi i teorii – Java, oraz XML wraz z językami zapytań dla
XML, podejście stosowe
 Tomasz Pieciukiewicz:
o
Stworzenie parsera, łącznie z konstrukcją drzewa rozbioru zapytania
o
Implementacja linków.
o
Adaptacja drzewa DOM do potrzeb pracy
o
Implementacja operatorów algebraicznych
o
Implementacja operacji ellipse
o
Stan sztuki, opis narzędzi i teorii – repozytoria dokumentów, języki zapytań (bez
języków zapytań dla XML), ewaluacja przydatności poszczególnych rozwiązań w
zakresie języków zapytań do potrzeb niniejszej pracy, JFLex, CUP, DOM
Każdy z członków zespołu odpowiedzialny był za napisanie części pracy magisterskiej
odpowiadającej jego zadaniom implementacyjnym. Pozostała część pracy została napisana wspólnie.
Strona 6
Język zapytań dla XML oparty na podejściu stosowym
II. Stan sztuki
Niniejszy rozdział stanowi próbę przedstawienia czytelnikowi istniejących rozwiązań w
zakresie repozytoriów dokumentów, XML wraz z technologiami pochodnymi oraz języków zapytań,
jak również wskazania najważniejszych według autorów braków w istniejących już rozwiązaniach.
Autorzy zdają sobie sprawę, że opis ten nie może być kompletny, gdyż wszystkie trzy wspomniane
dziedziny są bardzo rozbudowane, jak również szybko ewoluują i próba ich pełnego opisu skazana jest
na niepowodzenie.
1. Repozytoria
Repozytoria są szczególnym przypadkiem systemów gromadzenia danych. W przeciwieństwie
do najpopularniejszych – systemów zarządzania bazami danych - repozytoria służą do
przechowywania i wyszukiwania różnego rodzaju dokumentów elektronicznych (zamiast starannie
obrobionych danych o określonej strukturze). Dokumenty przechowywane w repozytoriach mogą być
różnego typu – od czystych dokumentów tekstowych, przez dokumenty w językach takich jak HTML
lub XML, kody źródłowe programów, po pliki binarne takie jak zdjęcia lub programy wykonywalne.
Repozytoria muszą dostarczać sposobów wyszukiwania tego typu danych, przechowywania informacji
o ich wzajemnych powiązaniach, różnych wersjach tego samego dokumentu itd. Informacje zawarte w
tej części pracy oparte są na standardzie opracowanym w Corporation for National Research
Initiatives (CNRI), opisanym w [8], stosowanym z większymi lub mniejszymi zmianami w większości
powstających obecnie cyfrowych bibliotek.
1.1. Zastosowanie repozytoriów
Repozytoria stosowane są w kilku obszarach:
 W bibliotekach cyfrowych takich jak na przykład CSTR (Computer Science Technical
Reports) w celu przechowywania, wyszukiwania i udostępniania dokumentów znajdujących
się w tych bibliotekach.
 W systemach zarządzania wersjami lub konfiguracją (takich jak CVS, ClearCase lub
internetowy SourceForge), w celu przechowywania wszystkich objętych kontrolą składników
oprogramowania.
 Wyszukiwarki internetowe, takie jak np. Altavista lub Google, również można uznać za
swego rodzaju repozytoria (zwłaszcza, że przechowują one kopie znajdujących się w ich
katalogach dokumentów).
1.2. Informacje o dokumentach przechowywanych w repozytoriach
Zgodnie z [8], informacje o dokumentach przechowywanych w repozytoriach powinny
zawierać następujące dane:
 Związki z innymi dokumentami. Dokument może być częścią innego dokumentu (na przykład
zdjęcie może być częścią artykułu prasowego). Dokument może też składać się z innych
dokumentów (na przykład książka z rozdziałów), lub też należeć do jakiejś sekwencji (na
przykład jeden z serii tygodniowych raportów z postępów prac). Repozytorium musi
zapewniać możliwość przechowywania informacji o związkach każdego z dokumentów z
innymi i naturze tych związków.
Strona 7
Język zapytań dla XML oparty na podejściu stosowym
 Format, w jakim przechowywany jest dany dokument. Ten sam dokument może być
przechowywany w różnych formatach, czasem różniących się przenoszoną informacją (na
przykład zdjęcie nie skompresowane i poddane kompresji stratnej), czasem zawierające tą
samą informację i umożliwiające przeprowadzenie konwersji (na przykład zdjęcie nie
skompresowane i poddane kompresji bezstratnej). Repozytorium powinno zapewniać
możliwość przechowywania informacji o formatach, w jakich dostępny jest dany dokument i
umożliwiać pobranie dokumentu w żądanym formacie (jeśli taki jest dostępny).
 Wersja dokumentu. Dokumenty mogą być zmieniane – w każdej z wersji mogą różnić się
pojedynczym bitem, lub całą zawartością. Repozytorium powinno umożliwiać
przechowywanie dokumentów z rozróżnieniem wersji, w jakiej są przechowywane, oraz
pobieranie żądanej wersji.
Ponadto w repozytoriach należałoby przechowywać następujące informacje, pozwalające na
łatwe wyszukiwanie dokumentów:
 Informacje identyfikujące autorów danego dokumentu, instytucje zaangażowane w jego
powstanie, datę i miejsce publikacji, ewentualnie dane wydawcy itd.
 Informacje mówiące o zawartości dokumentu, takie jak słowa kluczowe, nazwiska osób,
nazwy miejsc itd., których dotyczy dokument, ewentualnie kategorie tematyczne.
 Inne (zgodne z zapotrzebowaniem) dane dotyczące dokumentu.
1.3. Podstawowe założenia repozytoriów
Podczas projektowania architektura informacji w repozytoriach należy brać pod uwagę
następujące założenia ([8]):
 Należy dać użytkownikowi jak największą elastyczność. Ponieważ użytkownicy przeszukują
materiały na wiele różnych sposobów, organizacja informacji nie może być oparta na
oczekiwaniach dotyczących podejścia użytkownika do materiałów, jego poziomu
doświadczenia, lub kolejności dostępu do pozycji.
 Kolekcje muszą być proste w zarządzaniu. W bibliotekach cyfrowych (jak we wszystkich
bibliotekach), niewielki zespół specjalistów zarządza bardzo dużymi zbiorami. Architektura
musi pozwalać temu zespołowi skupić się na istotnych zadaniach, uwalniając ich od
rutynowych zajęć. (Dotyczy to też wykorzystania repozytoriów w zastosowaniach innych niż
biblioteki cyfrowe, w celu redukcji kosztów administracyjnych).
 Architektura musi odzwierciedlać ekonomiczne, społeczne i prawne ramy infrastruktury
informatycznej. W szczególności należy pamiętać, iż informacja jest wartościowa, podlega
rozmaitym uregulowaniom prawnym i jest transmitowana przez (zazwyczaj)
niezabezpieczone sieci, przekraczające granice państwowe.
Ponadto, system powinien spełniać następujące warunki dotyczące sposobu przechowywania i
opisywania dokumentów ([8]):
 Wszystkie dane (dokumenty) mają przypisany typ danych
Każdy dokument ma przypisany do niego typ danych. Typ określa, w jakim formacie jest
dany dokument (na przykład format ASCII lub JPEG), w jaki sposób powinien być
przetwarzany (na przykład, jeśli jest programem napisanym w C), lub jaką ma organizację (na
przykład tekst opisany znacznikami SGML).
 Metadane są kodowane explicite
Używane metadane są kodowane explicite. Żadna informacja semantyczna zawarta np. w
części nazwy nie może być pominięta w metadanych (w przeciwieństwie do np. systemów
plików w systemach operacyjnych, gdzie informacja semantyczna jest często zawarta w
nazwie pliku – np. „.txt” wskazuje na plik tekstowy).
Strona 8
Język zapytań dla XML oparty na podejściu stosowym
 Uchwyty są przypisane pojedynczym obiektom będącym własnością intelektualną
Jeśli informacja może być użyta samodzielnie, przyznawany jej jest własny uchwyt i
tworzony jest z niej osobny obiekt. Dzięki posiadaniu przez nią własnego uchwytu, można
uzyskać do niej bezpośredni dostęp. Pozwala to na dużą elastyczność. (Przykładowo, tekst
może zawierać ilustracje. Przy tym podejściu każda z ilustracji będzie osobnym obiektem z
własnym uchwytem).
 Metaobiekty są używane do agregowania obiektów
W bibliotece elektronicznej pełne metadane dotyczące pojedynczej pozycji informacji, jak
również jej kopie, mogą istnieć w wielu miejscach w repozytorium, jak również w
zewnętrznych systemach. Dla każdego obiektu w związku z tym należy tworzyć metaobiekt,
zawierający dane dotyczące obiektu oraz łącza do wszystkich wersji obiektu w repozytorium.
 Uchwyty są używane do identyfikacji obiektów zawartych w metaobiektach
Metaobiekt zawiera listę. Pozycje w liście identyfikowane są przy pomocy uchwytów.
Przykład użycia metaobiektu:
W repozytorium znajdują się 3 wersje tej samej fotografii: wersja o wysokiej, średniej i niskiej
rozdzielczości. Każda z wersji jest opisana przy pomocy własnego zestawu metadanych. Uchwyty do
wszystkich trzech wersji fotografii znajdują się w metaobiekcie. Metadane tego metaobiektu zawierają
informacje wspólne dla wszystkich trzech wersji fotografii. Jeśli w jakimś innym dokumencie znajdzie
się odniesienie do tego metaobiektu, użytkownik próbujący pobrać fotografię będzie miał wybór
między wszystkimi dostępnymi wersjami.
1.4. Uchwyty
Uchwyt jest unikalnym identyfikatorem obiektu, pozwalającym na jego identyfikację. Zasoby
identyfikowane przez uchwyt mogą być zmieniane, przenoszone w inne miejsca, przechowywane w
wielu miejscach repozytorium lub w inny sposób zmieniać się w czasie, lecz uchwyt do obiektu
pozostanie niezmienny. System jest w stanie powiązać uchwyt z konkretnym zasobem – obiektem.
Wszelkie powiązania między obiektami realizowane są właśnie przy pomocy uchwytów. Uchwyty
zbudowane są z dwóch części – kodu instytucji nadającej nazwy (naming authority) i kodu zasobu.
Przykładem uchwytu może być np. loc.pp/4a32371, gdzie loc.pp odnosi się do instytucji nadającej
nazwy, zaś 4a32371 do konkretnego zasobu.
1.5. Struktura Repozytorium
Repozytorium oparte na standardzie opracowanym w CRNI jest systemem wielowarstwowym.
Do komunikacji między repozytoriami, oraz między repozytorium a aplikacją kliencką
wykorzystywany jest protokół RAP (Repository Access Protocol) oparty na standardzie CORBA
(protokół ten to po prostu definicja interfejsu CORBA, realizującego 9 podstawowych operacji na
repozytorium).
Repozytorium składa się z trzech warstw:
 Interfejs repozytorium (Repository shell) udostępniający interfejs do repozytorium.
Implementuje protokół RAP, zapewnia konwersję między wewnętrzną i zewnętrzną
reprezentacją obiektów oraz zarządza prawami i uprawnieniami.
 Warstwa zarządzania obiektami (Object management Layer) zapewnia interfejs między
usługami trwałego składu i usługami interfejsu repozytorium. Zapewnia mapowanie
uchwytów na rzeczywiste obiekty.
 Trwały skład (Persistent store) służy do przechowywania informacji zawartej w
repozytorium. Implementacja trwałego składu jest ukryta przed światem zewnętrznym, dzięki
czemu możliwe jest użycie we wdrażanym systemie dowolnego z dostępnych systemów
trwałego składu.
Obiekty w składzie nie są przechowywane w postaci pojedynczego bloku danych. Każdy obiekt
mapowany jest na pewną strukturę:
Strona 9
Język zapytań dla XML oparty na podejściu stosowym
 Element jest najbardziej podstawową ze struktur składu. Każdy element składa się z
unikalnego (w ramach danego składu) identyfikatora, atrybutów opisujących dany element
(takich jak typ lub rola) oraz bloku danych (dowolnej sekwencji bajtów).
 Pakiet jest kolekcją elementów oraz innych pakietów, posiadającą własne ID.
 Obiekt jest pakietem lub elementem uzupełnionym o opisujące go metadane, przeznaczonym
do udostępnienia. ID obiektu to jego uchwyt.
Przykładowo, książka (obiekt w repozytorium) może składać się z rozdziałów (pakietów), zaś
każdy z rozdziałów zawierać elementy w postaci tekstu rozdziału i odpowiednich ilustracji.(Uwaga –
rozdziały, tekst i ilustracje, jeśli przypisane zostaną im odpowiednie metadane również bez przeszkód
mogą zostać udostępnione jako obiekty).
1.6. Repository Access Protocol
Repository Access Protocol używany jest we wszystkich interakcjach pomiędzy światem
zewnętrznym a repozytorium. Systemy opisywane w [8] implementują następujące metody składające
się na interfejs RAP:
 VerifyHandle pozwala sprawdzić, czy uchwyt został zarejestrowany w systemie uchwytów,
 AccessRepoMeta pozwala na dostęp do metadanych repozytorium,
 Verify_DO pozwala sprawdzić, czy repozytorium przechowuje obiekt z danym uchwytem,
 AccessMeta pozwala na dostęp do metadanych konkretnego obiektu,
 Access_DO pozwala na dostęp do obiektu,
 Deposit_DO pozwala na wprowadzenie obiektu do repozytorium,
 Delete_DO pozwala na usunięcie obiektu z repozytorium,
 MutateMeta pozwala na edycję metadanych obiektu,
 Mutate_DO pozwala na edycję obiektu,
Te 9 operacji pozwala na wykonywanie podstawowych działań na repozytorium.
Oprogramowanie klienckie opracowane w ramach programu początkowo wykorzystywało RAP,
później jednak zdecydowano się na odejście od idei grubego klienta na rzecz dostępu do repozytorium
przez WWW za pośrednictwem skryptów CGI, które z kolei kontaktowały się z repozytorium za
pomocą RAP.
1.7. Inne podejścia
Prezentowane podejście jest najbardziej zaawansowanym ze wszystkich znanych autorom
rozwiązań. Najczęściej spotykane systemy - używane wyłącznie w rozwoju oprogramowania, takie jak
CVS są bardzo ograniczone pod względem możliwości – małą elastyczność, jeśli chodzi o
definiowanie metadanych, sposób przechowywania zasobów (zazwyczaj jedynie przy pomocy
systemu plików) itd. Niestety, bardzo trudno jest uzyskać dane na temat struktury repozytoriów w
systemach komercyjnych, jednak określanie przez producenta możliwości dowolnego nazywania
wersji obiektu w repozytorium (nie zaś tylko przy pomocy numeru wersji) jako osiągnięcia (Visual
SourceSafe ([9]) świadczy o tym, że pod względem elastyczności tych systemów jest niewiele lepiej,
niż w przypadku systemów darmowych. Niektóre systemy komercyjne, takie jak np. Continuus
oferują możliwość wykonywania zapytań (w tym tworzenia raportów) na metadanych,
przechowywanych w relacyjnej bazie danych. Niestety, znaczny koszt komercyjnych systemów typu
Configuration Management uniemożliwia autorom osobiste zapoznanie się z zastosowanymi w nich
rozwiązaniami.
1.8. Dostrzeżone braki
Prezentowane rozwiązanie wydaje się być dość rozsądne i atrakcyjne, należy jednak zwrócić
uwagę na bardzo istotne niedomaganie. Rozbudowane metadane związane z obiektami i możliwość
Strona 10
Język zapytań dla XML oparty na podejściu stosowym
tworzenia powiązań (zarówno typu „część-całość” jak i „związany z”) między nimi są raczej
obciążeniem dla poszukujących informacji, nie zaś ułatwieniem, w sytuacji, gdy brak efektywnego
narzędzia służącego do nawigowania wśród danych – takiego jak język zapytań. Prezentowany
standard nie zakłada niczego na temat takiego języka, w znanych autorom materiałach brak
jakiejkolwiek wzmianki o konieczności jego istnienia. Niektóre systemy komercyjne używają języka
zapytań (zazwyczaj SQL), jednak są one silnie ukierunkowane na jeden obszar zastosowań.
1.9. Proponowane rozwiązanie
1.9.1
Cechy idealnego rozwiązania
Idealne repozytorium powinno być na tyle generyczne, aby możliwe było wykorzystanie go w
dowolnym zastosowaniu - nie powinno być z góry nastawione na wykorzystanie w systemie kontroli
konfiguracji, bibliotece elektronicznej czy portalu internetowym. Jego konstrukcja powinna
umożliwiać szybkie i łatwe przystosowanie go do użycia w dowolnym systemie wymagającym użycia
repozytorium. Uważamy, że do osiągnięcia tego celu należy użyć następujących środków:
 Struktura metadanych dla repozytorium powinna być jak najbardziej elastyczna, co umożliwi
dopasowanie metadanych do potrzeb,
 System powinien być wyposażony w język zapytań, umożliwiający szybkie i łatwe
operowanie na metadanych. Możliwości tego języka powinny być dopasowane do przyjętego
modelu metadanych,
 Powinien zostać skonstruowany w architekturze wielowarstwowej. System składu, system
zarządzania obiektami, interfejs repozytorium i interfejs użytkownika powinny być oddzielone
od siebie tak, aby możliwa była łatwa podmiana lub modyfikacja dowolnego z komponentów
systemu.
1.9.2
Nasza propozycja
Architektura opracowana w CNRI odpowiada dwóm z trzech wymienionych założeń – nie
posiada jedynie języka zapytań. Proponujemy rozwiązanie zbliżone do tej właśnie architektury. Nasza
propozycja realizacji poszczególnych założeń wygląda następująco:
 Dane i metadane można przechowywać w postaci plików XML o strukturze definiowanej
przez użytkownika. Pozwoli to na łatwą modyfikację struktury danych pod kątem konkretnych
zastosowań.
 Należy zaimplementować język zapytań umożliwiający wykonywanie zapytań na danych
przechowywanych w postaci plików XML. Da to podstawę do późniejszej budowy
repozytoriów używających dowolnych technologii, zaopatrzonych w silne narzędzie to
wyszukiwania potrzebnych dokumentów.
W dalszej części tego rozdziału przypatrujemy się bliżej rozwiązaniom w zakresie XML i
języków zapytań mogącym mieć zastosowanie w takiej pracy.
2.
XML (eXtensible Markup Language)
Materiały wykorzystane w tym rozdziale pochodzą w głównej mierze ze stron W3C ([15]),
książek ([25], [26]) oraz szeroko pojętych zasobów internetowych
Błyskawiczny rozwój internetu, a zwłaszcza WWW przyczynił się do ukazania niedostatków
HTML - głównego języka używanego w Internecie. Ponieważ HTML stworzony został jako język do
prezentacji danych, nie jest on dostatecznie elastyczny oraz nie udostępnia wsparcia wymaganego dla
rozwoju aplikacji internetowych. Mianowicie pojawiła się konieczność tworzenie dużych systemów
rozproszonych pobierających danych z systemów heterogenicznych, baz danych, aplikacji. Aplikacje
muszą porozumiewać się nie tylko z innymi elementami aplikacji, ale także z innymi systemami
biznesowymi – często opartymi o inne technologie. Co więcej klientem aplikacji to nie tylko
przeglądarki ale także telefony komórkowe (WAP), „organizery” obsługujące zupełnie inne znaczniki.
Strona 11
Język zapytań dla XML oparty na podejściu stosowym
W związku z tym podstawowym zadaniem współczesnej aplikacji jest organizacja i przetwarzanie
danych.
XML powstał jako narzędzie zdecydowanie mocniejsze niż HTML, mające stanowić panaceum
na problemy trapiące twórców aplikacji rozproszonych. Główną różnicą między HTML i XML jest to,
że HTML jest to typowy język znacznikowy, zawierający predefiniowane znaczniki, a XML jest
meta-językiem pozwalającym na definiowanie własnych znaczników a także własnej struktury
dokumentów.
2.1. Geneza XML
Prekursorem XML był SGML (Standard Generalized Markup Language), który powstał w
wyniku naturalnych potrzeb przechowywania danych niezależnie od oprogramowania lub jego
producentów. Na podstawie SGML powstało setki ukierunkowanych języków znacznikowych
zdefiniowanych przy pomocy SGML (aplikacjj SGML). Aplikacje te są używane w przemyśle
(J2008), wojsku (Mil-M-38784), w Sieci (HTML), a także innych zastosowaniach (DocBook, TEI).
Niestety SGML jest językiem zbyt skomplikowanym i kosztownym, aby używać go w Sieci na dużą
skalę. Skomplikowanie SGML powoduje, że do wykorzystanie go niezbędne są duże ilości szkoleń,
czasu, narzędzi.
Głównym celem XML, który powstał jako podzbiór SGML było umożliwienie przesyłania,
przetwarzania, udostępniania danych zakodowanych w SGML poprzez Sieć w możliwie jak
najprostszy sposób.
Popularność XML przyczyniła się do stworzenie wielu „kilkuliterowych” technologii,
rozszerzających możliwości XML (np. XSL, XSLT, XHTML, XSD, XPath, XPointer, XLink) – kilka
naszym zdaniem najistotniejszych zostanie opisana w dalszej części rozdziału.
W chwili obecnej XML oraz technologie z nim związane rozwijane są przez W3C.
2.2. Własności XML
Główna cecha XML wywodzącą się bezpośrednio z SGML jest możliwość definiowania
dowolnych znaczników oraz reguł gramatycznych, oraz możliwość późniejszej walidacji
dokumentów. Walidacja możliwa jest poprzez użycie w XML standardu DTD (Document Type
Definition) będącego częścią SGML, pozwalającego na walidację dokumentów zgodnie ze
zdefiniowanym schematem. Obecnie tworzony jest standard XML Schema, lepiej dopasowany do
specyfiki XML, mający zastąpić DTD.
Dodatkowo dziesięć głównych założeń (według W3C [15]) poczynionych przez twórców
spowodowało znaczne uproszczenie XML a także lepsze dopasowanie do wymogów Sieci.
Najważniejsze założenie to:
 XML może być używany w istniejących protokołach sieciowych i przy użyciu tych samych
mechanizmów.
 XML ma obsługiwać szeroki zakres zastosowań. Z tego założenia wynika prostota oraz
elastyczność XML.
 XML ma być kompatybilny z SGML.
 Łatwość tworzenia parserów XML. Prosta struktura XML pozwala w prosty sposób tworzyć
wydajne parsery XML.
 Minimalizacja opcjonalnych cech XML. Założenie to umożliwia szybsze nauczenia się XML,
a także uproszczenie narzędzi do XML.
 Dokumenty XML powinny być zrozumiałe także dla człowieka oraz bez nadmiernego lukru
syntaktycznego (można się spierać czy założenie to udało się spełnić w XML)
 Projekt XML należy stworzyć szybko.
Strona 12
Język zapytań dla XML oparty na podejściu stosowym
 Projekt XML ma być formalny i spójny. Jako podstawę specyfikacji XML użyto
rozszerzonego formatu Backus-Naura (EBNF – Extended Backus-Naura Format) dobrze
znanego wśród programistów1.
 Łatwość tworzenia dokumentów XML
 Zwięzłość znaczników nie ma praktycznie znaczenia.
Oprócz powyższych założeń zawiera wiele dodatkowych cech ułatwiających używanie go w Sieci:
 Modularność – możliwość łączenia wielu fragmentów kodu XML lub pojedynczych DTD w
spójną całość
 Internacjonalizacja – oparcie działania XML o Unicode pozwala zapomnieć o problemach ze
znakami diakrytycznymi. XML wymaga także, aby całe oprogramowanie obsługujące XML
także obsługiwało Unicode.
 Ukierunkowanie na dane – standard XML został stworzony do opisu i obsługi danych.
Zapewnia walidację struktury dokumentów, oraz ścisła kontrolę danych (XML Schema).
Niestety XML umożliwia tylko opisanie semantyki danych. Przy braku ontologii dla danych
problematyczne wydaje się automatyczne przetwarzanie danych przez komputer. W tym
momencie programiści tworzący aplikacje używające XML do wysyłania i odbierania danych
muszą znać ontologię danych w celu zrozumienia danych (wiedza ta niestety nie pochodzi z
XML).
 Możliwość tworzenia łączy między elementami XML (wewnątrz dokumentu oraz do
zewnętrznych źródeł danych) pozwala odzwierciedlić relację oraz zależności między encjami.
Służą do tego technologie XLink oraz XPointer. Technologie zostaną opisane w dalszej części
rozdziału.
XML pozwala pracować z dokumentami na dwa sposoby – formalnie i nieformalnie. Dla
małych projektów lub prototypowania, można tworzyć dokumenty poprawnie zbudowane. Dla
większych projektów lepsze jest stworzenie dokumentów walidowanych.
Poprawnie zbudowany dokument XML spełnia następujące reguły:
 Tylko jeden element główny
 Każdy niepusty element ma odpowiadające mu znaczniki początku i końca
 Wszystkie elementy są poprawnie zagnieżdżone, bez zazębiania
 Wymogi dotyczące znaków (np. znaki specjalne) oraz nazewnictwa.
Dokument walidowalny to dokument poprawnie zbudowany, który także:
 Zawiera lub odwołuje się do schematu lub DTD.
 Spełnia wymogi danego schematu lub DTD
Koncepcja XML oparta jest na dokumentach złożonych z encji. Każda encja może zawierać
jeden lub więcej logicznych elementów. Każdy z tych elementów może posiadać atrybuty
(właściwości) opisujące dany element. XML udostępnia składnię dla opisu związków między encjami,
elementami i atrybutami, które składają się na dokument XML, która z kolei jest używana przez parser
do rozpoznawania komponentów, z których składa się dokument.
2.3. Znaczenie XML
Istnieje wiele powodów zainteresowanie XML. Jednym z najważniejszych jest niezależność
danych przechowywanych w XML od środowiska, w jakim te dane mają zostać przetwarzane.
Łatwość tworzenia dokumentów oraz teoretyczna możliwość zrozumienia struktury i zawartości
dokumentu (rozsądne tylko dla niewielkich dokumentów) pozwala twierdzić, że XML może zastąpić
w niedługim czasie HTML. Przykładem takiego trendu jest technologia XHTML, w której dokumenty
1
Bardziej popularna jest jednak notacja BNF.
Strona 13
Język zapytań dla XML oparty na podejściu stosowym
HTML są opisywane zgodnie z wymogami XML. Ponadto XML wraz z DTD (lub XML Schema)
pozwala stworzyć standard wymiany informacji niezależny od rozwiązanie programowego oraz
platformy sprzętowej. Spowodowane jest to tym, iż prostota budowy dokumentów umożliwia łatwą
budowę wydajnych narzędzi. Na dzień dzisiejszy powstały parsery XML dla wszystkich popularnych
języków.
2.4. XML – Zastosowanie
Chociaż pierwotnym założeniem twórców XML było stworzenie języka mogącego zastąpić, w
coraz większym stopniu niewystarczający, HTML. XML jako otwarty język, wraz ze wsparciem CSS,
miał dostarczyć narzędzie dopasowane do wszystkich potrzeb, będące zarazem alternatywą dla
HTML. Cel ten miał być osiągnięty głównie poprzez oddzielenie zawartości (danych) od prezentacji
(wyświetlania). Z perspektywy dnia dzisiejszego widać, że ten cel nie został osiągnięty. XML jest
używany do tworzenia stron, aczkolwiek zdecydowana większość stron tworzona jest nadal w HTML.
Powodem takiego stanu rzeczy, mimo niewątpliwych zalet XML nad HTML, może być wymiernie
wyższy wymagany nakład pracy na zaprojektowanie i stworzenie strony internetowej. Oprócz tego w
przypadku prostych stron, tworzonych przez pojedynczych użytkowników, część właściwości XML
jest niepotrzebna. Kolejnym powodem może być to, że ludzie znający HTML nie mają ochoty uczyć
się XML wraz z powiązanymi technologiami (DTD, XSLT). W związku z powyższymi problemami,
XML jest używany głównie przez firmy (bądź ludzi), dla których istotne jest rozdzielenie prezentacji
do danych. Zasadniczą zaletą takiego podejścia jest to, iż zawartość jest niezależna od aplikacji i może
być dowolnie formatowana, prezentacja zaś zależna jest od rodzaju klienta (np. przeglądarką,
telefonem z obsługą Internetu itd.) oraz z funkcjami udostępnianymi przez klienta (HTML 4.0, język
WML). Zawartość jest przechowywana w XML a prezentacja dla poszczególnych klientów tworzona
jest za pomocą XSL i XSLT.
Jedną z najpotężniejszych funkcji oferowanych przez XML w zakresie prezentacji jest
możliwość tworzenia wielu arkuszy stylów odpowiadających dokumentowi XML. Możliwość ta
zdecydowanie zwiększa elastyczność prezentacji – nie tylko można korzystać z jednego dokumentu
XML dla wielu prezentacji, lecz struktura publikacji dokonująca transformacji może określić, od
jakiego klienta przyszło żądanie dokumentu i automatycznie wybrać właściwy arkusz stylów. Kolejną
zaletą jest przejrzystość i łatwość zarządzania systemem a co z tym związane niski koszt eksploatacji
systemu.
Niestety jak już wspomniano XML nie wyparł i prawdopodobnie nie wyprze HTML w związku
z wyższymi nakładami na stworzenie oraz zdecydowanie większym wymaganym nakładem prac na
opanowanie technologii. Jednakże bardzo silną alternatywą dla HTML może być XHTML język
znacznikowy, stworzony z połączenie HTML i XML (Patrz [XHTML]).
Drugim bardzo istotnym zastosowaniem XML jest wymiana danych między aplikacjami
systemami. Jest to możliwe, ponieważ dane XML są niezależne od typu klienta, a także nie są
wykorzystywane bezpośrednio przez klienta. Kolejną cechą XML przydatna do tego typu zastosowań
jest opisywanie dokumentu XML przez samego siebie (co prawda tylko semantyki, ale lepsze to niż
nic). Użycie XSL do dokumentu XML pozwala na bardzo łatwą konwersję dokumentu XML do
innego dokumentu XML o zupełnie odmiennej strukturze a następnie po przetworzeniu wynikowego
dokumentu XML (przez aplikację) znów dzięki XSL na powrót do oryginalnej struktury XML ze
zmodyfikowanymi danymi.
Kolejnym użyciem XML w komunikacji jest standard XML-RPC. Technologia ta opisuje
komunikację między elementami aplikacji. RPC to skrót od Remote Procedure Calls (zdalne
wywołania procedur). RPC to jedna z najstarszych technologii umożliwiających wywoływanie
procedur przez sieć i także poprzez sieć otrzymywanie odpowiedzi.. Technologia XML-RPC stała się
bardzo użytecznym sposobem odwoływanie się do zdalnych usług. XML umożliwiło rozwiać jeden z
poważniejszych problemów RPC, związanym z próbą kodowanie złożonych obiektów wyłącznie
tekstowo. Dzięki użyciu XML możliwe jest reprezentowanie „dowolnych” typów danych za pomocą
dokumentów XML. XML-RPC odwzorowuje parametry obiektu po stronie klienta na elementy XML
Strona 14
Język zapytań dla XML oparty na podejściu stosowym
a następnie dekoduje te elementy na odpowiedni obiekt na serwerze. Komunikacja w drugą stronę
wygląda analogicznie.
Kolejnym niezwykle istotnym zastosowaniem XML zastosowanie typu B2B (business-tobusiness). W tym przypadku XML może stanowić standard wymiany informacji między aplikacjami,
oraz zamkniętymi systemami. Pozwala on na łatwe przekazywanie danych a także zbieranie i
wprowadzanie do systemu informacji do/od partnerów handlowych (sprzedawców, kontrahentów).
XML z założenia pozwala na przetwarzanie danych przez komputer, lecz również wyświetlenie
informacji np. w przeglądarce, co może eliminować koszt tworzenia aplikacji prezentujących
informacje, co umożliwia wykorzystanie danych przez partnerów o niższych możliwościach
technicznych (trzeba jednakże wziąć pod uwagę ludzkie ograniczenia dotyczące percepcji). Ostatnim
elementem jest publikacja aktualnych informacji o firmie np. finansowych za pośrednictwem XSL
oraz XSLT.
XML jest także coraz częściej używany do tworzenia plików konfiguracyjnych. Jest to
wymogiem dla aplikacji tworzonych zgodnie ze specyfikacją EJB (Enterprise Java Beans) tzw.
deskryptory wdrożeniowe (definicja sposobu działania i inne parametry dla EJB) muszą być tworzone
w XML. Ponieważ wszyscy producenci wykorzystują te same deskryptory – zwiększa się przenośność
kodu EJB. Także duża część nowo tworzonych plików konfiguracyjnych dla aplikacji jest tworzona w
XML (np. Apache Tomcat).
XML może być też stosowany do przechowywania informacji. Jest to doskonałe rozwiązanie
dla przechowywania niewielkiej ilości hierarchicznych danych. Powyżej pewnej ilości
przechowywanych danych olbrzymim problemem może być wydajność takiego rozwiązania,
zdecydowanie ustępująca wyspecjalizowanym systemom baz danych. Jednakże nawet w przypadku
dużej ilości danych XML może być użyty do przenoszenia danych między bazami danych. Większość
komercyjnych baz danych umożliwia konwersję do i z XML, dzięki czemu standard XML może w
niedalekiej przyszłości stać się standardem wymiany informacji między konkurencyjnymi systemami
baz danych.
Użycie XML w repozytoriach danych (głównie dokumentów) jest powiązane z poprzednim
punktem. Ponieważ nie wszystkie repozytoria wymagają dużej wydajności w dostępie do danych, lub
z założenia nie przechowują ogromnej ilości danych, XML może być z powodzeniem używany jako
składnica danych dla takich repozytoriów. Doskonałym przykładem takiego typu repozytorium jest
repozytorium dokumentów. W pliku XML przechowujemy tylko atrybuty dokumentów, powiązania
oraz linki do dokumentów, które przechowywane są niezależnie na dysku. Oczywiście w przypadku
chęci indeksowania dokumentów np. po słowach kluczowych lub przechowywania dużej ilości
dokumentów, lepszym rozwiązaniem jest składowanie danych w bazie danych, aczkolwiek także i w
tym przypadku wygodne może być działanie na XML dla początkowych faz istnienia repozytorium, z
powodu łatwej zmiany struktury XML (jak wiadomo, struktura bazy danych może się znacznie
zmienić w trakcie tworzenia systemu, głównie z powodu zmian w wymaganiach użytkownika, lub
błędów w analizie) oraz łatwej migracji do kolejnych wersji pliku XML. Drugim ciekawym typem
repozytorium, dla którego XML jest wystarczającą składnicą danych jest repozytorium projektowe
(wersje, informacje o wersjach itp.). XML zazwyczaj jest wystarczająco silną platformą do tego
rodzaju repozytoriów, ponieważ, niezbyt często repozytoria te posiadają ilość dokumentów, dla której
przetwarzanie plików tekstowych jest uciążliwe, oraz zazwyczaj nie stawiają ostrych wymogów na
wydajność repozytorium.
Ostatnim zastosowaniem XML, o którym chcielibyśmy wspomnieć jest użycie XML do
tworzenia nowych języków znacznikowych. W rozdziale tym wymieniliśmy dwa takie języki
(XHTML i WML). XHTML – połączenie HTML i XML, WML – język znacznikowy stworzony do
wyświetlania informacji w telefonach komórkowych. Także nowy format graficzny, SVG (Scalable
Vector Graphics), służący do opisu dwu-wymiarowej grafiki wektorowej w XML, oraz wiele innych
(np. XUL, VML, MathML).
Strona 15
Język zapytań dla XML oparty na podejściu stosowym
2.5. Technologie i standardy powiązane z XML
Równolegle z standardem XML rozwijany jest szereg technologii oraz standardów bardzo ściśle
powiązanych z XML, dzięki którym XML zyskuje na elastyczności, możliwościach a co z tego
wynika potencjalnych zastosowaniach. Oprócz tego istnieją standardy związane z SGML, które są
używane przez XML (patrz DTD). W związku z tym, iż XML jest obecnie niezmiernie popularny na
świecie, ilość technologii z nim powiązanych jest bardzo dużo. Poczynając od definicji przestrzeni
nazw przez technologie umożliwiające walidację dokumentów, aż do technologii służących do
tworzenia relacji między elementami XML. Osobną sprawą są języki stworzone za pomocą XML (np.
XHTML i WAP).
Ponieważ nie ma najmniejszego sensu opisywać wszystkich technologii powiązanych z XML
skoncentrujemy się tylko naszym zdaniem na najważniejszych technologiach starając się opisać ich
założenia, wady oraz zalety a także określić zastosowanie dla tych technologii.
2.5.1
DTD (Document Type Definition)
Definicja typu dokumentu nie została wyróżniona w odrębnej specyfikacji, lecz stanowi część
specyfikacji XML. Używanie DTD w XML jest bezpośrednim następstwem bycia XML podzbiorem
SGML. Jednak, mimo, że XML DTD wywodzi się z SGML DTD to struktura DTD dla XML została
znacznie uproszczona, w związku z tym nie jest możliwe przeniesienie DTD stworzonego dla
dokumentu SGML do XML bez wykonania konwersji.
DTD może narzucić szereg ograniczeń na dokument XML. W DTD zdefiniowana jest
poprawna struktura dokumentu XML wraz z listą poprawnych elementów. Poprzez DTD definiujemy
gramatykę dokumentu XML. DTD może być zdefiniowany wewnątrz dokumentu XML lub też
trzymany w oddzielnym pliku.
DTD umożliwia zdefiniowanie następujących ograniczeń:
 Deklarację dopuszczalnych elementów
 Deklarację atrybutów dla elementów
 Deklarację struktury elementów wraz z określeniem wymagalności elementu.
Poprzez ograniczenie budowy dokumentu XML uzyskuje się bardzo wymierne korzyści.
Aplikacja przetwarzające dokument XML może przeszukać dane, ponieważ wie jak zagnieżdżane są
elementy w dokumencie XML. Co więcej poprzez stworzenie DTD tworzymy pewnego rodzaju
standard dla dokumentów, w związku ułatwiona jest wymiana danych (ponieważ znamy strukturę
dokumentu). Poprzez umożliwienie definiowania elementów opcjonalnych można w zależności od
potrzeb, stworzyć bardzo restrykcyjny lub bardzo elastyczny DTD.
Wady DTD:
 DTD posiada własną składnię, zupełnie inną niż składania XML.
 Konieczność nauki przez ludzi zupełnie innej składni.
 Konieczność tworzenia odrębnych narzędzi lub odrębnego kodu do parsowania DTD.
 Brak kontroli zawartości danych umieszczonych między znacznikami (co uniemożliwia
kontrolę przekazywanych danych)
 Trudności w obsłudze konfliktów przestrzeni nazw.
W związku z wyżej wymienionymi wadami powstał już XML Schema będący następcą XML
DTD. Chociaż XML DTD nie jest jeszcze martwym standardem, istnieje szansa, że stanie się to w
niedługiej przyszłości, gdy pojawi się więcej narzędzi do XML Schema.
2.5.2
XML Schema
XML Schema jest technologią zaproponowaną przez Microsoft a obecnie tworzoną przez
twórców XML oraz członków W3C. XML Schema jest z założenia zamiennikiem DTD, o znacznie
zwiększonych możliwościach, usuwający zarazem wady XML DTD. Tak samo jak DTD XML
Schema jest standardem służącym do ograniczania (zawężania) dopuszczalnej struktury dokumentów
XML. XML Schema można nazwać abstrakcyjnym modelem danych składającym się komponentów
np. definicja typu, deklaracja elementu. Komponenty te służą następnie do walidacji poprawnie
Strona 16
Język zapytań dla XML oparty na podejściu stosowym
zbudowanego dokumentu. XML Schema zbudowany został w oparciu o standard XML 1.0 (Second
Edition) oraz standard przestrzeni nazw (XML-Namespaces).
Główne cechy XML Schema:
 Definiuje elementy dopuszczalne w dokumencie
 Definiuje atrybuty dopuszczalne w dokumencie
 Definiuje typy danych dla elementów i atrybutów
 Definiuje domyślne wartości dla elementów i atrybutów
 Definiuje zagnieżdżanie i liczność zagnieżdżonych elementów
Główne zalety XML Schema nad XML DTD
 Składnia XML Schema identyczna ze składnią XML
 Wspiera typy danych wraz z tworzeniem nowych typów na podstawie istniejących.
 Wspiera przestrzeń nazw.
 Umożliwia zdefiniowanie zbiorów.
 Definicja równoważności elementów – można przypisać jeden typ wielu elementom.
 Możliwość używania wyrażeń regularnych przy sprawdzaniu poprawności
Bardzo ciekawym i istotnym elementem jest wprowadzenie reguły zamienialności
(substitutability) elementów – możemy zdeklarować, element, który może być zamieniony przez inne
elementy. Warunkiem koniecznym jest tutaj zgodność typów elementów. Elementy podmieniające
muszą mieć typ identyczny z typem elementu podstawianego lub wyprowadzony z tego typu).
Można przyjąć, że w praktyce najważniejszym elementem będącym w XML Schema, którego
brakowało w DTD jest możliwość definiowania i kontroli typów (pod względem dopuszczalnej
zawartości).
Mocne narzędzie, jakim jest XML Schema dla dokumentów XML rozszerza możliwe
zastosowania XML. XML Schema umożliwia znacznie mocniejszą kontrolę przekazywanymi danymi.
Kontrola taka jest praktycznie niezbędna w zastosowaniach bazodanowych oraz biznesowych.
Ponieważ większość takich systemów działo według zasady GIGO (Garbage In – Garbage Out),
jednym sposobem uniknięcia części śmieci jest kontrola przekazywanych danych. Teoretycznie
kontrolę danych można przeprowadzić w aplikacji przetwarzającej XML, aczkolwiek to podejście ma
kilka wad – przede wszystkim aplikacji przetwarzających dany typ dokumentu XML może być wiele,
w związku z tym, występuje konieczność wielokrotnego pisania podobnego kodu.
XML Schema mimo niewątpliwych zalet posiada też pewne wady.
 Częste zmiany do specyfikacji
 Stosunkowo duże skomplikowanie specyfikacji (13 typów komponentów w 3 kategoriach,
specyfikacja ma kilkaset stron)
 Dziwna definicja XML Schema – zdefiniowany w XML Schema.
Mimo swoich wad, częściowo związanych z wiekiem specyfikacji i brakiem wersji końcowej,
XML Schema jest bardzo mocnym narzędziem do walidacji dokumentów XML. Oprócz zwiększenia
możliwości w porównaniu z DTD, pozbyto się wad związanych z odmienną składnią, które utrudniały
życie zarówno użytkownikom jak i twórcom parserów walidujących.
2.5.3
Przestrzeń nazw w XML (XML Namespaces)
Przestrzeń nazw jest to rozwiązanie problemu niejednoznaczności (np. do jakiego elementu
odnosi się dany atrybut) oraz kolizji nazw.
Zgodnie z definicją W3C przestrzeń nazw XML jest to kolekcja nazw, identyfikowanych
poprzez URI (Uniform Resource Identifier), które są używane w dokumencie XML jako nazwy
atrybutów i elementów. W3C stwierdza także, że różnica pomiędzy przestrzenią nazw XML a
tradycyjną przestrzenią nazw polega na tym, że wersja XML posiada wewnętrzną strukturę i nie jest w
matematycznym znaczeniu zbiorem.
Strona 17
Język zapytań dla XML oparty na podejściu stosowym
Identyczność referencji URI uzyskuje się poprzez porównanie znak po znaku. Referencje URL
niespełniające warunku identyczności mogą być równoważne pod względem funkcjonalności (np.
referencje różniące się tylko i wyłącznie wielkością znaków).
Nazwy w przestrzeni nazw XML składają się z dwóch części rozdzielonych dwukropkiem.
Pierwsza część to prefiks, a druga to nazwa lokalna. Na podstawie prefiksu wybierana jest
odpowiednia przestrzeń nazw.
Ponieważ referencja URI może zawierać znaki niedozwolone dla nazw dopuszczalnych w
XML, prefiks z nazwy używany jest jako zamiennik dla właściwej referencji.
Zakres użycia danej przestrzeni nazw, ograniczony jest do elementu, w którym został
zadeklarowany, a także wszystkich elementów zawartych w danym elemencie.
Zakres użycia przestrzeni nazw XML w dokumentach XML jest obecnie raczej niewielki.
Istnieje kilka powodów dla takiego stanu rzeczy.
1. W większości przypadków nie ma konfliktów nazw – dotyczy to zwłaszcza dokumentów
XML używanych w jednej organizacji.
2. Definicja przestrzeni nazw stworzona przez W3C jest delikatnie rzecz ujmując nieprecyzyjna i
mało szczegółowa.
3. Brak wygodnego łączenia DTD i przestrzeni nazw XML – problem ten ma zlikwidować XML
Schema
Głównym problemem z przestrzenią nazw jest to, że W3C zadeklarowało tylko i wyłącznie
nowy system nazewniczy i praktycznie nic więcej.
Oto kilka praktycznych i teoretycznych problemów związanych z przestrzenią nazw XML:
 Teoretycznie nie można określić czy dana nazwa z przestrzeni nazw odnosi się do atrybutu,
czy też do elementu.(w praktyce problem ten rozwiązuje aplikacja przetwarzająca XML).
 Brak sposobu łączenia dokumentów z różnymi DTD.
 Brak walidacji przestrzeni nazw w dokumentach jej używających.
 Brak możliwości określenia zależności między schematem a przestrzenią nazw.
 Brak definicji struktury przestrzeni nazw (chociaż w definicji przestrzeni nazw XML napisane
jest, że posiada wewnętrzną strukturę, zapomniano ją określić).
 Nazwa przestrzeni określona jako URI może prowadzić donikąd.
Chociaż występuje wyraźna potrzeba dokładanego określenia przestrzeni nazw dla XML, W3C
definiuje praktycznie tylko jednoznaczne identyfikatory i niewiele więcej. Brak jakichkolwiek
informacji o budowie przestrzeni nazw, zastąpione ogólnikowymi stwierdzeniami i bardzo
szczegółowymi przykładami pokazującymi użycie przestrzeni nazw. Zdecydowanie bardziej
precyzyjna definicja tego problemu byłaby bardzo na miejscu, szczególnie, jeśli weźmiemy pod
uwagę ilość specyfikacji odnoszących się w jakiś sposób do przestrzeni nazw XML (np. XLink,
XPointer).
2.5.4
XPath
XPath (XML Path Language) jest produktem współpracy grup zajmujących się rozwojem XSL
oraz XPointer. W trakcie rozwoju specyfikacji XSL i XPointer okazało się, że obie technologie
potrzebują sposobu na wskazanie zbioru specyficznych elementów w dokumencie XML. Ponieważ
tworzenie dwóch praktycznie identycznych języków byłoby tylko i wyłącznie stratą czasu, stworzona
została specyfikacja XPath. Jednak, ponieważ istniały pewne różnice w wymaganiach XPath definiuje
tylko podstawową (bazową) funkcjonalność, do której zarówno XSL jak i XPointer dodają
specyficzne dla siebie wymagania.
Specyfikacja XPath określa, w jaki sposób zlokalizować określony element dokumentu XML.
Aby to umożliwić definiuje pojęcie węzla (node). Węzłem może być dowolny element, atrybut a
nawet dane tekstowe. XPath modeluje dokument XML jako drzewo tak zdefiniowanych węzłów.
Specyfikacja ta w pełni wspiera przestrzeń nazw XML, w związku z tym nazwa węzła składa się z
części lokalnej oraz URI z przestrzenią nazw (może być pusty).
Strona 18
Język zapytań dla XML oparty na podejściu stosowym
Podstawową konstrukcją syntaktyczną XPath jest wyrażenie. Wyrażanie może operować
zarówno na adresach względnych jak i bezwzględnych. Wyrażenie może zwracać następujące typy
danych:
 Zbiór węzłów
 Wyrażenie boolowskie (prawda lub fałsz).
 Liczba
 Ciąg znaków
Obliczanie wyrażenia zachodzi względem kontekstu. Kontekst składa się między innymi z
węzła (względem którego jest wyliczane wyrażanie), pozycji i wielkość kontekstu.
Bardzo istotnym typem wyrażanie jest wyrażanie lokalizujące (LocationPath). Rezultatem
takiego wyrażanie jest zbiór węzłów wybranych względem kontekstu spełniających warunki danego
wyrażania.
Specyfikacja XPath definiuje zestaw funkcji operujących na węzłach, znakach oraz liczbach,
które mogą być używane w wyrażeniach. Funkcje te pozwalając na budowanie całkiem
skomplikowanych wyrażeń.
W XPath zdefiniowano składnię dopasowania wzorca (np. znajdź element którego elementem
macierzystym jest X i elementem siostrzanym Y).
XPath wprowadza także definicję unikalnego identyfikatora. Określa się, że tylko elementy w
dokumentach posiadających DTD mogą, ale nie muszą posiadać identyfikator.
Podsumowując XPath jest w miarę spójnym i intuicyjnym sposobem adresowania zawartości
dokumentów XML. Jedynym mankamentem tej specyfikacji jest to, że nie pozwala odróżnić od siebie
elementów tego samego typu (siostrzanych o takiej samej nazwie), ani ich uporządkować. Aczkolwiek
nie było to założeniem tej specyfikacji. Jednoznaczną identyfikację elementów zajmuje się XPointer
bazujący częściowo na XPath.
2.5.5
XPointer
Specyfikacja XPointer (XML Pointer Language) definiuje język, który ma być używany jako
podstawa do identyfikowania jakiejkolwiek referencji URI, która wskazuje na zasób będący typu
XML.
XPointer zbudowany jest na bazie XPath. Oprócz specyfikacji XPath duży wpływ na tworzenie
specyfikacji miały standardy HTML oraz HyTime (standard ISO umożliwiający reprezentację
statycznych i dynamicznych informacji przetwarzanych i wymienianych przez aplikację
multimedialne i hipertekstowe).
XPointer wspiera adresowanie wewnętrznych struktur dokumentów XML. Pozwala na
przeglądanie hierarchicznej struktury dokumentu XML, a także umożliwia wybór części danego
dokumentu na podstawie wielu właściwości, jak typ elementu, wartość atrybutu, zawartość danych
tekstowych, a także pozycji względnej danego elementu. W szczególności (według specyfikacji)
XPointer dostarcza referencję do elementów, oraz innych części dokumentu XML, nawet w przypadku
nie posiadanie przez elementy identyfikatora.
XPointer jak już wspomniano przy opisie specyfikacji XPath, definiuje rozszerzenia do tej
specyfikacji. Rozszerzenia te umożliwiają:
 Użycie XPath jako części referencji URI określającej dany zasób.
 Adresowanie punktów (pozycji w dokumencie XML) i zakresów (wszystkie dane między
dwoma punktami), jak również całych węzłów.
 Lokalizację informacji poprzez dopasowywanie ciągów znaków.
Struktury adresowane, przez XPointer mogą być używane w tworzeniu łączy, a także do
zastosowań specyficznych dla konkretnej aplikacji. Specyfikacja nie ogranicza, co aplikacja może
robić danymi identyfikatorami przez XPointer. W szczególności implementacja przejścia do zasobu
identyfikowanego przez XPointer nie jest określona w specyfikacji. Definiowaniem łączy wiążących
różne zasoby, włączając dokumenty XML i ich części, zajmuje się specyfikacja XLink).
Strona 19
Język zapytań dla XML oparty na podejściu stosowym
Pewną wadą specyfikacji XPointer jest brak adresowania wewnętrznych struktur DTD oraz
deklaracji XML – specyfikacja określa, że te tematy są poza obszarem danej specyfikacji.
Prawdopodobnie związane jest to z tym, iż DTD posiada zupełnie inną strukturę (całkowicie
niezgodną, z XML), a deklaracja XML, chociaż jest częściowo zgodna z syntaktyką XML(znaczniki i
atrybuty), burzy hierarchię dokumentu XML (musi być traktowana inaczej niż elementy XML).
Bardzo ciekawą informacją w specyfikacji XPointer, jest możliwość odniesienia się do
dowolnego elementu nawet, jeżeli nie posiada on jednoznacznego identyfikatora. W dalszej części
specyfikacji można przeczytać, że w tym przypadku, element jest określany względnie np. węzła
posiadającego ID. Jest to bardzo ciekawe podejście, ponieważ, naszym zdaniem nie umożliwia
precyzyjnego określenia dokumentu (a taki jest sens specyfikacji XPointer), w przypadku możliwości
wykonywania zmian na dokumencie (np. wstawmy element siostrzany przed elementem określanym
względnie – wtedy identyfikator odnosić się będzie do nowo wstawionego elementu, a nie do już
istniejącego). Specyfikacja wspomina, że powinno się używać identyfikatorów elementów i W3C do
tego zachęca, ale nie wymaga. Praktycznie jedynym sensownym rozwiązaniem tego problemu jest
wymuszenie istnienia unikalnych identyfikatorów dla każdego elementu mogącego być adresowanym
przez XPointer, a co z tego wynika, mogącym być odnośnikiem jakiegoś łącza. W tym momencie
można korzystać z specyfikacji XPointer, wymuszając np. w ramach projektu stosowanie
identyfikatorów.
Podsumowując, specyfikacja ta jest krokiem w dobrym kierunku, aczkolwiek błędy, które się w
niej znalazły, wykluczają wiele zastosowań. Widać wyraźnie, że twórcy tego standardu nie mają za
wiele do czynienia z bazami danych i nie zdają sobie sprawy z konsekwencji tego, co piszą. Miejmy
nadzieję, że standard XPointer poprawi te błędy, wymuszając stosowanie identyfikatorów (a co za tym
idzie, XML Schema lub DTD, dzięki którym można sprawdzić czy jest atrybut o nazwie ID) dla
dokumentów, które chcą korzystać z specyfikacji XPointer.
Bardzo istotnym dodatkowym problemem związanym z specyfikacją XPointer jest to, że jest
ona wciąż w trakcie tworzenia i w związku z tym nie jest zaimplementowana w najważniejszych
przeglądarkach, przeglądarkach także innych programach.
2.5.6
XLink (XML Linking Language)
Specyfikacja XLink definiuje język umożliwiający wstawianie elementów do dokumentów
XML w celu zdefiniowania łączy między zasobami. Używa syntaktyki XML w celu stworzenia
struktur, które opisują proste łącza jak w HTML, jak również bardziej złożone.
Łącze w terminologii XLink to połączenie dwóch lub większej ilości obiektów danych lub ich
fragmentów.
Łącza XML oparte są na elementach łączących. Z kolei elementy łączące zawierają lokalizatory
(dane dotyczące lokalizacji) wskazujące konkretne zasoby. Lokalizatory są to URI, identyfikator
fragmentu, bądź połączenie obu tych możliwości. Lokalizatorami dla dokumentów XML mogą być
wskaźniki typu XPointer.
XLink definiuje dwa typy łącz – łącza proste i złożone. Łącza proste są bardzo zbliżone do
mechanizmu łącz znanego z standardu HTML. Są to łącza jednokierunkowe, gdzie występuje tylko
jeden lokalizator.
Łącza złożone jest to bardzo ciekawa propozycja, umożliwiająca znaczne rozszerzenie
zastosowań XML. Jednym z ciekawszych rzeczy jest fakt, że łącza nie muszą znajdować się w pliku
XML, w którym się zaczynają lub, na który wskazują. Jest to jednakże tylko udogodnienie, oprócz
tego łącza złożone umożliwiają:
 Łączenie dowolnej liczby zasobów, umożliwia to tworzenie relacji jeden-do-wielu a co za tym
idzie także obsługę relacji wiele-do-wielu, zamiast zwykłej relacji jeden-do-jednego znanej z
łącz prostych i HTML.
 Łączenie zasobów, które same nie mogą zawierać łączy (np.pliki graficzne, binarne itp.)
 Dynamiczne filtrowanie, dodawania i modyfikację łączy.
 Realizację połączeń na wiele sposobów w zależności od potrzeb.
Strona 20
Język zapytań dla XML oparty na podejściu stosowym
Łącza złożone w rzeczywistości bezpośrednio na nic nie wskazują, ani nic nie łączą. Element
łącza złożonego zawiera lokalizatory oraz wewnętrzną identyfikację, które łącznie tworzą właściwe
łącze.
Oprócz tego XLink pozwala opisywać łącza i ich zasoby poprzez zdefiniowanie pewnych
atrybutów. Przykładowym atrybutem jest atrybut „role” oznaczający rolę, jaką stanowi dane łącze dla
aplikacji.
Jak już wspomniano łącza nie muszą znajdować się w dokumentach których dotyczą. Możliwe
jest to poprzez zdefiniowanie grupy łącz. Elementy grupy łącz, nic nie wskazuje, umożliwia natomiast
określenie elementów, w których poszczególne dokumenty zawierają zasoby.
Dodatkowymi cechami XLink jest możliwość określenia zachowania się łączy. Można określić,
kiedy łącze będzie aktywne, kiedy nastąpi skok, lecz także, co ma się dziać w momencie skoku.
Specyfikacja XLink znacznie rozszerza możliwości XML. Zastosowanie XLink umożliwi
modelowania bardziej rzeczywistych zależności między dokumentami XML, a także pozwoli na
usunięcie redundancji danych. Teoretycznie pozwoli także na tworzenie baz danych opartych w
całości na dokumentach XML (pozostaje kwestia wydajności takiego systemu). Zaletą takiej bazy
danych byłoby naturalne rozproszenie zasobów.
Trzeba jednak stwierdzić, że bez precyzyjnej możliwości określenia elementów, do których
odnosi się łącze XLink (poprzez bardziej precyzyjne zdefiniowanie XPointer), mogą wystąpić
problemy w wielu zastosowaniach (np. bazy danych).
Niestety tak samo jak XPointer, specyfikacja XLink jest wciąż w trakcie tworzenia, przez co nie
jest ona jeszcze praktycznie implementowana (Mozilla posiada częściową implementację poprzedniej
wersji XLink – XML Link). W związku z tym, problematyczne jest ustosunkowanie się do
rzeczywistych możliwości i potencjalnych zastosowań technologii XLink oraz technologii z nią
powiązanych.
2.5.7
Rozszerzalny język arkuszy stylów (XSL - eXtensible Style sheet Language)
XSL jest to język stylów dla dokumentów XML. Ponieważ XML nie posiada niezmiennych i
ściśle określonych znaczników (jak HTML), oraz informacje zawarte w dokumencie XML, mogą nie
być w formie, w jakiej chcemy je prezentować, a także znaczniki XML zazwyczaj nie niosą informacji
o formatowaniu, stworzono XSL udostępniający informacje jak prezentować i przetwarzać dokumenty
XML. XSL składa się z trzech części:
 Transformacji XSL (XSLT) – język dla dokonywania transformacji na dokumentach XML
 XPath – języka używanego przez XSLT do wskazania lub pobrania części dokumentu XML.
 XSL Formatting Objects – zestaw słów kluczowych XML, dla specyfikowania formatowania.
Rozdzielenie treści od warstwy prezentacji pozwala prezentować te same informacje na wiele
różnych sposobów. Oto kilka przykładowych zalet:
 Ta sama treść może mieć różny wygląd w zależności od kontekstu.
 Wiele formatów docelowych, w zależności od medium przenoszącego informacje (papier,
wersja elektroniczna), rozmiaru, urządzeń docelowych (stacja robocza, palmtop, telefon
komórkowy).
 Wygląd dostosowany do preferencji użytkownika (wygląd, kolor, itp.).
 Używanie standardowych arkuszy stylów np. w firmie pozwala na uzyskanie jednorodnego
wyglądu dokumentów.
Istnieją dwa podstawowe zastosowania rozszerzalnych arkuszy stylów.
 Transformacja jednego dokumentu XML w inny dokument XML – ta bardzo istotna cecha
pozwala na usprawnienie wymiany informacji między aplikacjami. Przy czym struktury tych
dokumentów mogą być diametralnie różne.
 Tworzenie opisu dotyczącego prezentacji przekształconych informacji (np. jakie właściwości
powiązać z każdą częścią przetwarzanego dokumentu.
Podczas transformacji jednego dokumentu XML w inny dane są następujące transformacje:
Strona 21
Język zapytań dla XML oparty na podejściu stosowym





Generowanie stałych fragmentów tekstu (np. etykiety).
Przenoszenie tekstu (np. zamiana kolejności imienia i nazwiska).
Duplikacja tekstu (np. Tworzenie spisu treści).
Sortowanie
Bardziej złożone transformacje „tworzące” nowe informacje na podstawie istniejących
danych.
Istnieją także następujące formatowanie informacji:
 Specyfikowanie ogólnego układu strony
 Przyporządkowywanie przetworzonej treści do odpowiednich „kontenerów zawartości” np.
listy, paragrafy.
 Specyfikowanie właściwości formatowania (odstępy, margines, font, itp.).
Podsumowując XSL jest specyfikacja niezbędna do szerszego wykorzystania XML w praktyce.
Możliwość transformacji dokumentów, wraz z możliwością dodawania opisów dotyczących
formatowania, tworzą z XSL bardzo potężne narzędzie zarówno dla twórców stron WWW jak i
twórców aplikacji (prezentacja danych oraz wymiana z innymi aplikacjami). Jeżeli pozostaniemy przy
tylko takim zastosowaniu XSL to trzeba przyznać, że ta specyfikacja jest jedną z lepszych, jakie
powstały w otoczeniu XML. Oczywiście należy pominąć milczeniem próby stworzenie języka zapytań
opartego o XSL (w oparciu o wzorce i ich wyszukiwanie), lecz przecież specyfikacja ta nie do tego ma
służyć.
3. Języki zapytań
Każdy system służący do gromadzenia danych, aby miał jakiekolwiek praktyczne zastosowanie,
musi posiadać narzędzia służące do ich odzyskiwania. Jeśli gromadzone są duże ilości danych,
narzędzia te muszą być odpowiednio rozbudowane – powinny umożliwiać wyszukiwanie danych
spełniających określone wymagania, agregowanie danych i inne, odpowiednie do przewidywanych
zastosowań, operacje. Systemy specjalizowane, tworzone dla konkretnego użytkownika bardzo często
zawierają gotowe funkcje tworzenia raportów i filtrowania danych, przystosowane do konkretnych
zastosowań. Bardziej generyczne systemy – takie jak Systemy Zarządzania Bazami Danych wymagają narzędzi uniwersalnych: języków zapytań2.
3.1. Języki zapytań w systemach relacyjnych
Wszystkie znane autorom pracy Relacyjne SZBD używają jakiejś mutacji języka SQL. Język
ten powstał (jeszcze pod nazwą SEQUEL) pod koniec lat 70-tych podczas prac nad System/R –
prototypem relacyjnej bazy danych, opracowywanym w laboratoriach IBM. System/R nie doczekał się
komercyjnego zastosowania, SQL jednak przetrwał, i został zastosowany w produkcie firmy
Relational Software – Oracle, jak również w opracowanych przez IBM systemach SQL/DS i DB2. W
połowie lat osiemdziesiątych SQL wygrał konkurencję z językiem QUEL, używanym przez SZBD
Ingres. Dzięki stojącej za SQL potędze IBM, język ten stał się standardem de facto. Inne pojawiające
się na rynku SZBD również używały SQL jako język zapytań, zaś ANSI rozpoczęła pracę nad
standaryzacją SQL. Prace te zaowocowały standardami: SQL-86, SQL-89, SQL-92 i roboczymi
wersjami: SQL3 (zarzucony przed zakończeniem prac) i SQL1999 (obecnie opracowywany standard
SQL).
Niestety, mimo istnienia opracowanych i zatwierdzonych standardów, trudno jest dziś znaleźć
SZBD stosujący się do nich w 100%. Każdy producent SZBD wprowadza „usprawnienia” i
„udogodnienia”, zapominając jednak często o wprowadzeniu elementów należących do standardu
Warto tu zauważyć, że systemy specjalizowane zazwyczaj budowane są na SZBD i ich narzędzia do
wyszukiwania danych oparte są na językach zapytań tych SZBD. Ukrywają one zazwyczaj niewygodną dla
typowego użytkownika warstwę języka zapytań, oferując łatwiejsze w użyciu (choć bardziej ograniczone)
narzędzie.
2
Strona 22
Język zapytań dla XML oparty na podejściu stosowym
(przykładem tu może być brak typu TIMESTAMP w systemie Oracle 8i, deklarującym zgodność z
SQL-92). Nierzadko różnice te są widoczne już na poziomie syntaktyki języka (drobne różnice w
sposobach zapisu wyrażeń, różnice w zbiorach słów kluczowych).
Najczęstsze sposoby użycia SQL to:
 Zanurzony SQL – zapytania SQL są wstawiane bezpośrednio w kod programu w innym
języku, w blokach rozpoczynających się deklaracją EXEC SQL. Manipulacja pozyskiwanymi
(lub wstawianymi) w ten sposób danymi odbywa się z poziomu języka programowania, w
którym zanurzony są instrukcje SQL. Zamiana bloków EXEC SQL na odpowiednie
wywołania wykonywana jest przez preprocesor. Sposób użycia zanurzonego SQL określony
jest w standardzie SQL-92 (i późniejszych SQL3 i SQL1999).
 Dynamiczne lub statyczne zapytania SQL, wywoływane przy pomocy odpowiednich API
(ODBC, JDBC, API producenta bazy danych). API te są zazwyczaj produktami pojedynczych
firm, ich pozycja standardów de facto wynika z pozycji promujących je firm.
Napotykają one na szereg problemów, nazywanych zbiorczo „niezgodnością impedancji”,
wymienionych i opisanych m.in. w [3]. Wynikają one z zasadniczo różnych koncepcji, z których
wywodzą się języki powszechnie używane do tworzenia aplikacji (takie jak C++ lub Java) i SQL.
Problemy te są możliwe do uniknięcia tylko przez użycie do tworzenia aplikacji języków
zbudowanych na bazie języków zapytań – takich, jak np. Oracle PL/SQL. Niestety, języki te jak na
razie mogą mieć tylko ograniczone zastosowanie – kod w takim języku wykonywany jest po stronie
serwera SZBD, wskutek czego trudno zastosować taki język np. do oprogramowania interfejsu
użytkownika3.
SQL – Krótka charakterystyka
Oparty jest na modelu relacyjnym,
Dostarcza konstrukcje wysokiego poziomu do przetwarzania wielozbiorów i zbiorów krotek,
Nie zapewnia swobodnego ortogonalnego kombinowania operatorów. Posiada pod tym
względem bardzo ograniczone możliwości, które są często jeszcze bardziej ograniczane przez
konkretne implementacje,
 Nie jest kompletny obliczeniowo,
 Zapytania SQL mogą być używane wewnątrz języków programowania, dla których
zdefiniowane są wiązania.
3.1.1



3.2. Języki zapytań w systemach obiektowych
O ile rynek relacyjnych SZBD można uznać za opanowany przez język SQL, o tyle na rynku
obiektowych SZBD brak w chwili obecnej takiego ogólnie uznanego standardu. Standard ODMG,
obejmujący między innymi OQL (Object Query Language – obiektowy język zapytań) jest
implementowany tylko przez część systemów dystrybuowanych jako Obiektowe SZBD. Wielu
producentów Obiektowych SZBD wydaje się albo nie dostrzegać potrzeby zaimplementowania języka
zapytań (poprzestając jedynie na mechanizmach zapewnienia trwałości obiektów i ich filtrowania),
albo uważa za wystarczającą implementację rozbudowanej wersji SQL.
3.2.1
OQL – Krótka charakterystyka
Język OQL stanowi część standardu ODMG. Jest językiem deklaratywnym, opartym o składnię
SQL. Został zaprojektowany jako język zapytań dla obiektowych baz danych. Obiekty mogą być
używane w zapytaniach, są też zwracane przez zapytania. OQL może być używany zarówno z
poziomu innego języka programowania (standaryzowano wiązania dla języków C++ i Java), jak i jako
samodzielny język zapytań. W przeciwieństwie do SQL jest jedynie językiem zapytań, nie umożliwia
wykonywania operacji zmieniających stan bazy danych, z wyjątkiem tworzenia nowych obiektów.
W przypadku Oracle PL/SQL możliwe jest stworzenie interfejsu użytkownika opartego na WWW, przy użyciu
pakietów PL/SQL wchodzących w skład aplikacji takich jak Oracle Web Application Server, Oracle Web DB
lub Oracle Application Server.
3
Strona 23
Język zapytań dla XML oparty na podejściu stosowym
Wszelkie operacje wpływające na stan bazy danych muszą być wykonywane z poziomu języka
programowania. Możliwość tworzenia nowych obiektów z poziomu języka zapytań, przy
jednoczesnym braku możliwości ich usuwania lub zmiany wydaje się być dość dziwne.
 OQL charakteryzuje się następującymi cechami ([7]):
 Bazuje na modelu obiektowym ODMG,
 Powierzchownie przypomina SQL,
 Przewiduje konstrukcje wysokiego poziomu do przetwarzania zbiorów obiektów, ale nie jest
ograniczony do przetwarzania zbiorów (może również przetwarzać struktury, listy, tablice, itp.
z taka samą efektywnością),
 Zapewnia swobodne ortogonalne kombinowanie operatorów, o ile tylko nie narusza to mocnej
kontroli typów. Wynika to z faktu, że rezultat zapytania ma typ należący do systemu typów
ODMG i w związku z tym może stanowić argument większego zapytania,
 Nie jest kompletny obliczeniowo,
 Zapytania OQL mogą być używane wewnątrz języków programowania, dla których ODMG
zdefiniował wiązania. OQL może także wołać operacje zdefiniowane w tych językach
programowania. Nie ma istotnej różnicy pomiędzy użyciem w zapytaniu atrybutu i metody
obiektu.
 Nie przewiduje explicite operacji aktualizacyjnych, ale może wywoływać operacje zapisane w
innych językach, które są dla tego celu zdefiniowane
 Zapewnia deklaracyjny (nieproceduralny) dostęp do obiektów
 Zgodnie z deklaracjami ODMG, Formalna semantyka OQL może być łatwo zdefiniowana.
To, czy jest tak w rzeczywistości stanowi problem dyskusyjny. Faktem jest, że jak dotąd nie
została ona zdefiniowana.
3.2.2
Inne istniejące rozwiązania
Poza OQL pojawiły się również inne rozwiązania:
 SQL3 i SQL1999 wykonują (zgodnie z deklaracjami projektodawców) pewien krok w stronę
obiektowości, wprowadzając m.in. ADT – abstrakcyjne typy danych. Są to jednak
rozwiązania sprawiające wrażenie prowizorycznych i nie zajmujące się wieloma problemami.
 Rozszerzenia SQL takie jak SQL++ proponowany przez Objectivity ([4]) i VSQ proponowany
przez Versant ([6]), łączące SQL-92, rozszerzenia obiektowe wprowadzone w SQL3,
elementy OQL i własne propozycje producentów. Są to rozwiązania, które można uznać co
najwyżej za prowizoryczne – zazwyczaj nie umożliwiają one (tak jak w przypadku VSQ i
SQL++) wywoływania w ramach zapytania metod.
 Propozycje typu „Query By Example” proponowane w [5].
 SBQL, proponowany w [3], odchodzący całkowicie od związków z SQL, unikający
większości jego błędów i problemów. Najbardziej rozbudowany z proponowanych modeli
przypomina ideą PL/SQL – język programowania, zintegrowany z językiem zapytań. Taka
konstrukcja umożliwia między innymi użycie zapytań jako parametrów procedur (metod),
użycie metod w zapytaniach, traktowanie perspektyw jako procedur. Rozwiązuje też problemy
z niezgodnością impedancji. Istniejąca implementacja SZBD, używająca tego języka – system
Loquis dowodzi, iż jest on możliwy do implementacji.
3.3. Języki zapytań dla XML
Jako, że XML jest często wskazywany jako uniwersalny format przechowywania danych
strukturalnych, dostrzeżono potrzebę stworzenia języka zapytań umożliwiającego obróbkę danych
zawartych w plikach XML. Mimo tego, iż standard XML powstał już wiele lat temu, do tej pory nie
udało się stworzenie standardowego języka zapytań dla XML. W3C stworzyło zalecenie dla języka
zapytań pod nazwą XML Query Requirements, lecz dokument ten wzbudza wiele kontrowersji.
Powstało też wiele języków niebazujących na XML Query Requirements lub bazujących na tym
dokumencie tylko częściowo. Poniżej omawiamy znane nam rozwiązania w tym zakresie, jak również
zalecenia W3C.
Strona 24
Język zapytań dla XML oparty na podejściu stosowym
3.3.1
XML Query Requirements
Jak można przeczytać na stronach W3C ([15]), celem XML Query Requirements jest
stworzenie modelu danych dla dokumentów XML, zestawu operatorów działających na tym modelu,
oraz języka zapytań bazującego na tych operatorach. W3C zakłada użycie języka zapytań dla XML w
następujących celach:
 Wykonywania zapytań na dokumentach XML oraz kolekcjach dokumentów takich jak np.
instrukcje obsługi, w celu znalezienia dokumentu, lub fragmentu dokumentu.
 Wykonywanie zapytań na dokumentach zawierających dane w celu przekształcenia ich do
nowej postaci, lub zintegrowania danych z wielu źródeł.
 Wykonywanie zapytań na dokumentach zawierających zarówno dane jak i opisy tekstowe,
takich jak katalogi, dane chorobowe pacjenta itp.
 Wykonywanie zapytań na danych administracyjnych (pliki konfiguracyjne, logi, profile
użytkowników)
 Filtrowania danych napływających w formie dokumentów XML przysyłanych strumieniowo.
 Wykonywanie zapytań na drzewach DOM
 Wykonywanie zapytań na repozytoriach dokumentów w XML oraz serwerach WWW.
 „Wykonywanie zapytań na katalogach zawierających serwery dokumentów, typy dokumentów,
pliki XML Schema, lub dokumenty. Takie katalogi mogą być łączone w celu umożliwienia
wyszukiwania na wielu serwerach. System wyszukiwania dokumentów powinien pozwolić
użytkownikowi na wybranie katalogów serwerów, reprezentowanych w XML, na podstawie
informacji dostarczanej przez serwery, kosztu dostępu lub praw dostępu. Po wybraniu serwera,
system wyszukiwania dokumentów może zwrócić rodzaje dokumentów znajdujące się na
serwerze i pozwolić użytkownikowi na odpytywanie tych dokumentów”.
 Zapytania mogą być używane w wielu „środowiskach syntaktycznych” takich jak: URL, strona
XML, JSP, ASP. Zapytania mają mieć reprezentację ciągu znaków w programie napisanym w
języku programowania ogólnego zastosowania, jako argument z linii komend, lub przesyłane
jako protokołu sieciowego.
Autorzy dokumentu już określając założenia dotyczące języka zapytań mieszają ze sobą bardzo
ogólne, ze szczegółowymi opisami konkretnych zastosowań, oraz ze sprawami czysto technicznymi
mającymi mały związek z samą konstrukcją języka zapytań. Jest to po prostu typowy dokument
napisany przez W3C.
W3C definiuje następujące wymagania stawiane językowi zapytań dla XML:
 Języki zapytań zbudowane na podstawie dokumentu W3C mogą mieć różne syntaktyki, Język
zapytań musi być wygodny i czytelny dla użytkownika i wyrażony w XML.
 Język zapytań musi być deklaratywny, oraz nie może wymuszać konkretnej strategii ewaluacji
 Język musi być niezależny od protokołu komunikacyjnego.
 Język zapytań musi określać standardowe błędy mogące powstać podczas ewaluacji zapytania.
 Język zapytań dla XML nie może ograniczać możliwości rozbudowy samego standardu XML.
 „Język zapytań dla XML musi być zdefiniowany dla skończonych instancji modelu danych.
Może być zdefiniowany dla nieskończonych instancji.”.
Podobnie jak cele, również wymagania stawiane językom zapytań są bardzo dalekie od ideału. W
gruncie rzeczy wymaganie te określają tylko i wyłącznie budowę języka zapytań (nakazując
wyrażanie zapytań w XML), pomijając praktycznie wszystkie istotne wymagania, jakie powinny
znaleźć się w tym dokumencie.
Strona 25
Język zapytań dla XML oparty na podejściu stosowym
Model danych XML zdefiniowany w opisywanym dokumencie musi spełniać następujące założenia
 Model danych dla zapytań musi opierać się na informacjach otrzymanych od procesorów XML
oraz XML Schema i nie może wymagać informacji niedostarczanych przez te procesory.
Model danych musi pokazywać odwzorowanie konstrukcji XML w odpowiednie konstrukcje
modelu danych. Model danych powinien mieć reprezentację dla wszystkich elementów
niosących informację lub zawierać wyjaśnienie, dlaczego konkretna konstrukcja została
pominięta. Model musi być opracowany we współpracy z XML Schema Working Group w
celu zapewnienia zgodności między modelem danych a danymi dostarczonymi przez
procesory XML Schema.
 Model danych musi reprezentować zarówno prosty typ znakowy jak i typy proste i złożone
zdefiniowane w XML Schema
 Model danych musi umożliwiać reprezentację kolekcji dokumentów i kolekcji wartości
prostych i złożonych.
 Model danych musi zawierać wsparcie dla referencji, włączając referencje wewnętrzne oraz do
zewnętrznych dokumentów XML.
 Model danych musi uwzględniać elementy wprowadzane do dokumentu XML przez XML
Schema, takie jak np. wartości domyślne.
 Model danych musi uwzględniać przestrzenie nazw.
W3C wymaga od języków zapytań dla XML następującej funkcjonalności:
 Język zapytań musi wspierać operację na wszystkich typach danych reprezentowanych w
modelu danych.
 Zapytania muszą umożliwiać wyrażanie prostych warunków na tekst, włączając warunki na
tekst przekraczający granice elementu.
 Język zapytań musi wspierać kwantyfikatory ogólne i egzystencjalne.
 Język zapytań musi wspierać operacje na hierarchii i sekwencji struktur dokumentu.
 Język musi być zdolny do łączenia informacji z wielu części dokumentu, lub wielu
dokumentów.
 Język zapytań musi zawierać operacje agregujące.
 Język zapytań musi zawierać operacje sortujące.
 Język zapytań musi umożliwiać zagnieżdżanie zapytań.
 Język zapytań musi wspierać wartości NULL.
 Język zapytań musi przenosić hierarchię i kolejność elementów z dokumentu źródłowego do
dokumentu stanowiącego wynik zapytania.
 Język zapytań musi umożliwiać transformację struktury XML i tworzenie nowych struktur.
 Język zapytań musi umożliwiać przechodzenie po referencjach zarówno wewnątrz jak i na
zewnątrz dokumentu.
 Język zapytań musi zachowywać tożsamość elementów.
 Język zapytań musi umożliwiać operację na literałach (dowolne dane zdefiniowane wewnątrz
zapytania).
 Język zapytań musi umożliwiać wykonywanie prostych operacji na nazwach, takich jak
porównywanie nazw elementów, atrybutów, instrukcji przetwarzania. Musi pozwalać także na
operacje na kombinacji nazw i danych. Zapytania mogą wykonywać bardziej złożone operacja
na nazwach.
Strona 26
Język zapytań dla XML oparty na podejściu stosowym
 Język zapytań powinien umożliwiać dostęp do XML Schema lub DTD dla danego dokumentu.
Jeżeli schemat jest reprezentowany w postaci DTD, mapowanie do XML Schema może być
wymagane.
 Język zapytań musi operować na informacjach post-walidacyjnych otrzymanych od procesora
XML Schema.
 Język zapytań powinien wspierać wykorzystanie zewnętrznie zdefiniowanych funkcji na
wszystkich typach danych istniejących w modelu danych. Powinien definiować interfejs dla
takich funkcji oraz powinien rozróżniać takie funkcje od funkcji zdefiniowanych w języku
zapytań. Implementacja funkcji zewnętrznych nie jest częścią języka zapytań.
 Język zapytań musi udostępniać informacje środowiskowe, właściwe dla środowiska, w którym
zapytanie jest wykonywane.
 „Zapytanie muszą być domknięte względem modelu danych dla zapytań XML. Zarówno
wejście jak i wyjście zapytania muszą być zdefiniowane wyłącznie przy pomocy modelu
danych dla zapytań XML. Źródła niebędące dokumentami XML mogą być odpytywane tylko
i wyłącznie w przypadku, gdy zostanie dla nich zdefiniowana reprezentacja w modelu danych.
Podobnie wyniki zapytań zdefiniowane są wyłącznie przy pomocy modelu danych dla zapytań
XML. W oprogramowaniu wyniki te mogą być utworzone przy pomocy dowolnej, wygodnej
reprezentacji, takiej jak: DOM, węzły, hiperlinki, tekst XML, lub różne inne formaty danych.”
Ponadto W3C stworzyło dwa dokumenty: XML Query Use Cases oraz XQuery 1.0 Formal Semantics.
Pierwszy z tych dokumentów zawiera wiele przykładowych danych wraz z przykładami zapytań i
pożądanymi wynikami tych zapytań. Drugi zaś zgodnie z tytułem powinien zawierać semantykę
XQuery, trudno jest natomiast określić, co rzeczywiście zawiera (ale raczej nie jest to semantyka,
zgodnie z ogólnie przyjętą definicją semantyki). Zawarcie przykładów zapytań w dokumencie XML
Query Use Cases kłóci się z przyjętym w dokumencie XML Query Requirements założeniem o nie
narzucaniu składni języka zapytań. Podobnie jest z dokumentem XQuery 1.0 Formal Semantics,
którego znaczne część poświęcona jest gramatyce języka.
3.3.2
XQuery
XQuery jest językiem opartym na XML Query Requirements, XQuery 1.0 Formal Semantics i
XML Query Use Cases. Istnieje kilka implementacji podzbiorów tego języka, przykładową może być
XQuantum Database stworzony przez firmę Cognetic Systems ([16]). Składnia języka oparta jest na
gramatyce zdefiniowanej w XQuery 1.0 Formal Semantics oraz przykładach zapytań z dokumentu
XML Query Use Cases.
Przykładowe zapytanie w XQuery, pochodzące z dokumentu XML Query Use Cases (przykład
1.7.4.7 Q7), wyszukujące strony z wszystkimi aukcjami, dla których zarówno sprzedawca jak i
kupujący zarejestrowani są w tym samym domu aukcyjnym.
namespace ma = "http://www.example.com/AuctionWatch"
<Q7>
{
for $a in document("data/ns-data.xml")//ma:Auction
let $seller_id := $a/ma:Trading_Partners/ma:Seller/*:ID,
$buyer_id := $a/ma:Trading_Partners/ma:High_Bidder/*:ID
where namespace-uri($seller_id) = namespace-uri($buyer_id)
return
$a/ma:AuctionHomepage
}
Strona 27
Język zapytań dla XML oparty na podejściu stosowym
</Q7>
Wynikiem takiego zapytania (dla przykładowych danych podanych w dokumencie) może być
następująca struktura:
<Q7 xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:ma="http://www.example.com/AuctionWatch" >
<ma:AuctionHomepage xlink:type="simple"
xlink:href="http://auctions.yabadoo.com/auction/13143816" />
</Q7>
Jak widać stosunkowo proste zapytanie, jest niezbyt czytelne dla użytkownika. Bardziej
skomplikowane zapytania, stają jeszcze bardziej nieczytelne. Możliwość wyszukiwania błędów w
takich zapytaniach stoi pod znakiem zapytania.
3.3.3
XML-QL
XML-QL był propozycją W3C przed stworzeniem XQuery. Podobnie jak w przypadku
XQuery, język ten jest zdefiniowany przy pomocy przykładów i gramatyki co wydaje się niezbyt
profesjonalną i precyzyjną metodą definiowania języków.
Przykładowe zapytanie zawierające złączenie pochodzi z dokumentu opisującego język XML-QL
([17]). Zwraca wszystkie artykuły napisane przed autora, który napisał przynajmniej jedną książkę po
1995 roku.
WHERE <article>
<author>
<firstname> $f </> // firstname $f
<lastname> $l </>
// lastname $l
</>
</> CONTENT_AS $a IN "www.a.b.c/bib.xml"
<book year=$y>
<author>
<firstname> $f </> // join on same firstname $f
<lastname> $l </>
// join on same lastname $l
</>
</> IN "www.a.b.c/bib.xml",
y > 1995
CONSTRUCT <article> $a </>
Również ta propozycja W3C, pomijając już niejasności wynikłe z braku precyzji w definiowaniu
języka, nie wydaje się zbyt łatwa w użyciu.
3.3.4
LOREL
LOREL jest językiem zapytań stworzonym na uniwersytecie w Stanford w ramach projektu
LORE ([18]), którego celem było stworzenie systemu zarządzenie bazą danych dla danych półstrukturalnych. Prace nad LORE rozpoczęto w 1995 roku i zakończono ogłaszając sukces w roku
Strona 28
Język zapytań dla XML oparty na podejściu stosowym
2000. LOREL jest rozszerzeniem OQL. Zmiany dotyczyły obsługi danych pół-strukturalnych oraz
osłabienia mocnej kontroli typów występującej w OQL..
Przykładowe zapytanie w LOREL, wyszukujące nazwy i kody pocztowe wszystkich „tanich”
restauracji, w zapytaniu tym nie wiemy czy kod pocztowy będzie częścią adresu czy też elementem
potomnym, oraz w którym miejscu opisu restauracji wystąpi słowo „tani”:
select Guide.restaurant.name,
Guide.restaurant(.address)?.zipcode
where Guide.restaurant.% grep "cheap”
LOREL jest jednym z bardziej sensownych i czytelnych języków zapytań dla XML. Podobieństwo do
OQL pozwala w łatwy i szybki sposób przyswoić sobie ten język. Jego uniwersyteckie korzenie są
widoczne w jego elegancji (w porównaniu z propozycjami W3C). W ramach projektu LORE
stworzono cały system zarządzania bazą danych, z indeksowaniem i optymalizacją zapytań włącznie.
3.3.5
XQL
XQL ([19]) jest, jak twierdzi jego autor „naturalnym rozszerzeniem składni XSL”, został
przedstawiony w 1998 roku jako propozycja rozszerzenia składni XSL do XSL Working Group.
Zakłada on wykorzystanie mechanizmów XSL w celu wykonywania zapytań na plikach XML.
Pomysł ten wydaje się co najmniej wątpliwy – równie dobrze można by wykorzystywać do
wykonywania zapytań inne narzędzia służące do obróbki plików tekstowych (jak AWK lub GREP).
Jedyną widoczną zaletą tego języka jest stosunkowo prosta składnia nieskomplikowanych zapytań
(przynajmniej w porównaniu z przedstawionymi już propozycjami W3C). Przykładowe zapytanie
znajdujące węzły typu „author” o wartości tekstowej „Matthew Bob” może wyglądać tak:
author[text() = 'Matthew Bob']
lub tak
author[. = 'Matthew Bob']
Niestety bardziej skomplikowane zapytania, zwłaszcza wykorzystujące kolekcje lub złączenia, mimo
podobnie zwięzłej formy stają się znacznie mniej czytelne.
3.3.6
Yatl
Yatl powstał w Bell Laboratories, jako język, jak piszą autorzy w swoim opracowaniu na temat
tego języka ([20]), do „odpytywania, konwersji i integracji danych XML”. Został zaimplementowany
w całości w języku funkcyjnym (ML lub Objective CAML – autorzy nie są zdecydowani w tekście
swojego opracowania). Yatl sam jest językiem funkcyjnym.
Przykładowe zapytanie w języku Yatl, wzięte z opracowania „XML Query Languages:
Experiences and Exemplars” ([21]) wygląda następująco:
make
bib [ *book [ @year [ $y ],
title [ $t ] ] ]
match "www.bn.com/bib.xml" with
bib [ *book [ @year [ $y ],
title [ $t ] ],
publisher [ name [ $n ] ] ]
where
$n = "Addison-Wesley" and $y > 1991
Jak widać zapytanie to nie różni się zbytnio od zapytań wyrażonych w XQuery – można odnieść
wrażenie, że najistotniejszym wkładem autora było zastąpienie nawiasów trójkątnych kwadratowymi.
Podobnie jak wspomniane wcześniej języki jego definicja oparta jest na przykładach zapytań.
3.3.7
XML-GL
Strona 29
Język zapytań dla XML oparty na podejściu stosowym
XML-GL ([21]) jest to graficzny język pozwalający na reprezentowanie: dokumentów XML,
DTD, zapytań XML.
Składnia XML-GL oparta jest na grafach, które zdaniem twórców są najbardziej intuicyjną i naturalną
reprezentacją dokumentów XML. Ta sama reprezentacja, z dodatkową notacją używana jest do
reprezentowania zapytań.
Przykładowe zapytanie pobrane ze strony twórców XML-GL, zwracające zamówienia wysłane do Los
Angeles oraz zawierające książkę zatytułowaną „Introduction to XML”.
Po lewej stronie znajduje się warunek, natomiast po prawej elementy, które mają być zwrócone jako
wynik zapytania.
Graficzne zapytanie, w prototypowym systemie, przekształcane jest na zapytanie w języku LOREL
lub XQL, które następnie jest wykonywane.
Podejście to wydaje się być ciekawym pomysłem do tworzenia szablonów zapytań mogących pomóc
mniej doświadczonym użytkownikom. Jednakże bardziej skomplikowane zapytania (np. ze
złączeniami) mogą stać się nieczytelne dla użytkownika.
3.3.8
WebOQL
WebOQL ([23]) jest językiem funkcyjnym, opartym na wcześniejszym WebSQL. Składania
WebOQL jest optycznie podobna do składni języka SQL. Wewnętrzna reprezentacja dokumentów
XML ma postać hiperdrzewa.
Przykładowe zapytanie (pobrane ze strony [24]), wyszukujące wszystkie publikacje autorstwa
„Smitha”:
[Tag:"result" /
select y
from
x
"publications"],
in
browse("file:pubs.xml")
Strona 30
via
^*[tag
=
Język zapytań dla XML oparty na podejściu stosowym
y in x',
z in y'
where z.tag = "author" and z.value ~ "Smith"
]
Zapytanie wydaje się być stosunkowo proste i czytelne, prawie pozbawione lukru syntaktycznego,
powszechnego w wielu innych rozwiązaniach (W3C). Niestety dokumenty dotyczące tego języka na
stronie autora są uszkodzone, w związku z czym niemożliwe jest bliższe zapoznanie się z tym
językiem zapytań.
3.4. Próba oceny przydatności istniejących rozwiązań
3.4.1
SQL
Zalety:
 Język popularny, rozwiązanie oparte na SQL może zyskać łatwą akceptację środowiska,
Wady:
 Nieprzystosowanie języka do obsługi wyrażeń ścieżkowych, atrybutów złożonych i
powtarzalnych oraz innych elementów, które powinny charakteryzować nowoczesny język
zapytań, zwłaszcza przeznaczony do obsługi XML.
 Brak możliwości ortogonalnego kombinowania operatorów.
Ocena przydatności:
 Dosyć wątpliwa zaleta nie równoważy dyskwalifikujących to rozwiązanie wad.
3.4.2
Rozszerzenie SQL o brakujące elementy
Zalety:
 Język popularny, rozwiązanie oparte na SQL może zyskać łatwą akceptację środowiska,
Wady:
 Rozszerzenie SQL o wszystkie brakujące elementy pozostawi z tego języka jedynie
drugorzędne elementy, takie jak np. wygląd niektórych konstrukcji.
Ocena przydatności:
 Uważamy podążanie tą ścieżką za niezbyt sensowne – prowadzi ona w ślepy zaułek.
3.4.3
OQL
Zalety:
 Język jest zaakceptowanym standardem,
 Ma wszystkie niezbędne cechy, potrzebne językowi zapytań przeznaczonemu do pracy z
XML.
Wady:
 Optymalizacja zapytań może być trudna,
Ocena przydatności:
 Rozwiązanie to może być w miarę rozsądne i godne rozważenia. Problemem tu może być
jednak pewna nadmiarowość języka – przy przetwarzaniu XML nie będzie konieczne np.
wywoływanie metod obiektów, co oznacza, że zaimplementowany będzie tylko pewien
podzbiór OQL.
3.4.4
SBQL
Zalety:
Strona 31
Język zapytań dla XML oparty na podejściu stosowym
 Ma wszystkie niezbędne cechy, potrzebne językowi zapytań przeznaczonemu do pracy z
XML,
 Dobrze zdefiniowana semantyka,
 Łatwy w oprogramowaniu i rozbudowie,
 Znane są sposoby optymalizacji zapytań,
Wady:
 Nie jest powszechnie zaakceptowanym standardem.
Ocena przydatności:
 Uważamy ten język za najrozsądniejszy wybór. Jako że definicja języka w przypadku SBQL
zajmuje się przede wszystkim jego semantyką i sposobem działania, nie zaś drugorzędnymi
(według Autorów) cechami takimi jak słowa kluczowe, możliwe będzie zarówno jego łatwe
zaprogramowanie, jak i dopasowanie słów kluczowych do przyjętych obecnie na świecie
standardów (np. Select … From … Where …).
3.4.5
Omówione propozycje języków dla XML
Zalety:
 Trudno znaleźć






Wady:
Zazwyczaj dość dziwna składnia
Nawet najprostsze zapytania są wyrażane w bardzo skomplikowany sposób
Ograniczone możliwości
Trudna rozbudowa
Pozbawione sensownych podstaw teoretycznych
Trudna optymalizacja zapytań
Ocena przydatności:
 Istniejące języki zapytań dla XML wydają się być produktami o wątpliwej przydatności i
nieprzyjemnymi zarówno w implementacji, jak i w użytkowaniu.
3.4.6
Potencjalny (nieistniejący) język stworzony zgodnie z XML Query Requirements
Zalety:
 Zgodność z propozycjami jednego z bardziej znanych konsorcjów
Wady:
 Spora część z wymagań wydaje się być co najmniej trudna do pogodzenia ze sobą
 Implementacja wszystkich propozycji spowodowałaby stworzenie mało użytecznego i
wygodnego języka, praktycznie niemożliwego do przyswojenia przez człowieka
 Część wymagań (jak obsługa kolekcji) nie ma związku z innymi istniejącymi na dzień
dzisiejszy normami i standardami W3C
 Część wymagań (jak niezależność od protokołów sieciowych) nie ma żadnego związku z
językami zapytań jako takimi – są to kwestie czysto techniczne
Ocena przydatności:
 Zalecenia W3C dotyczące języków zapytań dla XML osiągnęły stan, w którym sugerowanie
się nimi byłoby poważnym błędem, prowadzącym do stworzenia nieużytecznego narzędzia.
Poważne obawy budzi również niezrozumienie terminologii fachowej przez autorów
dokumentów W3C (jak choćby w przypadku dokumentu „XQuery 1.0 Formal Semantics”,
którego treść ma niewiele wspólnego z tym, co rozumiemy jako semantykę języka).
3.5. Proponowane rozwiązanie
Ze względu na łatwość implementacji i dobre dopasowanie do naszych potrzeb, wybieramy do
realizacji SBQL. Inne cechy tego języka – takie jak łatwa rozbudowa (nawet do poziomu języka
programowania zintegrowanego z językiem zapytań) oraz dobrze określona semantyka powodują, iż
Strona 32
Język zapytań dla XML oparty na podejściu stosowym
jest on godnym uwagi językiem. Ponadto w razie potrzeby możliwe jest opracowanie (w ramach
dalszych prac rozwojowych) translatora zapytań z innego języka zapytań do SBQL (w drugą stronę
mogłoby to być trudne lub niemożliwe).
Strona 33
Język zapytań dla XML oparty na podejściu stosowym
III. Narzędzia i teorie zastosowane podczas realizacji pracy
Niniejszy rozdział stanowi próbę przedstawienia czytelnikowi narzędzi i teorii zastosowanych
podczas realizacji pracy. Przedstawienie to powinno pokazać czytelnikowi zasadność dokonanych
wyborów w tym zakresie.
4. Język Java
Język Java został przez autorów wybrany jako język, w którym stworzona będzie prototypowa
implementacja języka zapytań. Poniższy opis języka Java opiera się na materiałach firmy SUN
Microsystems ([27]), jak również doświadczeniu autorów.
4.1. Co to jest Java
Język Java powstał jako część projektu, którego celem było stworzenie zaawansowanego
oprogramowania dla heterogenicznych środowisk. W momencie rozpoczęcia projektu dominującym
językiem programowania był język C++, posiadający jednak pewne wady. Chociaż projekt oraz
architektura Javy bazują głównie na języku C++, twórcy brali także pomysły z takich językach jak
SmallTalk, Eiffel oraz Cedar/Mesa. W wyniku tych działań powstał język nadający się zarówno do
tworzenia bezpiecznych aplikacji rozproszonych działających w heterogenicznych środowiskach, jak i
praktycznie każdego innego rodzaju oprogramowania (może za wyjątkiem oprogramowania
systemowego).
Główne założenie języka Java to:
 Prostota – dla rozpoczęcie pracy z językiem Java nie jest wymagana duża liczba szkoleń,
podstawowe założenia języka są proste, przez co programista może być efektywny
praktycznie od początku pracy z Java
 Obiektowość – Java jest zorientowana obiektowo, a co więcej praktycznie wymusza
programowanie obiektowe. Obiektowość Javy opiera się na koncepcjach zaprezentowanych w
językach Eiffel, SmallTalk, C++, Objective C. Trudne jest określenie jakości modelu
obiektowego języka Java, ponieważ opinie są bardzo rozbieżne. Naszym zdaniem jest on
zdecydowanie lepszy niż model używany w języku C++, co do innych języków
wymienionych w tym punkcie to magistranci nie mają wystarczających doświadczeń.
 Jako, że najbardziej popularnym językiem w czasach tworzenia Javy był język C++, składnia
języka Java jest bardzo zbliżona do składni C++. Pozwala to na łatwą migrację programistów
z C++ do Javy.
 Bezpieczeństwo – twórcy języka Java położyli bardzo silny nacisk na kwestie bezpieczeństwa.
Było to spowodowane samymi założeniami Javy – język mający działać w środowisku
rozproszonym nie może pomijać kwestii bezpieczeństwa. Trudno jest stwierdzić na ile udane
jest rozwiązanie przyjęte w języku Java, warto tylko zauważyć, że Java jest obecnie
dominującym językiem oprogramowania używanym w Internecie i pomimo pewnych błędów
jest uznawana jako język bezpieczny.
 Uproszczone zarządzanie pamięcią – bardzo proste tworzenie obiektów, automatyczne
odśmiecanie pamięci, co umożliwia uniknięcie wielu błędów.
 Przenośność – kod Javy ma być uruchomiany na wielu platformach, bez potrzeby rekompilacji,
co więcej zarówno rozmiary zmiennych jak i działania operatorów są niezależne od platformy
sprzętowej i operacyjnej.
Strona 34
Język zapytań dla XML oparty na podejściu stosowym
W związku z powyższymi wymaganiami język Java jest językiem interpretowanym,
prekompilowanym. Kod języka Java kompilowany jest do kodu pośredniego tzw. „bytecode”, który
następnie jest interpretowany przez maszynę wirtualną Javy.
W tym miejscu warto zaznaczyć, że pomysł z prekompilacją do kodu pośredniego nie był wcale
pomysłem nowatorskim (mimo starań marketingu firmy SUN, żeby wszystkich o tym przekonać), lecz
był od dawna wykorzystywany w kompilatorach.
Wynikiem tego podejścia jest pewien narzut wydajnościowy związany z potrzebą uruchamiania
maszyny wirtualnej. Z drugiej strony interpretacja kodu pozwala na zastosowanie optymalizacji
wykonywanych podczas działania programu, znacznie zwiększających wydajność aplikacji. Dzięki
tym optymalizacjom Java w dzisiejszych czasach ustępuje głównie aplikacjom zawierającym znaczne
ilości grafiki, a w przypadku serwerów aplikacyjnych posiada wydajność porównywalną z językiem
C++.
Od momentu uzyskania dojrzałości przez język Java (za moment uzyskania dojrzałości możemy
uznać wprowadzenie tzw. Java 2) zyskał on bardzo dużą popularność, głównie w środowisku
biznesowym. Język ten używany jest zarówno do tworzenia serwisów WWW, aplikacji internetowych,
złożonych aplikacji wielowarstwowych jak również prostych aplikacji. W ostatnich latach Java
zyskała bardzo duży udział w oprogramowaniu urządzeń przenośnych o niewielkich zasobach (Micro
Java).
4.2. Java a inne języki programowania
Poniższy punkt ukazuje podstawowe cechy języka Java w porównaniu do języka najbardziej
zbliżonego do Javy a mianowicie C++
Główne cech języka Java:
 Wszystkie typy danych za wyjątkiem typów prostych to obiekty.
 Tablice w języku Java są to również obiekty.
 Zarządzanie pamięcią – w porównaniu do C++ zdecydowanie uproszczono zarządzanie
pamięcią. Istnieje tylko operator tworzenia obiektu, a system automatycznie usuwa obiekt z
pamięci, gdy obiekt nie jest już dłużej używany. Model zarządzania pamięcią oparty jest na
referencjach do obiektów. W momencie, gdy liczba referencji odnosząca się do danego
obiektu wynosi 0, obiekt może być usunięty z pamięci. Istotną wadą tego podejścia jest to, że
w momencie powstania cyklu obiekty mogą nie być usuwane z pamięci.
 Wielowątkowość – Java posiada wbudowane wsparcie dla wątków, co zdecydowanie upraszcza
tworzenie i zarządzanie wątkami.
 Java zawiera zarówno statyczną (w czasie kompilacji) jak i dynamiczną kontrolę typów.
 Wszystkie klasy Javy mają wspólny korzeń w hierarchii dziedziczenia. Z powodu braku
wielokrotnego dziedziczenia, hierarchia klas w języku Java tworzy drzewo. Podejście to
zdecydowanie ułatwia operację na kolekcjach obiektów, lecz niestety może prowadzić także
do pewnych błędów wynikających z błędnego rzutowania. Optymalne byłoby wprowadzenie
do Javy możliwości tworzenia kolekcji opartych na wzorcach (jak w C++).
Rzeczy istniejące w C++ a niewprowadzone do języka Java
 Usunięto unie oraz struktury – efekt uzyskiwany za pomocą unii i struktur jest równie łatwo
osiągalny za pomocą klas.
 Brak funkcji – w związku z tym, że Java jest językiem obiektowym, a funkcje pochodzą z
programowania proceduralnego, Java nie posiada funkcji, a autorzy słusznie zauważyli, że
rzeczy osiągalne za pomocą funkcji są równie łatwo osiągalne za pomocą klas i metod.
Strona 35
Język zapytań dla XML oparty na podejściu stosowym
 Brak wielokrotnego dziedziczenia – z powodu znacznych problemów z wielokrotnym
dziedziczeniem, z języka Java usunięto tę możliwość. W zamian stworzono koncepcję
interfejsów. Interfejs nie jest definicją klasy, lecz definicją metod, które dane klasa
implementuje. Klasa może implementować wiele interfejsów, ale dziedziczy zawsze tylko po
jednej klasie.
 Usunięto instrukcję „goto” – zamiast instrukcji „goto” wprowadzono instrukcje „break” oraz
„continue”, które zapewniają większość funkcjonalności związanej z instrukcją „goto”.
Usunięcie „goto” uprościło język, lecz przede wszystkim pozbawiło programisty robienia
wielu „fascynujących” błędów.
 Brak przeciążania operatorów – twórcy Javy uznali, że przeciążania operatorów może być łatwo
zastąpione poprzez klasy i metody. Jedyną wadą takiego podejścia jest wydłużenie zapisu
instrukcji. Zaletą jest uproszczenie kodu a także zwiększanie czytelności (programista nie
musi się zastanawiać, czy dany operator był przeciążony.
 Brak automatycznej konwersji typów – w momencie, gdy konwersja typu prowadzi do utraty
informacji, w języku Java konieczna jest jawna konwersja typów.
 Brak wskaźników – w Javie usunięto wskaźniki uważając, że wskaźniki pomagają programiście
w pisaniu kodu zawierającego znaczne ilości błędów, które zazwyczaj są bardzo trudne do
wykrycia. Wszystkie operacje w języku C++ wykonywane na wskaźnikach można w Javie
wykonać na obiektach. Operacje wymagające wskaźników lub struktur w C można wykonać
za pomocą obiektów i tablic obiektów. Zamiast arytmetyki wskaźnikowej na tablicach, dostęp
do tablic w Javie jest uzyskiwany za pomocą indeksów liczbowych. Pomaga to na
sprawdzania poprawności dostępu do tablic podczas działania programu i zapobiega
„wychodzeniu” poza tablicą, co było częstym błędem w C. Wadą podejścia zastosowanego w
Javie jest pewne spowolnienia operacji wykonywanych w C na wskaźnikach (głównie chodzi
o operacje graficzne).
4.3. Java a XML
Zarówno Java jak i XML mają pewne wspólne cechy wskazujące, dlaczego właśnie Java jest
bardzo dobrym narzędziem do obsługi XML:
 Zarówno XML jak i Java są w pełni darmowe.
 XML jak i Java są całkowicie niezależne od platformy systemowej i sprzętowej ( w przypadku
Javy ograniczeniem jest ilość działających maszyn wirtualnych dla danego środowiska)
W chwili obecnej istnieją narzędzia do języka Java wspierające praktycznie wszystkie obowiązujące
standardy przetwarzania dokumentów XML (SAX, DOM, JDOM). Narzędzia te są nieustannie
rozwijane, aby nadążyć za ciągłymi zmianami zachodzącymi w XML.
4.4. Dlaczego właśnie Java?
Istnieje kilka powodów, dla których zdecydowaliśmy się na wybranie Javy jako języka
implementacyjnego:
 Magistranci posiadają doświadczenie w programowaniu w języku Java.
 Język Java dzięki swojej strukturze pozwala uniknąć wielu błędów, a także pozwala na łatwe
wykrywanie i usuwanie błędów już istniejących
 W dniu dzisiejszym istnieją narzędzie dla języka Java umożliwiające obsługę dokumentów
XML zgodnie z istniejącymi standardami.
 Poprzez połączenie Javy i XML uzyskujemy narzędzie działające bez dodatkowych nakładów
na wielu platformach sprzętowych i systemowych.
Strona 36
Język zapytań dla XML oparty na podejściu stosowym
5.
Parser XERCES i standard DOM
Oczywiste jest, iż aby możliwe było wykonanie jakiegokolwiek zapytania na dokumencie
XML, najpierw należy uzyskać dostęp do informacji w nim zawartych. Jako celem tej pracy nie jest
implementacja parsera XML lub API służącego do dostępu do dokumentu, zdecydowaliśmy się
skorzystać z gotowych narzędzi i standardów przedstawionych poniżej.
5.1. Standard DOM
Wyspecyfikowany przez W3C standard DOM (Document Object Model) jest interfejsem
pozwalającym na dynamiczny dostęp i modyfikację zawartości, struktury i stylu dokumentu. Interfejsy
należące do tego standardu zdefiniowane są w języku IDL.
DOM przedstawia dokument w formie lasu (zbioru drzew). Każdy dokument zawiera:
 0 lub 1 węzeł typu dokumentu (doctype node),
 1 węzeł zawartości dokumentu (document node),
 dowolną ilość węzłów z komentarzami i instrukcjami przetwarzania.
Każdy z węzłów dokumentu może zawierać dowolną liczbę węzłów potomnych. Węzły
potomne mogą być:
 wartościami tekstowymi (reprezentującymi tekst umieszczony pomiędzy znacznikami),
 atrybutami danego znacznika,
 węzłami reprezentującymi zagnieżdzone znaczniki,
 innymi węzłami (np. referencjami do encji XML).
Dzięki takiemu sposobowi reprezentacji dokumentów, standard DOM jest doskonałym
rozwiązaniem w sytuacji, gdy dla programisty istotna jest nie kolejność występowania poszczególnych
informacji w dokumencie, lecz łatwość dostępu do informacji w nim zawartych – takich właśnie jak
języki zapytań. Wadą DOM jest konieczność (nie określona w standardzie, ale występująca
faktycznie) przechowywania całej struktury dokumentu XML w pamięci jednocześnie. Należy jednak
zauważyć, że rzadko spotyka się dokumenty XML o rozmiarach istotnie przekraczających rozmiary
pamięci operacyjnej współczesnych komputerów, w związku z czym problem ten dotyczy co najwyżej
urządzeń przenośnych (typu palmtop lub telefon komórkowy), lub innych urządzeń z niewielką
pamięcią operacyjną.
5.1.1
Poziomy DOM
Standard DOM określa tzw. Poziomy (Levels), zawierające określony zakres funkcjonalności w
zakresie przetwarzania dokumentów XML. Każdy kolejny poziom oferuje więcej możliwości
programiście (równocześnie jednak stawiając większe wymagania przed autorami parserów). W
chwili obecnej zdefiniowane4 są 3 poziomy DOM – od najbardziej podstawowego Level 1 do
najbardziej zaawansowanego Level 3. Wytworzone w ramach pracy magisterskiej oprogramowanie
wymaga do działania parsera implementującego DOM Level 1.
5.1.2
Porównanie z innymi standardami i uzasadnienie wyboru
Poza standardem DOM często spotykane są jeszcze dwa API implementowane przez parsery
XML: SAX i JDOM.
Część z dokumentów specyfikujących poszczególne poziomy jest już zamknięta, część na etapie W3C
Recommendation, pozostałe są jeszcze w opracowaniu, ale część funkcjonalności już jest implementowana przez
producentów narzędzi.
4
Strona 37
Język zapytań dla XML oparty na podejściu stosowym
SAX (Standard API for XML Processing) jest interfejsem stosunkowo niskiego poziomu,
umożliwiającym uzyskanie sekwencyjnego dostępu do zawartości dokumentu XML. W
przeciwieństwie do DOM i JDOM, które tworzą reprezentację struktury dokumentu w pamięci, SAX
wymaga od programisty implementacji klasy obsługującej zdarzenia, jakie mogą zajść podczas
parsowania dokumentu XML (zdarzeniem może być np. napotkanie znacznika lub tekstu). Metody tej
klasy są następnie wywoływane przez parser SAX. Daje to programiście znacznie większą dowolność,
jeśli chodzi o sposób obsługi dokumentu XML, wymaga jednak znacznie większego nakładu pracy.
API to nadaje się doskonale do implementacji narzędzi, dla których przetwarzanie sekwencyjne jest
bardziej naturalne (przykładem mogą być procesory XSLT).
JDOM (Java Document Object Model) jest w swoich założeniach bardzo zbliżony do DOM,
jednak stworzony został z myślą o języku Java. Umożliwiło to jego twórcom wprowadzenie szeregu
rozwiązań ułatwiających pracę programistom korzystającym z tego języka, jednocześnie jednak
czyniąc JDOM nieprzenoszalnym. Nie uważamy, aby ułatwienia oferowane przez JDOM były
znaczące na tyle, żeby rezygnować z zastosowania bardziej popularnego (i będącego standardem
promowanym przez W3C) rozwiązania.
5.2. Parser XERCES
W chwili obecnej na rynku znajduje się duża ilość parserów XML implementujących standard
DOM. Wybrany przez nas parser XERCES będący produktem Apache Software Foundation ([10]).
Wybór ten został podyktowany wcześniejszymi doświadczeniami magistrantów, zarówno z innymi
produktami Apache Software Foundation, jak i z parserem XERCES.
Parser ten implementuje DOM Level 1 i 2, jak również SAX Version 1 i 2 oraz XML Schema
Recommendation 1.0. Umożliwia walidację dokumentów XML na podstawie DTD lub XML Schema
– zarówno podczas wczytywania dokumentu, jak i podczas wprowadzania zmian/tworzenia nowego
dokumentu.
6.
Narzędzia wspomagające tworzenie parserów
Aby przetwarzać zapytania, konieczne jest ich sparsowanie. Pierwsze wersje języka zapytań
zaimplementowane w ramach prac wykorzystywały parser zstępujący typu LL(1), ręcznie
zakodowany metodą zejść rekurencyjnych. Parser ten jednak był zbyt trudny w pielęgnacji, zwłaszcza
biorąc pod uwagę znaczne zmiany zachodzące w definicji języka na wczesnym etapie prac. Ze
względu na to, a także na możliwość uproszczenia składni języka przy zmianie typu parsera na LR(1)
(lub jeden z typów pochodnych), zdecydowaliśmy się na ten krok. Jako że istnieją wygodne narzędzia
do tworzenia parserów, zdecydowaliśmy się na ich użycie.
W porównaniu z językami takimi jak C/C++, istnieje stosunkowo niewiele generatorów
analizatorów leksykalnych i parserów generujących kod w języku Java. Odnośniki do większości z
nich można znaleźć na stronie [11]. Z dostępnych narzędzi wybrane zostały dwa.
6.1. JFLEX
JFLEX jest generatorem analizatorów leksykalnych autorstwa Gerwina Kleina. Został
zaimplementowany w całości w języku Java, generowany kod jest w tym samym języku. JFLEX
przyjmuje specyfikację leksykalną w formacie bardzo zbliżonym do tej tworzonej dla bardziej
popularnych narzędzi do C/C++ (takich jak LEX lub FLEX). Jest w stanie wygenerować analizatory
obsługujące klasyczny 7 lub 8 bitowy kod ASCII, jak i analizatory obsługujące standard UNICODE.
Możliwość ta jest bardzo istotna w przypadku implementacji języka zapytań dla XML, ze względu na
możliwość wystąpienia np. znaków diaktrycznych w zapytaniach.
Strona 38
Język zapytań dla XML oparty na podejściu stosowym
JFLEX został zaprojektowany z myślą o jak najłatwiejszej integracji z darmowymi
generatorami parserów: CUP i BYacc/J. Wskutek tego staje się on naturalnym wyborem w sytuacji,
gdy planowane jest użycie jednego z tych dwóch narzędzi.
W zależności od rozmiaru specyfikacji (i utworzonego na jej podstawie automatu) możliwe jest
wykorzystanie jednej z trzech metod generacji kodu wynikowego – z użyciem nie skompresowanej
lub skompresowanej (metoda domyślna) tablicy przejść lub też utworzenia zagnieżdżonych instrukcji
wyboru (switch). Wady i zalety poszczególnych metod opisane są szczegółowo w instrukcji JFLEX
[12], podobnie jak różnice pomiędzy składnią JFLEX i FLEX oraz metody integracji z narzędziami
CUP i BYacc/J.
6.2. CUP
CUP jest generatorem parserów LALR autorstwa Scotta Hudsona, rozszerzonym następnie
przez Franka Flannery, obecnie zaś pielęgnowanym przez C. Scotta Ananiana. Został napisany i
generuje kod w języku Java. Przyjmowana przez CUP specyfikacja parsera jest bardzo zbliżona do
używanej przez bardzo popularny generator parserów YACC, i opisana jest w dokumentacji CUP
([13]).
CUP oferuje programistom pewne ułatwienia – na przykład możliwość zdefiniowania priorytetu
i sposobu łączności (lewo- lub prawo- stronnej) dla każdego z operatorów.
7. Teoria stosowych języków zapytań
Autorzy zdając sobie sprawę, iż język zapytań powinien być zbudowany na mocnych
podstawach teoretycznych. Po przeanalizowaniu istniejących rozwiązań w zakresie języków zapytań,
autorzy zdecydowali się na najbardziej relewantne do problemu podejście stosowe zaproponowane
przez Kazimierza Subietę.
Informacje dotyczące podejścia stosowego w językach programowania oparte są na: [3], [28],
[29]. Informacje dotyczące podejścia stosowego w językach zapytań oparte są na: [3].
7.1. Podejście stosowe
Idea podejścia stosowego zagościła w informatyce w latach 60. Podstawową cechą tego
podejścia jest istnienie stosu zawierającego informacje o środowisku działania programu. Pojęcie
środowiska działania programu według Kazimierza Subiety ([3]) oznacza „zestaw wszystkich bytów
programistycznych czasu wykonania (zmiennych, stałych, obiektów, funkcji, procedur, typów, klas,
itd.), które są dostępne dla programisty w danym punkcie sterowania programu”. Takie podejście do
środowiska działania programu znajduje wyraźne odzwierciedlenie w większości języków
programowanie, w których to stos wołań (ang. call stack), lub stos środowiskowy odgrywa kluczową
rolę. Podejście stosowe pozwala na traktowanie środowiska jako struktury zmiennej w czasie działania
programu. W związku z zastosowaniem stosów w językach programowania opisane zostaną zalety
tego podejścia w kontekście języków programowania.
W większości języków programowania zachowywane są następujące zasady zarządzania
środowiskiem sterowania programu ([3]):
 Środowisko lokalne procedury posiada priorytet względem środowiska globalnego. Ta
zasada pozwala programiście na pomijanie stanu środowiska globalnego podczas
pisania procedur.
 Programista może wywoływać z procedury inne procedury lub funkcje. Szczególną
wersją tej zasady są wywołania rekurencyjne.
Strona 39
Język zapytań dla XML oparty na podejściu stosowym
 Programista podczas tworzenia procedury nie może w niej uwzględniać elementów
środowiska wykonania, które dopiero się w niej pojawią.
Zasady te umożliwiają tworzenie programów efektywniej, oraz z mniejszą ilością błędów.
W wielu językach, takich jak C, Pascal, Java zmienne lokalne są usuwane w momencie zakończenia
działania funkcji (metody), oraz ponieważ funkcja(metoda) zwraca wynik po otrzymaniu wyników od
wszystkich funkcji(metod), które sama wywołała, możemy stwierdzić, że takie wywołanie zachowuje
się zgodnie z zasadą LIFO(last in – first out), która dokładanie odpowiada zasadzie działania stosu.
W przypadku języków takich jak ML, Schema, gdy istnieją w zagnieżdżone funkcje wraz z funkcjami
zwracającymi funkcje występuje potrzeba istnienia zmiennej lokalnej dłużej niż wywołanie funkcji, w
której ta zmienna się znajduje. W tym przypadku użycie samego stosu nie wystarcza i potrzebne są
dodatkowe zabiegi w celu uzyskanie tej funkcjonalności.
Stos środowiskowy w językach programowania spełnia następujące funkcji:
 Przechowywanie zmiennych lokalnych funkcji (procedury, metody)
 Przechowywanie parametrów funkcji (procedury, metody)
 Przechowywanie adresu powrotu z funkcji – adres, pod który przechodzi sterowanie w
momencie zakończenia procedury
 Przechowywania wartości zwracanych przez funkcję (metodę, procedurę)
 Kontrolowanie zakresu nazw zmiennych a także wiązanie nazw zmiennych.
W celu łatwiejszego zarządzania stosem środowiskowym, dzielony jest one na części zwane ramkami
(sekcjami). Pojedyncza ramka, zwana także rekordem aktywacji jest to obszar stosu, w którym
znajdują się zmienne lokalne, parametry, wartość zwracana przez funkcję. Nowa ramka pojawia się na
wierzchołku stosu w momencie wywołania procedury (metody, funkcji). Po zakończeniu wywołania
funkcji ramka jest usuwana z wierzchołka stosu.
Aktualna metoda m1 wywołuje metodę m2
Wartość zwracana m2
Aktualne parametry
m2
Zapamiętany stan
procesora
Dane lokalne dla m2
Wartość zwracana m1
Wartość
zwracana m2
m1
Dane tymczasowe
Wartość zwracana m1
Aktualne parametry
m1
Aktualne parametry
m1
Aktualne parametry
m1
Zapamiętany stan
procesora
Zapamiętany stan
procesora
Zapamiętany stan
procesora
Dane lokalne dla m1
Dane lokalne dla m1
Dane lokalne dla m1
Poprzednie
ramki m1
Dane tymczasowe
(sekcje)
Poprzednie
ramki m1
Dane tymczasowe
(sekcje)
Poprzednie
ramki m1
Dane tymczasowe
(sekcje)
Na podstawie [28]
Strona 40
Język zapytań dla XML oparty na podejściu stosowym
Taka konstrukcja stosu pozwala na wywoływanie procedur z wnętrza procedur a także na rekurencje,
ponieważ każde wywołanie procedury (metody, funkcji) posiada własne zmienne lokalne, parametry
itp. Jednocześnie w związku z kontrolą zakresu nazw, wiązanie zmiennych następuje na właściwym
poziomie, co jest sprawą kluczową (szczególnie przy rekurencji gdzie nazwy zmiennych mamy
identyczne dla funkcji wywoływanej i wywołującej).
Wiązanie jest to zastępowanie nazw występujących w tekście programu na byty programistyczne
czasu wykonania, np. na adresy RAM, identyfikatory obiektów, adresy startowe procedur, itd. ([3])
Wiązanie nazw zmiennej jest to zastępowanie tekstu oznaczającego daną zmienną występującego w
kodzie programu na adres w pamięci gdzie przechowywana jest wartość tej zmiennej.
Możemy wyróżnić wiązanie statyczne (wczesne) oraz dynamiczne (późne). Wiązanie statyczne
odbywa się w trakcie kompilacji, dynamiczne zaś dopiero w momencie działania programu.
Wiązanie dynamiczne na stosie środowiskowym posiada bardzo proste zasady działania:
 Rozpoczynamy poszukiwanie od wierzchołka stosu
 Jeżeli nie znaleziono szukanej wartości przechodzimy do ramki znajdującej się poniżej.
 Proces ten kontynuujemy, do momentu znalezienia szukanej wartości
 W przypadku nie znalezienie wartości przeszukujemy zmienne globalne, dołączane biblioteki,
zmienne systemowe itp.
Podczas wiązania może się okazać, że należy pominąć niektóre sekcje stosu środowiskowego.
Spowodowane jest to tym, środowisko lokalne procedury (metody, funkcji) nie powinno być widoczne
w drugiej procedurze (metodzie, funkcji). Także w językach obiektowych bądź wprowadzających
moduły może zaistnieć potrzeba pomijania sekcji. Należy pominąć także sekcje związane z modułami,
klasami innymi niż te odpowiadające aktualnie wykonywanej procedurze (metodzie, funkcji).
p1 woła p2. Procedura p1 znajduje się wewnątrz modułu m1, zaś procedura p2 znajduje
się wewnątrz modułu m2. Wykonywany jest blok b wewnątrz p2.
Wierzchołek
stosu Zmienne zadeklarowane wewnątrz bloku b
Kolejność
poszukiwani
a zmiennej x
Zmienne i parametry procedury p2
Prywatne i publiczne własności modułu m2
Własności importowane przez moduł m2
Zmienne i parametry procedury p1
Prywatne i publiczne wartości modułu m1
Własności importowane przez moduł m1
.....
Referencje do wszystkich modułów
Referencje do własności środowiska globalnego
Dół stosu
Algorytm wiązania nazw (na podstawie [3])
Podejścia stosowego w językach programowania gwarantuje następujące właściwości:
 Programiści nie mają dostępu do wnętrza wywoływanych procedur (metod, funkcji)
 Brak potrzeby uzgadniania lokalnych nazw zmiennych w różnych procedurach (każda
procedura ma środowisko lokalne, które ma pierwszeństwo w przypadku wiązania
zmiennych).
Strona 41
Język zapytań dla XML oparty na podejściu stosowym
 Możliwość wywoływania procedur z wnętrza procedur, wraz z wywoływaniami
rekurencyjnymi. Możliwe jest to dzięki istnieniu lokalnego środowiska każdego wywołania
procedury.
7.2. Podejście stosowe a języki zapytań
W literaturze istnieje kilka punktów widzenia na to, jaka jest istota języka zapytań. Jednym z
nich jest traktowanie języków zapytań jako wyrażeń wysokiego poziomu zintegrowanych z językiem
programowania. Jest to koncepcja o tyle odmienna od pozostałych w szczególności od obecnie
najbardziej popularnej (zanurzania języka zapytań w istniejącym języku programowania), ponieważ
zakłada stworzenie całkowicie nowego języka, którego integralną częścią będą zapytania.
Rozwiązanie to pozwala na bardzo efektywne tworzenie aplikacji, ponieważ programista nie musi
poznawać wielu języków (programowania i zapytań) do tworzenia logiki aplikacji, oraz komunikacji z
bazą danych. Przykładem takiego języka jest PL/SQL firmy Oracle. Niestety obecne tego typu
rozwiązania są zazwyczaj nacechowane ograniczeniami, brakiem uniwersalności oraz innymi wadami.
Zakładając takie podejście do języka zapytań można zauważyć, że podejście stosowe jest
praktycznie idealne do stworzenia języka zapytań, zawierającego konstrukcje istniejące w językach
programowania. Jako pierwszy zauważył to Kazimierz Subieta, który opracował teorię podejścia
stosowego dla języków zapytań a także opracował działający prototyp takiego języka (LOQIS
powstały w latach 1990-1991).
Aby dostosować podejście stosowe, używane do tej pory głównie w językach programowania
do specyfiki języka zapytań należy poczynić szereg założeń, co do stosu środowisk.
Podstawowe założenia stosu środowisk to:
 Traktować w jednakowy sposób kolekcie i dane indywidualne
 Stos nie będzie zawierał wartości zmiennych, obiektów. Spowodowane jest to faktem, iż w
zakładanym podejściu odwołania do tego samego obiektu, mogą pojawiać się w wielu
miejscach stosu. Na stosie będą przechowywane tylko zbiory „binderów”.
 Stos będzie podzielony na sekcje zawierające pewne informacje o środowisku wykonania.
 Na dole stosu znajdować się będą sekcje globalne. Sekcje globalne to: baza danych, zmienne
środowiskowe systemu komputerowego, zmienne globalne, itp.
 Stos będzie w jednorodny sposób traktował zarówno dane ulotne jak i trwałe (znajdujące się w
bazie danych)
Jak już wspomniano wcześniej na stosie występować będą bindery. „Binder jest parą <n, x>,
gdzie n jest zewnętrzną nazwą (nazwą zmiennej, stałej, obiektu, funkcji, perspektywy, procedury,
metody, itd.), zaś x jest bytem czasu wykonania (zwykle referencją do obiektu).” ([3]). Bindery są
używane do wiązania nazw występujących w zapytaniu na byty czasu wykonania.
Nowa sekcja na stosie środowisk tworzona jest we wszystkich przypadkach określonych dla języków
programowania, oraz dla pewnych operatorów zwanych „nie-algebraicznymi”. Zmiana ta stanowi
podstawową zmianę w stosunku do standardowego podejścia stosowego i warunkowana jest
właściwościami języków zapytań. Operatory „nie-algebraiczne” swoim działaniem na stosie
przypominają bloki programów. Operatory „nie-algebraiczne” są to operatory niedające sprowadzić
się w prosty sposób do algebry. Określone są następujące operatory „nie-algebraiczne” określone dla
podejścia stosowego:
 Where – operator selekcji
 „.” – operator kropki jest to operator projekcji, nawigacji
 Operator zależnego złączenia
 Operator sortowania
Strona 42
Język zapytań dla XML oparty na podejściu stosowym
 Kwantyfikatory
Równie istotne jak zdefiniowanie właściwości stosu środowisk jest określenie „Stanu”. Jako „Stan” w
podejściu stosowym rozumiemy stany wszystkich obiektów znajdujących się w składzie obiektów,
oraz stan stosu środowisk.
Zapytania nigdy nie zwracają obiektów a jedynie referencje do obiektów, lub struktury złożone z
referencji, wartości elementarnych i nazw.
Podobnie jak w przypadku języków programowania także w językach zapytań trzeba określić zasady
wiązania nazw. Podobnie jak w językach programowanie wyszukiwanie zaczynamy od wierzchołka
stosu. Wyszukiwanie kontynuujemy aż do znalezienia sekcji, w której znajduje się „Binder” z nazwą
odpowiadającą szukanej nazwie. Rezultatem jest wartość wszystkich „binderów” w danej sekcji
posiadających szukaną nazwę.
Podstawową zaletą zastosowania podejścia stosowego do tworzenia języków zapytań jest z pewnością
„czystość” oraz przejrzystość nowo utworzonego języka. Co więcej poprzez zastosowanie podejścia
stosowego można bez problemów odrzucić wiele ograniczeń istniejących w aktualnie używanych
językach zapytań jak SQL, OQL itp.. Język zapytań zbudowany w oparciu o podejście stosowe
charakteryzuje się bardzo małą ilością konstrukcji gramatyczno-semantycznych.
Dodatkowo, ponieważ języki programowaniu także budowane są w oparciu o podejście stosowe, w
miarę łatwym zadaniem jest dobudowanie instrukcji imperatywnych do języka zapytań, tworząc z
niego pełnoprawny język programowania, doskonale nadający się do tworzenia aplikacji operujących
na bazach danych.
Oparcie języka zapytań o podejście stosowe pozwala na wykorzystanie wielu ciekawych i relatywnie
prostych optymalizacji. Więcej informacji na temat optymalizacji znajduje się w pracy doktorskiej
pana Jacka Płodzienia ([30]).
7.3. Podejście stosowe na tle innych teorii
W punkcie tym pokażemy wady istniejących teorii, na których budowane są języki zapytań
zarówno do baz relacyjnych jak i obiektowych. Pominiemy tutaj wszystkie teorie, które powstały dla
języków zapytań i skoncentrujemy się na dwóch teoriach mających zdecydowanie najwięcej
zwolenników:
 Algebra relacyjna i rachunek relacyjny – podstawową wadą algebry i rachunku relacji jest brak
pokrycia całości języka. Algebra relacyjna nie przewiduje istnienia operatorów
imperatywnych (INSERT, DELETE, UPDATE), które są integralną częścią języka zapytań
bazującego na tych teoriach. Także operacje grupowania i porządkowania nie występują w
algebrze relacyjnej
 Algebry obiektowe – podstawowe wady podobne jak w algebrze relacyjnej. Brak możliwości
dokonywanie operacji imperatywnych na obiektach. Algebry obiektowe traktują także pewne
operatory nie-algebraiczne jako algebraiczne. Powstał także rachunek obiektowy, który
pokazywano jako równoważny algebrze obiektowej ([31], [32]).
Jak widać dwie podstawowe teorie na których opierają się języki zapytań, nie wystarczają aby w
całości opisać dany język. Problemy powstałe z tego powodu są doskonale widoczne na przykładzie
ewolucji SQL, gdzie w miarę rozbudowywania języka o nowe właściwości, jego skomplikowanie
rosło w niesamowitym tempie, przy jednoczesnym braku czytelnej semantyki, oraz wielu
ograniczeniach na zapytania dopuszczalne w tym języku.
Zastosowanie podejścia stosowego do tworzenia języków zapytań, usuwa większość problemów, z
którymi borykali się twórcy języków budowanych na innych teoriach. Dając jednocześnie bardzo silne
narzędzie zarówno w ręce twórców języka zapytań jak i późniejszych użytkowników tego języka.
Strona 43
Język zapytań dla XML oparty na podejściu stosowym
7.4. Podejście stosowe a XML
Standard XML posiada kilka cech umożliwiających w miarę naturalne odwzorowanie XML na
język zapytań oparty o podejście stosowe. Pierwszą z nich jest traktowanie kolekcji. Zarówno w XML
jak i w podejściu stosowym kolekcje tworzy się nie poprzez specjalne struktury, lecz poprzez
identyczne nazwy obiektów. Kolejną cechą XML, która doskonale dopasowuje się do podejścia
stosowego jest stosunek do wartości zerowych (null). W XML wartości te są po prostu pomijane, co
wydaje się być bardzo dobrą zasadą.
Istnieje jednak kilka problemów związanych z XML, które powodują pewne problemy przy
traktowaniu XML jako bazy danych. Po pierwsze obiekty XML nie posiadają wewnętrznego
identyfikatora. Powstaje, więc problem z określeniem identyfikatorów dla XML. Brak jest również w
XML standardu dotyczącego możliwości tworzenia relacji, a istniejące propozycje standardów
określania relacji (XLink, XPointer) trudno jest uznać za doskonałe.
Strona 44
Język zapytań dla XML oparty na podejściu stosowym
IV. Omówienie rezultatów pracy
Poniższy rozdział przedstawia rezultaty prac. Opis składa się z dwóch części – omówienia
języka zapytań dla XML, oraz API udostępnianego przez prototypową implementację tego języka.
8. Omówienie języka zapytań dla XML stanowiącego zasadniczy
rezultat pracy
Omówienie języka zapytań dla XML przedstawia składnię oraz semantykę tego języka. Aby
ułatwić zrozumienie działania poszczególnych operatorów, autorzy oprócz semantyki każdego z nich
przedstawiają również przykład użycia wraz z przykładowymi danymi i uzyskiwanym wynikiem.
8.1. Składania języka
Składnia, syntaktyka (syntax), formalna budowa napisów języka określona przez jego
gramatykę. Program poprawny składniowo nie musi być poprawny semantycznie. Bliskie pytaniu
o składnię jest pytanie: „jak to (naprawdę) powinno wyglądać?”. ([14])
W związku z tym, że stworzony przez nas język zapytań, opiera się na podejściu stosowym dla
języków zapytań, składnia jego jest podobna do składni języka SBQL (Stack-Based Query Language)
opracowanego przez Kazimierza Subietę ([3]).
Możemy wyróżnić następujące podstawowe elementy zapytania:
 Łańcuch znaków w apostrofach np. ‘Kowalski’, ‘Warszawa’ jest zapytaniem, traktowany jest
jako dana typu tekstowego.
 Łańcuch znaków bez apostrofów, możliwy do konwersji na liczbę zmiennoprzecinkową
traktowany jest jako dane typu zmiennoprzecinkowego
 Łańcuch znaków w apostrofach ‘true’ lub ‘false’, z dokładnością do rozmiaru znaków, będzie
traktowany jako dana logiczna lub tekstowa w zależności od operatora.
 Łańcuch znaków bez apostrofów nie możliwy do konwersji na liczbę zmiennoprzecinkową
związany będzie do elementu o nazwie odpowiadającej łańcuchowi znaków, znajdującego się
na stosie środowisk. Łańcuch ten musi być zgodny ze standardami nazewnictwa węzłów
XML. Może być zmodyfikowany poprzez wyrażenie eliptyczne ellipse lub operację $
oznaczającą zawężenie wyszukiwania danej nazwy tylko do wierzchołka stosu środowisk.
Zapytania można łączyć ze sobą za pomocą operatorów. Operatory ze względu na syntaktykę możemy
podzielić na unarne oraz binarne, oraz ze względu na wykorzystanie stosu środowisk na algebraiczne
oraz nie-algebraiczne.
 Jeżeli operator „op” jest oznaczeniem unarnego operatora algebraicznego, a „q” zapytaniem
wówczas „op q” jest zapytaniem. Przykładami operatorów tego typu operatorów są: count, -,
exists itd.
 Jeżeli operator „op” jest oznaczeniem binarnego operatora algebraicznego, a „q1” oraz „q2” są
zapytaniami, wówczas „q1 op q2” jest również zapytaniem. Przykładami operatorów tego
typu są: +,-,/,*, AND itd.
 Jeżeli operator „op” jest oznaczeniem operatora nie-algebraicznego niebędącego
kwantyfikatorem, a „q1” oraz „q2” są zapytaniami, wówczas „q1 op q2” jest również
zapytaniem. Przykładami operatorów nie-algebraicznych jest operator selekcji (where),
projekcji lub nawigacji (.), operator zależnego złączenia (DepJoin) itd.
Strona 45
Język zapytań dla XML oparty na podejściu stosowym
 Jeżeli operator „op” jest oznaczeniem kwantyfikatora, a „q1” oraz „q2” są zapytaniami
wówczas „FOR ALL q1 HOLDS q2” jest zapytaniem i oznacza kwantyfikator uniwersalny,
oraz „FOR ANY q1 HOLDS q2” jest również zapytaniem i oznacza kwantyfikator
egzystencjalny. Zapisy te są równoważne „q1 op q2” jednakże zdecydowaliśmy się zachować
w miarę tradycyjną składanie do tego typu operatorów.
 Jeżeli „q” jest zapytaniem wówczas „(q)” jest również zapytaniem. Pozwala to na dowolne
używanie nawiasów a co za tym idzie, zmieniać priorytety operatorów.
 Jeżeli „q” jest zapytaniem, zaś n jest wyrażeniem tekstowym („test”, „zmienna”), wówczas „q
as n” jest również zapytaniem, Operator as jest unarnym operatorem zmiany nazwy,
wykorzystywany jest do definiowania pomocniczej nazwy.
 Jeżeli „q” jest zapytaniem, zaś n jest wyrażeniem tekstowym („test”, „zmienna”), wówczas „q
group as n” jest również zapytaniem.
Przykładowe zapytania zgodne ze zdefiniowaną składnią:
 1356.12
 ‘Warszawa’
 -2
 8*14
 nazwisko = ‘Kowalski’
 Osoba where (nazwisko = ‘Kowalski’)
 (Osoba where (nazwisko = ‘Kowalski’)).(1.3*Zarobek)
 FOR ALL Osoba HOLDS (Wiek>50)
 (2+2)*3
 ((Osoba as p) DepJoin (p.pracujeW.Dzial as d)).(p.nazwisko, d.nazwa)
Rysunek podsumowujący składnie zdefiniowaną w języku zapytań dla XML
zapytanie ::= wyrażenie tekstowe
zapytanie ::= wyrażenie liczbowe
zapytanie ::= nazwa węzła
zapytanie ::= ellipse nazwa węzła | $nazwa węzła
zapytanie ::= opUnary zapytanie
opUnary
oznacza
algebraiczny
unarny
operator
zapytanie ::= zapytanie opBinarny zapytanie
opBinary
oznacza
algebraiczny
binarny
operator
zapytanie ::= zapytanie opNieAlg zapytanie
opNieAlg oznacza operator nie-algebraiczny
opNieAlg ::= where |.| DepJoin
zapytanie ::= FOR ANY zapytanie HOLDS zapytanie
zapytanie ::= FOR ALL zapytanie HOLDS zapytanie
zapytanie ::= (zapytanie)
zapytanie ::= zapytanie as wyrażanie tekstowe
zapytanie ::= zapytanie group as wyrażanie tekstowe
Strona 46
Język zapytań dla XML oparty na podejściu stosowym
8.2. Stos rezultatów
Ponieważ podczas ewaluacji zapytania mogą być potrzebne wyniki cząstkowe, potrzebna jest
struktura, na której przechowywać będziemy zarówno wyniki cząstkowe jak i rezultat całego
zapytania. W większości języków zapytań funkcję tą pełni stos arytmetyczny, w naszym przypadku
konieczne jest nieznaczna modyfikacja stosu arytmetycznego, ponieważ na stosie rezultatów
znajdować się będą tablice węzłów będące rezultatami zapytań. Wszystkie operacje na stosie
rezultatów odbywają się tylko na elementach znajdujących się na wierzchołku stosu ( w zależności od
operatora mogą to być jeden lub dwa elementy).Elementy stosu znajdujące się poniżej staną się
widoczne dopiero w momencie usunięcia odpowiedniej liczby elementów z wierzchołka stosu
rezultatów.
8.3. Semantyka języka zapytań dla XML
Semantyka (angielskie semantics), znaczenie przyporządkowane symbolom i napisom języka.
W przypadku języka programowania jego semantyka jest wyznaczana przez faktyczne zachowanie się
sprzętu lub innych składowych systemu komputerowego, wynikające z interpretacji jednostek
programowych (instrukcje, deklaracje). Bliskie pytaniu o semantykę jest pytanie: „co to (naprawdę)
powoduje?”. ([14])
Semantyka stworzonego przez nas języka zapytań dla XML zdefiniowana jest poprzez metody
implementujące operatory. Operatory te wywoływane są przez rekurencyjną metodę, executeQuery,
która dokonuje odpowiednich wywołań. Ponieważ w naszej implementacji języka zapytań nie
implementujemy operatorów zmieniających stan, zachowane są następujące założenia:
 Podczas ewaluacji zapytania nie zmienia się stan składu obiektów
 Podczas ewaluacji zapytania stan stosu środowisk może ulec zmianie, lecz po zakończeniu
ewaluacji, będzie taki sam jak przed ewaluacją zapytania
 Podczas ewaluacji zapytania „q” nie zmienia się ta część stosu rezultatów, która istniała w
momencie rozpoczęcia ewaluacji zapytania. W trakcie ewaluacji mogą być dodawane i
usuwane elementy ze stosu rezultatów, lecz po zakończeniu ewaluacji zapytania, na stosie
rezultatów będzie o jeden element więcej niż przed rozpoczęciem ewaluacji.
Definicja semantyki będzie sterowana składnią, oznacza to, że metodę executeQuery będzie
wspomagał analizator gramatyczny(w naszym przypadku LR(1) wygenerowany dla podanej składni),
który dokona rozbioru zapytanie na podzapytanie wraz z operatorami łączącymi te podzapytania. Po
wyliczeniu wyniku podzapytania, rezultat całego zapytania jest tworzony w oparciu o wyniki
podzapytań.
Po ewaluacji zapytania rezultat zostaje odłożony na stos rezultatów. W związku z tym powinien być
on „konsumowany” przez operator języka lub interfejsu, dla którego zapytania było parametrem.
Doskonałym przykładem takiego operatora jest operator delete lub update.
Zapytaniem elementarnym w stworzonym przez nas języku, może być wyrażenie tekstowe,
liczbowe lub też identyfikator obiektu znajdującego się w składzie. W takim przypadku procedura
ewaluacji jest bardzo prosta. Jeżeli jest to wartość tekstowa lub liczbowa, jest ona po prostu wkładana
na wierzchołek stosu rezultatów. W przypadku, gdy jest to identyfikator obiektu znajdującego się w
składzie dokonywane jest wiązanie tej nazwy na stosie środowisk, a następnie wstawienie wyniku na
wierzchołek stosu rezultatów.
We wszystkich pozostałych przypadkach najpierw dokonywany jest rozbiór zapytania na jedno lub
dwa podzapytania oraz operator. Następnie wyliczany jest rezultat podzapytań i łączony w rezultat
całego zapytania zgodnie z operatorem. Proces ten jest z natury rekurencyjny, który kończy się w
momencie rozłożenia zapytania na zapytania elementarne.
Operatory łączące podzapytania możemy podzielić na algebraiczne i nie-algebraiczne. Podstawowa
różnica między operatorami algebraicznymi i nie-algebraicznymi to ich stosunek do stosu środowisk.
Strona 47
Język zapytań dla XML oparty na podejściu stosowym
Operatory algebraiczne do swojego działania nie potrzebują stosu środowisk, używają tylko i
wyłącznie stosu rezultatów, natomiast operatory nie-algebraiczne oprócz korzystania ze stosu
rezultatów, odwołują się i wykonują operacje na stosie środowisk.
Przykładowa baza danych, na której będziemy pokazywać działania przykładowych operatorów
wygląda następująco:
<baza>
<Pracownik>
<Imie>Jan</Imie>
<Nazwisko>Kowalski</Nazwisko>
<Pensja>2000</Pensja>
<Premia>1000</Premia>
</Pracownik>
<Pracownik>
<Imie>Kamil</Imie>
<Nazwisko>Bylejaki</Nazwisko>
<Pensja>1500</Pensja>
<Premia>0</Premia>
</Pracownik>
<Pracownik>
<Imie>Kamil</Imie>
<Nazwisko>Kowalski</Nazwisko>
<Pensja>1700</Pensja>
<Premia>0</Premia>
</Pracownik>
<Dzial>
<Nazwa>Produkcja</Nazwa>
</Dzial>
</baza>
8.3.1
Operatory algebraiczne
Podstawową cechą operatorów algebraicznych jest fakt, ze kolejność ewaluacji argumentów nie
ma wpływu na wynik. Stanowi to zasadniczą różnicę w stosunku do operatorów nie-algebraicznych.
Ewaluacja zapytanie z operatorem algebraicznym dla operatora unarnego polega na ewaluacji
podzapytania pobrania wyniku, a następnie wstawienia na stos rezultatów rezultatu działania operatora
na wynik ewaluacji podzapytania.
Dla algebraicznych operatorów binarnych jedyną różnicą jest konieczność ewaluacji dwóch
podzapytań.
Ewaluację operatów algebraicznych można zapisać w następujący sposób:
wynik(op(q1)) = op(wynik(q1)) – dla operatora unarnego
wynik(q1 op q2) = wynik(q1) op wynik(q2)
Strona 48
Język zapytań dla XML oparty na podejściu stosowym
Możemy
wyodrębnić
kilka
charakterystycznych
zaimplementowanych w naszym języku:
grup
operatorów
algebraicznych
 Operatory dotyczące liczb całkowitych i rzeczywistych: „+”„–”, „*”, „/”
Zapytanie: 2+3*12-10/2
Wynik:
33
Zapytanie: baza.Pracownik.((Pensja.TextValue)+(Premia.TextValue))
Wynik:
3000.0
1500.0
1900.0
 Operatory działające na łańcuchach tekstowych: operator konkatenacji „&”
Zapytanie:
baza.Pracownik.((Nazwisko.TextValue)& (' ' & (Imie.TextValue)))
Wynik:
'Kowalski Jan'
'Bylejaki Kamil'
'Kowalski Kamil'
 Operatory logiczne: AND, OR, !
Zapytanie:
baza.Pracownik
where
((Pensja.TextValue=2000)
(Nazwisko.TextValue!='Kowalski'))
OR
Wynik:
<Pracownik>
<Imie>Jan</Imie>
<Nazwisko>Kowalski</Nazwisko>
<Pensja>2000</Pensja>
<Premia>1000</Premia>
</Pracownik>
<Pracownik>
<Imie>Kamil</Imie>
<Nazwisko>Bylejaki</Nazwisko>
<Pensja>1500</Pensja>
<Premia>0</Premia>
</Pracownik>
 Generyczny operator porównania na równość, oznaczany „=”, oraz operator odwrotny „!=”. W
naszej implementacji operatory te zdefiniowane są dla liczb, wyrażeń tekstowych,
identyfikatorów obiektów (poprzez referencje). Np.
Zapytanie: 2=2
Wynik: ‘true’
Zapytanie: baza.Pracownik where (Nazwisko.TextValue='Kowalski')
Wynik:
<Pracownik>
<Imie>Jan</Imie>
Strona 49
Język zapytań dla XML oparty na podejściu stosowym
<Nazwisko>Kowalski</Nazwisko>
<Pensja>2000</Pensja>
<Premia>1000</Premia>
</Pracownik>
<Pracownik>
<Imie>Kamil</Imie>
<Nazwisko>Kowalski</Nazwisko>
<Pensja>1700</Pensja>
<Premia>200</Premia>
</Pracownik>
 Operatory porównywania nie na równość – działają zarówno na liczbach jak i wartościach
tekstowych: <.>,>=.<=
Zapytanie: 2>=2
Wynik:
‘true’
Zapytanie: ‘Ala' > 'Beaty'
Wynik:
‘false’
Zapytanie: baza.Pracownik where (Pensja.TextValue>1800)
Wynik:
<Pracownik>
<Imie>Jan</Imie>
<Nazwisko>Kowalski</Nazwisko>
<Pensja>2000</Pensja>
<Premia>1000</Premia>
</Pracownik>
 Funkcje działające na kolekcjach. Są to takie operatory jak count (zliczający liczbę elementów
w kolekcji), sum (sumujące liczby znajdujące się w kolekcji), exists (sprawdza czy kolekcja
jest niepusta).
Zapytanie: count(baza.Pracownik.Pensja.TextValue)
Wynik:
3
Zapytanie: sum(baza.Pracownik.Pensja.TextValue)
Wynik:
5200
8.3.2
Operator definiowania pomocniczej nazwy
Operatory definiowania pomocniczej nazwy pojawiły się w relacyjnych językach zapytań, gdzie
noszą nazwę „zmiennych”. Po zdefiniowaniu mogą być używane w warunkach selekcji, złączeń itp..
Operator definiowania pomocniczej nazwy jest operatorem unarnym parametryzowanym nazwą.
Operator ten jest praktycznie niezbędny do wyrażenia niektórych zapytań. W naszej implementacji
nosi on nazwę „as”. Jeżeli x jest zapytaniem zwracającym pewną kolekcję to „x as n” zwróci kolekcję
etykietowaną poprzez nazwę „n” np.
Strona 50
Język zapytań dla XML oparty na podejściu stosowym
Zapytanie: baza.Pracownik zwróci wynik:
<Pracownik>
<Imie>Jan</Imie>
<Nazwisko>Kowalski</Nazwisko>
<Pensja>2000</Pensja>
<Premia>1000</Premia>
</Pracownik>
<Pracownik>
<Imie>Kamil</Imie>
<Nazwisko>Bylejaki</Nazwisko>
<Pensja>1500</Pensja>
<Premia>0</Premia>
</Pracownik>
<Pracownik>
<Imie>Kamil</Imie>
<Nazwisko>Kowalski</Nazwisko>
<Pensja>1700</Pensja>
<Premia>200</Premia>
</Pracownik>
zaś zapytanie: baza.Pracownik as prac zwróci:
<prac>
<Imie>Jan</Imie>
<Nazwisko>Kowalski</Nazwisko>
<Pensja>2000</Pensja>
<Premia>1000</Premia>
</prac>
<prac>
<Imie>Kamil</Imie>
<Nazwisko>Bylejaki</Nazwisko>
<Pensja>1500</Pensja>
<Premia>0</Premia>
</prac>
<prac>
<Imie>Kamil</Imie>
<Nazwisko>Kowalski</Nazwisko>
<Pensja>1700</Pensja>
<Premia>200</Premia>
</prac>
Strona 51
Język zapytań dla XML oparty na podejściu stosowym
Jak widać została zmieniona nazwa węzła – efekt ten jest niestety wynikiem specyfiki tego języka
zapytań, spowodowanej użyciem XML jako bazy danych. Operator „as” może być dowolnie
zagnieżdżany w związku z tym zapytanie (baza.Pracownik as prac) as pracus jest jak
najbardziej poprawne. Operator „as” zdecydowanie ułatwia tworzenie niektórych zapytań, np. w
momencie, gdy potrzebujemy w zapytaniu dwukrotnie odnieść się do tej samej kolekcji obiektów np.:
Zapytanie zwracające pracowników zarabiających więcej od przynajmniej jednego pracownika:
(((baza.Pracownik
as
p1),(baza.Pracownik
as
p2))
where
((p1.Pensja.TextValue) > (p2.Pensja.TextValue))).p1.Pensja.TextValue
Zwróci wynik:
2000
2000
1700
Czasami może pojawić się potrzeba grupowania obiektów, do tego celu służy operator „group as”.
Operator ten opakowuje kolekcję zwróconą przez podzapytania w nowy węzeł o nazwie podanej jako
parametr operatora. Operator ten jest użyteczny w przypadku, gdy chcemy nazwać cały wynik
zapytania a nie elementy wyniku tego zapytania. Przykładowe zapytanie:
baza.Pracownik group as Pracownicy
Zwraca następujący wynik:
<Pracownicy>
<Pracownik>
<Imie>Jan</Imie>
<Nazwisko>Kowalski</Nazwisko>
<Pensja>2000</Pensja>
<Premia>1000</Premia>
</Pracownik>
<Pracownik>
<Imie>Kamil</Imie>
<Nazwisko>Bylejaki</Nazwisko>
<Pensja>1500</Pensja>
<Premia>0</Premia>
</Pracownik>
<Pracownik>
<Imie>Kamil</Imie>
<Nazwisko>Kowalski</Nazwisko>
<Pensja>1700</Pensja>
<Premia>200</Premia>
</Pracownik>
<Pracownicy>
8.3.3
Operator budowania struktury
Bardzo często zachodzi potrzeba stworzenia struktury. Operator „,” zaimplementowany w
języku zapytań, dla XML, swoim zachowaniem bardzo przypomina, operator o tej samej nazwie („,”).
Działa on praktycznie jak iloczyn kartezjański, tylko z jednym małym wyjątkiem, mianowicie, jeżeli
Strona 52
Język zapytań dla XML oparty na podejściu stosowym
jeden z elementów jest pusty, jest on podczas wyliczania iloczynu pomijany. Wynikiem działania
operatora jest kolekcja węzłów o nazwie „StructNode”, z których każdy zawiera cząstkowy wynik tak
zdefiniowanego iloczynu kartezjańskiego.
Przykładowe zapytanie wykorzystujące operator „,”:
((baza.Pracownik where (Pensja.TextValue>1800)), (baza.Dzial))
Wynikiem tego zapytania jest:
<StructNode>
<Pracownik>
<Imie>Jan</Imie>
<Nazwisko>Kowalski</Nazwisko>
<Pensja>2000</Pensja>
<Premia>1000</Premia>
</Pracownik>
<Dzial>
<Nazwa>Produkcja</Nazwa>
</Dzial>
</StructNode>
8.3.4
Operatory nie-algebraiczne
Operatory nie-algebraiczne stanowią istotę podejścia stosowego. Do tej kategorii operatorów
należą operatory selekcji (where), operator kropki, operator zależnego złączenia oraz kwantyfikatory.
Wszystkie wyżej wymienione operatory są operatorami binarnymi. Mimo znacznego podobieństwa
(syntaktycznego) do operatorów algebraicznych, semantyka operatów nie-algebraicznych nie daje się
łatwo sprowadzić do algebry. Podstawową różnicą pomiędzy operatorami algebraicznymi i niealgebraicznymi jest to, iż operatory nie-algebraiczne mogą wykonywać operację na stosie środowisk
(jest on niezbędny dla działania operatorów nie-algebraicznych). Stan stosu środowisk jest zmienny w
czasie wykonywania operatora, lecz po zakończeniu działania, jest taki sam jak przed rozpoczęciem
ewaluacji operatora (jeżeli operator nie ma działań ubocznych).
Poniżej podany jest nieformalny opis ewaluacji zapytania „q1 opNieAlg q2”:
1. Dokonaj ewaluacji zapytania q1. Wynikiem jest kolekcja węzłów.
2. Dla każdego węzła „e” należącego do wyniku q1 wykonaj:
a. Pobierz wnętrze węzła „e” – wynikiem jest zbiór binderów „z”
b. Stwórz nową sekcję na wierzchołku stosu środowisk i wstaw tam „z”.
c. Dokonaj ewaluacji zapytania q2.
d. Oblicz wynik pośredni dla elementu e, poprzez połączenie e z wynikiem ewaluacji q2.
Funkcja łącząca zależy od operatora.
e. Usuń nowo wstawioną sekcję ze stosu środowisk
3. Zsumuj wszystkie wyniki pośrednia. Funkcja sumująca zależna jest od rodzaju operatora.
Operatory nie-algebraiczne różnią się między sobą wyłącznie sposobem obliczania wyniku
pośredniego, oraz sposobem sumowania wyników pośrednich.
Poniżej podane są definicje operatorów wraz z opisem:
Strona 53
Język zapytań dla XML oparty na podejściu stosowym
Operator where
Operator where jest operatorem selekcji. Odpowiada on operatorom selekcji znanym, z SQL, czy
OQL.
Składnia: q1 where q2
Sposób obliczania wyniku pośredniego: dla danego elementu e należącego do wyniku q1 zwraca
jednoelementową kolekcją zawierającą element e w przypadku, gdy dla tego e ewaluacja podzapytania
q2 zwróciła ‘true’, w przeciwnym wypadku zwraca pustą kolekcję.
Sumowanie wyników pośrednich: sumuj (mnogościowo) wszystkie wyniki pośrednie.
Przykładowe zapytanie: baza.Pracownik where (Pensja.TextValue >= 1700)
Wynikiem zapytanie jest:
<Pracownik>
<Imie>Jan</Imie>
<Nazwisko>Kowalski</Nazwisko>
<Pensja>2000</Pensja>
<Premia>1000</Premia>
</Pracownik>
<Pracownik>
<Imie>Kamil</Imie>
<Nazwisko>Kowalski</Nazwisko>
<Pensja>1700</Pensja>
<Premia>200</Premia>
</Pracownik>
Operator kropki
Operator „.” jest to operator projekcji, nawigacji
Składnia: q1.q2
Sposób obliczania wyniku pośredniego: pomija e, zwraca wynik ewaluacji q2.
Sumowanie wyników pośrednich: sumuj (mnogościowo) wszystkie wyniki pośrednie.
Przykładowe zapytanie: baza.Pracownik.Pensja
Wynikiem zapytanie jest:
<Pensja>2000</Pensja>
<Pensja>1500</Pensja>
<Pensja>1700</Pensja>
Operator zależnego złączenia
Składnia: q1 DepJoin q2
Sposób obliczania wyniku pośredniego: Dla każdego elementu e2 będącego wynikiem ewaluacji q2,
tworzy strukturę łącząc e z e2. Wynikiem pośrednim jest kolekcja tak stworzonych struktur.
Sumowanie wyników pośrednich: sumuj (mnogościowo) wszystkie wyniki pośrednie.
Strona 54
Język zapytań dla XML oparty na podejściu stosowym
Przykładowe zapytanie:
baza.Dzial DepJoin (baza.Pracownik)
Wynikiem zapytanie jest:
<StructNode>
<Dzial>
<Nazwa>Produkcja</Nazwa>
</Dzial>
<Pracownik>
<Imie>Jan</Imie>
<Nazwisko>Kowalski</Nazwisko>
<Pensja>2000</Pensja>
<Premia>1000</Premia>
</Pracownik>
<Pracownik>
<Imie>Kamil</Imie>
<Nazwisko>Bylejaki</Nazwisko>
<Pensja>1500</Pensja>
<Premia>0</Premia>
</Pracownik>
<Pracownik>
<Imie>Kamil</Imie>
<Nazwisko>Kowalski</Nazwisko>
<Pensja>1700</Pensja>
<Premia>200</Premia>
</Pracownik>
</StructNode>
Kwantyfikator egzystencjalny
Składnia: FOR ANY q1 HOLDS q2
Sposób obliczania wyniku pośredniego: pomija e, zwraca wynik ewaluacji q2.
Sumowanie wyników pośrednich: zwraca ‘true’, jeżeli chociaż jeden wynik pośredni zwrócony przez
q2 jest ‘true’, w przeciwnym przypadku zwraca ‘false’.
Przykładowe zapytanie:
FOR ANY (baza.Pracownik) HOLDS (Pensja.TextValue>1600)
Wynikiem zapytanie jest: ‘true’
Kwantyfikator uniwersalny
Składnia: FOR ALL q1 HOLDS q2
Strona 55
Język zapytań dla XML oparty na podejściu stosowym
Sposób obliczania wyniku pośredniego: pomija e, zwraca wynik ewaluacji q2.
Sumowanie wyników pośrednich: zwraca ‘false’, jeżeli chociaż jeden wynik pośredni zwrócony przez
q2 jest ‘false’, w przeciwnym przypadku zwraca ‘true’.
Przykładowe zapytanie:
FOR ALL (baza.Pracownik) HOLDS (Pensja.TextValue>1600)
Wynikiem zapytanie jest: ‘false’
8.3.5
Operacje ellipse i $
Operacja ellipse
Składnia operacji ellipse jest następująca: ellipse nazwa gdzie nazwa jest nazwą obiektu istniejącego
w składzie danych.
Wynikiem działania operacji ellipse jest kolekcja zawierająca wszystkie węzły o danej nazwie,
niezależnie od miejsca w strukturze XML, w której się oryginalnie znajdowały.
Przykładowe zapytanie: ellipse Pensja
Wynikiem zapytania jest następująca kolekcja:
<Pensja>2000</Pensja>
<Pensja>1500</Pensja>
<Pensja>1700</Pensja>
Operacja $
Użycie operacji $ przed nazwą obiektu, określa, że wiązania danej nazwy ma nastąpić tylko i
wyłącznie na wierzchołku stosu środowisk (stos środowisk nie jest przeszukiwany w celu znalezienia
bindera o danej nazwie). Operacja ta jest niezmiernie przydatna w przypadku, gdy mamy do czynienia
z odwołaniem do nazwy, która nie istnieje w danym elemencie węzła, ale istnieje już na stosie
środowisk (np. gdy w elemencie nadrzędnym istnieje atrybut o takiej nazwie jaką wyszukujemy).
Ponieważ podejście XML, jeżeli mamy wartość zerową (pustą), to węzeł o danej nazwie nie występuje
w danym elemencie. W związku, z tym wiązanie nazw w tym przypadku powinno być ograniczone
tylko do wierzchołka stosu środowisk.
8.4. Linki i sposób ich użycia
W celu zwiększenia możliwości języka zapytań wprowadzona została możliwość definiowania
„linków” prowadzących do innych węzłów w ramach bazy danych (niekoniecznie do tego samego
pliku).
8.4.1
Sposób wprowadzenia linków do bazy danych
W celu wprowadzenia linka do bazy danych należy wykonać dwie czynności:
 Węzeł, do którego chcemy stworzyć link musi otrzymać atrybut id o unikalnej wartości w
ramach bazy (jeśli jeszcze takiego atrybutu nie posiada)
 W węźle, w którym chcemy stworzyć link należy stworzyć węzeł potomny o dowolnej
nazwie (będzie ona nazwą linka), mający atrybut pointer=”true” i wartość tekstową
równą wartości atrybutu id, do którego link ma prowadzić.
8.4.2
Sposób wykorzystania linków w zapytaniach
Strona 56
Język zapytań dla XML oparty na podejściu stosowym
Linki w zapytaniu wykorzystuje się w ten sam sposób, jakby węzeł, do którego prowadzi link
był zagnieżdżony w węźle stanowiącym link. Przykładowo, jeżeli fragment bazy danych wygląda
następująco:
<baza>
<pracownik id=”AA121”>
<nazwisko>Kowalski</nazwisko>
<imie>Jan</imie>
</pracownik>
<zaklad>
<nazwa>Duza Firma S.A.</nazwa>
<prezes pointer=”true”>AA121</prezes>
</zaklad>
</baza>
możemy sprawdzić, kto jest prezesem firmy Duza Firma S.A. w sposób następujący:
(baza.zaklad where nazwa.TextValue=’Duza Firma
S.A.’).prezes.pracownik
otrzymując następujący wynik:
<ResultSet>
<pracownik id=”AA121”>
<nazwisko>Kowalski</nazwisko>
<imie>Jan</imie>
</pracownik>
</ResultSet>
Należy przy tym pamiętać o tym, iż w celu prawidłowego zadania zapytania należy znać typ
węzła, do którego prowadzi link. Jeśli w powyższym przykładzie zadalibyśmy zapytanie
(zaklad where nazwa.TextValue=’Duza Firma S.A.’).prezes.osoba
otrzymalibyśmy jako wynik zbiór pusty – link nie prowadzi do węzła typu osoba:
<ResultSet>
</ResultSet>
Węzeł stanowiący link może zawierać inne, zagnieżdżone węzły, oraz mieć dodatkowe
atrybuty, nie może jednak mieć w swojej wartości tekstowej informacji innych, niż id węzła do
którego prowadzi link. Jeśli w wartości tekstowej węzła stanowiącego link będą dodatkowe dane,
system wykonujący zapytania uzna je za część identyfikatora poszukiwanego obiektu – i nie znajdzie
go (lub znajdzie niewłaściwy). Z tego samego powodu nie należy umieszczać w ramach jednego
węzła stanowiącego link identyfikatorów dwóch różnych węzłów docelowych. Jeśli w ramach jednego
węzła chcemy stworzyć kilka linków o tej samej nazwie, należy dla każdego linka stworzyć osobny
węzeł stanowiący link, tak jak w poniższym przykładzie:
</pracownik>
<zaklad>
<nazwa>Duza Firma S.A.</nazwa>
<prezes pointer=”true”>AA121</prezes>
<wiceprezes pointer=”true”>AA122</prezes>
<wiceprezes pointer=”true”>AA123</prezes>
<wiceprezes pointer=”true”>AA124</prezes>
</zaklad>
8.4.3
Nałożone ograniczenia
System nakłada na użytkownika tylko jedno ograniczenie – identyfikatory węzłów w ramach
bazy danych muszą być unikalne. Jeśli po dołączeniu do bazy kolejnego pliku XML warunek ten
przestanie być spełniany, wszystkie linki przestaną funkcjonować – wyrażenia ścieżkowe takie jak
Strona 57
Język zapytań dla XML oparty na podejściu stosowym
podane w przykładach powyżej nie będą dawały oczekiwanych wyników. Nadal możliwe będzie
uzyskanie podobnych efektów poprzez zapytania używające równości atrybutów. Zalecamy również
nie używanie w identyfikatorach znaków klasyfikowanych jako „białe spacje” – spacji, tabulatorów
itd. Węzły stanowiące link również powinny nie zawierać takich znaków – sposób ich obsługi przez
używany parser XML może być nie do końca zgodny z oczekiwanym przez użytkownika.
8.4.4
Wady i zalety przyjętego systemu
Przyjęty system realizacji linków charakteryzuje się następującymi wadami i zaletami:
 Wszystkie linki działają jednokierunkowo. Jedyna możliwością znalezienia węzłów
stanowiących linki, jeśli znamy węzeł, do którego prowadzi link, jest zadanie zapytania
wykorzystującego równość atrybutów i wartości tekstowych (tzn. id=węzeł.TextValue).
 Możliwe jest zrealizowanie odpowiednika asocjacji z atrybutami – węzeł stanowiący link
może posiadać dodatkowe atrybuty i węzły potomne, które możemy wykorzystywać
jako atrybuty związku. Oczywiście należy pamiętać o wspomnianej wyżej
jednokierunkowości takiego związku.
 Należy ręcznie dbać o to, aby linki prowadziły do jakiegoś węzła. Brak jest
automatycznych mechanizmów usuwania „wiszących” linków.
 Należy dbać o to, aby identyfikatory węzłów nie powtarzały się w ramach grupy plików
wykorzystywanych jako baza danych. Możliwe byłoby wprowadzenie mechanizmów
służących do automatycznej zmiany id pochodzących z różnych plików (np. przez
prefiksowanie), utrudniałoby to jednak tworzenie linków pomiędzy różnymi plikami
XML.
9. Omówienie API udostępnianego przez system
Opracowany język zapytań może być wykorzystywany albo za pośrednictwem aplikacji
klienckiej, albo poprzez udostępniane API. Poniżej znajduje się opis metod udostępnianych przez
poszczególne obiekty, istotnych z punktu widzenia programisty chcącego wykorzystać opracowane
klasy we własnej aplikacji:
9.1. Klasa edu.t2r.magisterka.QueryExecutor
Klasa QueryExecutor jest główną klasą, implementującą wszystkie operatory oraz większość
mechanizmów języka zapytań. Do większości zastosowań wystarcza użycie metod udostępnianych
przez tą klasę.
9.1.1
public QueryExecutor()
Domyślny, bezparametrowy konstruktor.
9.1.2
public org.w3c.dom.Document mountDatabase(String databaseName)
Metoda służy do załadowania dokumentu XML pełniącego rolę bazy danych. Parametr
databaseName służy do podania nazwy i ścieżki do dokumentu XML. Zwraca obiekt typu
org.w3c.dom.Document (na wypadek gdyby potrzebny był programiście). Jeśli używany parser DOM
nie wspiera operacji Traversal, podniesie wyjątek RuntimeException ze stosowną informacją.
9.1.3
public org.w3c.dom.Node evaluateQuery(String query) throws
edu.t2r.magisterka.TypeMismatchException, Exception
Metoda służy do ewaluacji zapytania. Parametr query służy do przekazania zapytania, zwrócony
będzie obiekt typu org.w3c.dom.Node, zawierający węzeł typu ResultNode, „opakowujący” wynik
zapytania. Metoda ta może zwrócić wyjątek edu.t2r.magisterka.TypeMismatchException informujący
Strona 58
Język zapytań dla XML oparty na podejściu stosowym
o wykryciu niezgodności typów podczas ewaluacji zapytania, lub też wyjątek typu Exception
przekazany ze skanera (klasa edu.t2r.magisterka.Lexer) lub parsera (klasa edu.t2r.magisterka .parser),
informujący o problemach powstałych podczas parsowania zapytania. Opis wyjątków zwracanych
przez skaner i parser znajduje się w dokumentacji generatorów: skanerów (JFlex) i parserów (CUP).
9.1.4
public boolean relationsUsed()
Metoda zwraca informacę o tym, czy włączona jest obsługa linków.
9.1.5
public Node createNode(String value)
Metoda służy do stworzenia węzła typu TEXT_NODE o wartości zadanej w parametrze.
9.1.6
public Node createNode(String type, String value)
Metoda ta służy do stworzenia węzła o nazwie zadanej w parametrze type, mającego węzeł
potomny typu TEXT_NODE o wartości zadanej w parametrze value.
9.1.7
public Node createNode(Node[] nodes, String type)
Metoda ta służy do stworzenia węzła mającego węzły potomne zadane w parametrze nodes, o
nazwie zadanej w parametrze type.
9.1.8
public Node createNode(String type, Node node1, Node node2)
Metoda ta służy do stworzenia węzła mającego dwa węzły potomne zadane w parametrach
node1 i node2, o nazwie zadanej w parametrze type.
9.1.9
public void clearResultsStack()
Metoda ta służy do oczyszczenia stosu rezultatów w wypadku wystąpienia wyjątku. Powinna
być użyta po wystąpieniu wyjątku, a przed zadaniem kolejnego zapytania (np. w klauzuli catch).
9.1.10 public ReferenceManager refManager
Zmienna publiczna typu edu.t2r.magisterka.ReferenceManager przechowująca
zarządzający referencjami. Opis metod udostępnianych przez obiekt znajduje się poniżej.
obiekt
9.1.11 public LinkManager linkManager
Zmienna publiczna typu edu.t2r.magisterka. LinkManager przechowująca obiekt zarządzający
linkami. Opis metod udostępnianych przez obiekt znajduje się poniżej.
9.2. Klasa edu.t2r.magisterka.ReferenceManager
Klasa ReferenceManager jest klasą, odpowiedzialną za przechowywanie informacji o
referencjach węzłów oraz kopiach danego węzła (w związku ze specyfiką DOM konieczne jest
tworzenie kopii węzłów „klonów”). Metody udostępniane przez daną klasę, pozwalają na dodawanie
informacji zarówno o oryginałach jak i kopiach, jak również pobierania informacji dotyczących węzła.
9.2.1
public boolean isClone(Node node)
Metoda zwraca informację czy dany węzeł jest „klonem” (kopią oryginalnego węzła).
9.2.2
public boolean isReal(Node node)
Metoda zwraca informację czy dany węzeł jest węzłem oryginalnym.
9.2.3
public boolean addClone(Node realNode, Node cloneNode)
Metoda służy do dodawania węzłów-kopii („klonów”), dla węzła oryginalnego.
9.2.4
public Node[] getClones(Node realNode)
Strona 59
Język zapytań dla XML oparty na podejściu stosowym
Metoda służy do pobierania węzłów-kopii dla podanego węzła.
9.2.5
public void addReal(Node realNode)
Metoda służy do dodawania węzłów oryginalnych.
9.2.6
public Node getReal(Node cloneNode)
Metoda służy do pobierania węzła oryginalnego (referencji) w stosunku do podanego węzła.
9.2.7
public void doCleanUp()
Metoda służy do czyszczenia informacji o „klonach” (należy ją wykonać po lub przed
ewaluacją zapytania).
9.3. Klasy klasa edu.t2r.magisterka.parser i edu.t2r.magisterka.Lexer
Opisy metod udostępnianych przez te klasy i sposobów ich użycia znajdują się w dokumentacji
generatorów: skanerów (JFlex) i parserów (CUP). Metody te mogą być użyteczne, jeśli aplikacja ma
udostępniać użytkownikowi informacje związane z procesem parsowania zapytania (np. wskazywać
błędy w zapytaniu).
9.4. Klasa edu.t2r.magisterka.LinkManager
Klasa LinkManager używana jest do zarządzania informacją o węzłach, do których mogą być
prowadzone linki (posiadających atrybut id). Metody tej klasy będą musiały być wykorzystywane
przez programistę wykonującego aktualizacje bazy przy pomocy metod DOM, lub rozbudowującego
system o możliwość wykonywania operacji aktualizacyjnych.
9.4.1
public LinkManager(QueryExecutor executor)
Konstruktor, pobierający obiekt typu QueryExecutor, który będzie wykorzystywać tą instancję.
9.4.2
public Node[] getRelated(String foreignKey)
Metoda zwraca jednoelementową tablicę węzłów, jeśli znajdzie węzeł odpowiadający
identyfikatorowi zawartemu w parametrze, lub zero elementową, jeśli nie znajdzie takiego węzła.
9.4.3
public void addDestinationNode(String nodeValue, org.w3c.dom.Node destinationNode)
throws Exception
Metoda dodaje węzeł przekazany jako parametr drugi, z identyfikatorem przekazanym jako
parametr pierwszy, do struktury danych przechowującej informacje o węzłach posiadających unikalne
identyfikatory. Jeśli okaże się, że nastąpiła próba zdublowania identyfikatora (inny węzeł o tym
identyfikatorze istniał w bazie wcześniej), podniesiony zostanie wyjątek z odpowiednią informacją. W
takim przypadku metoda ta wyłączy również stosowanie relacji w bazie danych.
Metoda ta powinna być używana przez programistów dodających nowe węzły do bazy danych.
9.4.4
Wskazane zmiany klasy przy rozszerzaniu funkcjonalności języka o możliwość
wykonywania operacji aktualizacyjnych.
Należy wprowadzić metody umożliwiające zmianę identyfikatora, pod jakim zapisany jest
obiekt, usuwanie identyfikatorów oraz ponowną kontrolę unikalności identyfikatorów w bazie (w celu
ewentualnego włączenia relacji). Takich metod będzie również potrzebował programista wykonujący
aktualizacje bazy przy pomocy metod DOM.
Strona 60
Język zapytań dla XML oparty na podejściu stosowym
9.5. Metody służące do operacji na węzłach XML
Co prawda w obecnie zaimplementowanej wersji język zapytań nie przewiduje operacji
aktualizacyjnych (takich jak wstawianie, usuwanie lub modyfikacja węzłów), można jednak
wykonywać takie operacje przy pomocy metod udostępnianych przez interfejs DOM. Metody te
opisane są w specyfikacji interfejsu DOM na stronach W3C, oraz w specyfikacjach API parserów.
Ponieważ, po zaimplementowaniu operatorów aktualizacyjnych, może być również wymagane
zapisywanie zmodyfikowanych węzłów na dysk, warto dodać, iż specyfikacja interfejsu DOM zawiera
klasę XMLSerializer odpowiedzialną za zapisywanie struktury XML na dysk (lub inne wyjście).
Uwaga – aby prawidłowo posłużyć się operacjami aktualizacyjnymi należy najpierw odzyskać
referencje do oryginalnego węzła na podstawie kopii uzyskanej w wyniku wykonania zapytania.
Sposób odzyskania referencji omówiony jest w punkcie 2.2 tego rozdziału. Przy modyfikowaniu
atrybutu id węzłów (niezalecane w obecnej wersji), lub też przy dodawaniu tego atrybutu do
istniejących/nowych węzłów należy również używać metod opisanych w punkcie 2.4 tego rozdziału.
Nie użycie tych metod uniemożliwi budowę prawidłowo działających linków do węzłów.
Strona 61
Język zapytań dla XML oparty na podejściu stosowym
V. Omówienie implementacji
Rozdział ten przedstawia implementację języka zapytań. Jego lektura może pomóc w lepszym
zrozumieniu działania języka, jak również jest istotna dla osób chcących rozbudować lub
zmodyfikować prototypową implementację.
10. Rozwiązania implementacyjne – struktury danych
Poniżej znajduje się opis struktur danych wraz z wyjaśnieniem celowości użytych rozwiązań.
10.1.Skład obiektów
W związku z tym, że wykorzystujemy standard DOM do parsowania dokumentów XML, oraz
faktem, iż założeniem pracy było obsługiwanie tylko średniej wielkości dokumentów XML, do
przechowywanie elementów XML używamy standardowego dokumentu XML wytworzonego podczas
parsowania dokumentu XML przez parser XML. Wadą takiego rozwiązania jest stosunkowo wysokie,
zużycie pamięci, aczkolwiek przy dzisiejszych pojemnościach pamięci, dokumenty średniej wielkości
powinny bez problemów zmieścić się w pamięci współczesnego komputera.
10.2.Stos środowisk i rezultatów
Ponieważ podejście stosowe zakłada istnienie stosu środowisk konieczna było stworzenia tego typu
stosu w naszej implementacji języka zapytań. Zgodnie z założeniami podejścia stosowego dla języków
zapytań podstawowe założenia stosu środowisk to ([3]):
 Traktowanie w jednakowy sposób kolekcji i danych indywidualnych.
 Stos nie będzie zawierał wartości zmiennych, obiektów. Spowodowane jest to faktem, iż w
zakładanym podejściu odwołania do tego samego obiektu, mogą pojawiać się w wielu
miejscach stosu. Na stosie będą przechowywane tylko zbiory „binderów”.
 Stos będzie podzielony na sekcje zawierające pewne informacje o środowisku wykonania.
 Na dole stosu znajdować się będą sekcje globalne. Sekcje globalne to: baza danych, zmienne
środowiskowe systemu komputerowego, zmienne globalne, itp.
 Stos będzie w jednorodny sposób traktował zarówno dane ulotne jak i trwałe (znajdujące się w
bazie danych)
W naszej implementacji każda sekcja składa się z tablicy binderów, które to jako jedyna mogą
znajdować się na stosie środowisk. Na samym dole stosu znajduje się sekcja bazy danych. Nie
uznaliśmy za konieczne wprowadzanie sekcji ze zmiennymi środowiska komputerowego, ani sekcji
zez zmiennymi globalnymi. Dodanie takich sekcji jest relatywnie proste i nie powinno sprawić
większego problemu. W naszej implementacji sekcja bazy danych zawiera bindery z referencjami
wszystkich węzłów, od których możemy rozpocząć zapytania (ponieważ każdy plik XML musi mieć
jeden węzeł główny, dla każdego wczytanego pliku XML jest to jeden element). Dodatkowo w sekcji
bazy danych znajdują się bindery z referencjami do wszystkich węzłów (nietekstowych), nazwy tych
binderów rozpoczynają się od „ellipse ”. Umożliwia to wykonywanie zapytań eliptycznych, które
rozpoczynają się od „ellipse ”. Zapytanie eliptyczne w naszej implementacji zwraca wszystkie węzły o
nazwie zadanej po wyrażeniu „ellipse ”. Takie podejście cechuje się prostotą implementacji, a
ponieważ nazwy węzłów w XML nie mogą zawierać spacji, nie wystąpi sytuacja, w której nazwa
Strona 62
Język zapytań dla XML oparty na podejściu stosowym
węzła pokryje się z nazwą bindera używanego do wyrażeń eliptycznych. W naszej implementacji
dopuściliśmy następujące operacje na stosie środowisk:
 isEmpty – sprawdzenie czy stos jest pusty (nie zawiera żadnej sekcji).
 peek – pobiera tablicę binderów znajdującą się na wierzchołku stosu (null jeżeli stos jest
pusty)
 push(binder) - dodaje binder do sekcji znajdującej się na wierzchołku stosu. Jeżeli binder
o danej nazwie już istnieje w danej sekcji nie wykonywana jest żadna operacja.
 pushAndMerge(binder) – do sekcji znajdującej się na wierzchołku stosu. Jeżeli binder o
danej nazwie już istnieje w danej sekcji do binder dodawana jest kolejna referencja
powiązana z tym binderem.
 search(nazwa bindera).- wyszukuje binder o danej nazwie, rozpoczynając od wierzchołka
stosu. Jeżeli sekcja nie zawiera bindera o danej nazwie, przeszukiwana jest kolejna
sekcja znajdująca się bezpośrednio pod aktualnie przeglądaną sekcją. Jeżeli żadna
sekcja nie zawiera bindera o danej nazwie zwracany jest null.
 raiseStack – tworzy nową sekcję na wierzchołku stosu.
 lowerStack – usuwa sekcję z wierzchołka stosu, zwracając tablicę binderów z usuwanej
sekcji.
 getStackHeight – zwraca bieżącą wysokość stosu.
Równie istotny jak stos środowisk jest stos rezultatów. Na stosie tym odkładana są wyniki
działania operatorów. Także argumenty operatorów pobierane są ze stosu rezultatów. W naszej
implementacji na stosie rezultatów odkładane są tablice węzłów (ang. Notes). Węzły znajdujące się w
tablicach zgodne są ze standardem DOM.. Jedyne operacje wykonywane na stosie rezultatów to
pobranie i wstawienie tablicy węzłów. Z tego powodu jako stosu rezultatów użyliśmy standardowego
stosu dostarczanego wraz z językiem Java.
10.3.Bindery
Zgodnie z założeniami podejścia stosowego dla języków zapytań opracowanego przez
Kazimierza Subietę na stosie środowisk, muszą znajdować się bindery. Bindery używane są do
wiązania nazw występujących w zapytaniu na byty czasu wykonania (np. referencje, stałe itp.).
Oryginalnie binder był parą <n,x>, gdzie „n” było zewnętrzną nazwą (np. zmiennej, stałej, obiektu
itp.), a „x” bytem czasu wykonania (zwykle byłą to referencja do obiektu). W naszej implementacji
binder jest to para <n,k>, gdzie „n” jest również zewnętrzną nazwą, lecz „k” jest zbiorem węzłów w
rozumieniu DOM odpowiadających danej nazwie. Różnica wynikająca z tego jest taka, iż w naszym
przypadku w danej sekcji stosu środowisk może znajdować się najwyżej jeden binder o danej nazwie,
oraz w naszym przypadku bindery przechowują referencje do węzłów DOM. Operacje określone dla
bindera to:
 Tworzenie bindera o danej nazwie
 Dodawanie nowych referencji węzłów
 Pobieranie referencji węzłów
 Pobieranie nazwy bindera.
10.4.Zarządzanie referencjami
Podczas tworzenia języka zapytań, okazało się, że z powodu przyjętych założeń, co do składu
obiektów, występują problemy z zachowaniem identyczności referencji.
Strona 63
Język zapytań dla XML oparty na podejściu stosowym
10.4.1 Wpływ DOM na referencje.
Podczas ewaluacji zapytania często dochodzi do sytuacji, gdy musimy przepisać węzeł z
jednego dokumentu do innego. Operacja taka zachodzi często, ponieważ stos wyników w naszym
przypadku zawiera tylko i wyłącznie węzły w rozumieniu DOM. Operacje takie jak zmiana, nazwy,
tworzenie węzła opakowującego tworzonego np. podczas budowania struktur wymaga przepisania
węzła z jednego dokumentu do innego. Optymalnym rozwiązaniem w tym przypadku byłoby
przepisanie referencji do elementu. Niestety standard DOM nie zezwala na takie przenoszenie węzła z
dokumentu do dokumentu, ponieważ każdy węzeł ma przypisany do siebie dokument, do którego
należy. W związku z tym, aby przenieść element do innego dokumentu należy zaimportować węzeł.
Niestety operacja to powoduje stworzenie nowego węzła, o tej samej strukturze, lecz zupełnie innej
referencji. Powoduje to, że porównywanie takich węzłów referencyjnie nie ma większego sensu, co
więcej w przypadku dobudowania do aktualnego systemu operacji imperatywnych (np. aktualizacji,
usuwania) operacje takie mogą mieć bardzo ciekawe efekty (np. uaktualnienie tylko części węzłów,
które należałoby uaktualnić).
10.4.2 Dlaczego zarządzanie referencjami jest potrzebne.
Ponieważ chcieliśmy w naszym systemie zaimplementować porównywanie elementów poprzez
referencje a nie porównywanie struktury, konieczne okazało się zaimplementowanie dodatkowych
struktur danych pozwalających na pobieranie referencji oryginalnego obiektu dla obiektu
zaimportowanego. Dodatkowo posiadając możliwość zdobycia referencji oryginału, a także referencji
wszystkich klonów oryginału, możliwe jest zaimplementowanie operacji imperatywnych
dokonywanych na obiektach.
10.4.3 Opis zaimplementowanego rozwiązania
Rozwiązanie, które przyjęliśmy opiera się na dwóch tablicach pomocniczych struktur
składających się z numerycznego identyfikatora węzła oraz referencji do danego węzła. Jedna z tablic
zawiera węzły „oryginalne” tzn. takie, które tworzone są w momencie dodawania nowego pliku XML
do bazy danych. Są to wszystkie węzły, atrybuty znajdujące się w danym pliku XML. Ponadto,
ponieważ węzły XML nie muszą posiadać unikalnego identyfikatora, każdemu z elementów
dodawanych do tablicy „oryginałów” nadawany jest unikalny numer. Numer ten jest jednakowy
podczas całego czasu działania programu, aczkolwiek może być różny pomiędzy kolejnymi
wywołaniami programu. Kolejna tablica „klonów” zawiera struktury składające się z identyfikatora
oryginału (liczba nadawana podczas dodawania do tablicy „oryginałów”) oraz referencji do węzłaklonu. Wpisy do tablicy „klonów” dodawane są w momencie zaimportowaniu węzła. Ponieważ
możliwe jest importowanie węzła, który jest „klonem” w związku z tym przed właściwym
wstawieniem do tablicy, pobierany jest węzeł „oryginalny” dla węzła importowanego. Takie podejście
pozwala na bardzo łatwe przejście z modelu gdzie nie były zapamiętywane referencje do modelu je
obsługującego. W celu łatwiejszego tworzenia i utrzymania kodu, obsługa referencji do węzłów
znajduje się w oddzielnej klasie udostępniającej zestaw metod, do dodawania i pobierania referencji
do węzłów. Klasa ta udostępnia następujące metody:
 isClone(Node) – sprawdza czy węzeł podany jako parametr jest „klonem” (czy wektor
klonów zawiera element od danej referencji)
 isReal(Node) – sprawdza czy węzeł podany jako parametr jest „oryginałem” (czy wektor
oryginałów zawiera element od danej referencji)
 addClone(oryginal, klon) – dodaje nowy element do wektora „klonów”, zapisując
referencje klonu i identyfikator oryginału do wektora „klonów".
 getClones(node) – zwraca tablicę węzłów, będącymi klonami węzła podanego jako
parametr, lub też węzła będącego oryginalnym w stosunku do węzła podanego jako
parametr (jeżeli podany węzeł jest „klonem”). Wykonanie tej metody polega na
wyszukaniu węzła oryginalnego w stosunku do parametru (może to być ten sam węzeł)
Strona 64
Język zapytań dla XML oparty na podejściu stosowym
a następnie przeszukanie wektora „klonów” w celu znalezienia wszystkich elementów
będących „klonami” węzła oryginalnego. W związku z tym możliwe jest, istnienie w
wyniku metody węzła podanego jako parametr.
 getReal(node) – zwraca węzeł „oryginalny” w stosunku do węzła pobranego jako
parametr. Zwraca „null”, jeżeli węzeł podany jako parametr nie występuje ani w tablicy
„oryginałów” ani w tablicy „klonów”. Jeżeli węzeł będący parametrem jest już węzłem
„oryginalnym” zwracany jest ten węzeł.
 doCleanUp – powoduje wyczyszczenie tablicy „klonów”. Metoda ta wywoływana jest po
zakończeniu ewaluacji zapytania.
 addReal(node) – dodaje węzeł do wektora „oryginałów” nadając mu jednocześnie
unikalny identyfikator.
11. Rozwiązania implementacyjne – implementacja operatorów
algebraicznych
Operatory algebraiczne są operatorami niepodnoszącymi stosu środowisk. Operują one jedynie
na stosie rezultatów, używając (w zależności od operatora) jednego lub dwóch górnych elementów
tego stosu, i umieszczając wynik na szczycie stosu rezultatów.
Uwaga – na rysunkach ilustrujących działanie operatorów algebraicznych nie została pokazana
zawartość stosu środowisk – z punktu widzenia tych operatorów jest ona nieistotna.
11.1.Operatory arytmetyczne
Operatory arytmetyczne realizują podstawowe operacje arytmetyczne. Ogólnie przyjęte zasady
dotyczące kolejności działań (najsilniej wiąże „unarny -” potem mnożenie i dzielenie, następnie
dodawanie i odejmowanie) są przestrzegane.
11.1.1 Operatory „+”, „–„, „*”, „/”
Ilość argumentów: 2
Zachowanie:
Operator pobiera dwa górne elementy ze stosu rezultatów i wykonuje na nich
odpowiednie działanie arytmetyczne, jeżeli oba elementy mogą być
skonwertowane na typ liczbowy. W przeciwnym wypadku podnoszony jest
wyjątek TypeMismatchException. Wynik jest odkładany na stosie
rezultatów.
Strona 65
Język zapytań dla XML oparty na podejściu stosowym
Stos środowiskowy
Stos rezultatów
Przed
12
12
Stos środowiskowy
Stos rezultatów
Po
144
Rysunek 5 - 1 przykład działania operatora "*"
Uwagi:
Wyjątek rzucany przy próbie dodania wartości innych niż typy liczbowe
wynika z braku koncepcji, co konkretnie miałoby być wynikiem takiego
działania.
11.1.2 Operator „– unarny”
Ilość argumentów: 1
Zachowanie:
Operator pobiera górny element ze stosu rezultatów. Jeśli element może być
skonwertowany na typ liczbowy, element zostaje odjęty od 0 (zamiana
znaku), a następnie wynik zostaje odłożony na stos rezultatów.
Stos środowiskowy
Stos rezultatów
Przed
12
Stos środowiskowy
Stos rezultatów
Po
-12
Rysunek 5 - 2 przykład działania operatora "unarny -"
Uwagi:
Wyjątek rzucany przy próbie zanegowania wartości innych niż typy
liczbowe wynika z braku koncepcji, co konkretnie miałoby być wynikiem
takiego działania.
11.2.Operatory działające na łańcuchach tekstowych
11.2.1 Operator „&”
Ilość argumentów: 2
Zachowanie:
Operator pobiera dwa górne elementy ze stosu rezultatów. Oba są traktowane
jako łańcuchy tekstowe, zostają skonkatenowane, a wynik zostaje odłożony
na stos rezultatów. Jeśli przynajmniej jeden z elementów nie jest wartością
Strona 66
Język zapytań dla XML oparty na podejściu stosowym
atomową (jest węzłem o typie innym niż TEXT_NODE
CDATA_SECTION_NODE), konwersja na łańcuch tekstowy
niemożliwa i podnoszony jest wyjątek TypeMismatchException.
Stos środowiskowy
Przed
lub
jest
Stos rezultatów
‘cd’
‘ab’
Stos środowiskowy
Stos rezultatów
Po
‘abcd’
Rysunek 5 - 3 przykład działania operatora "&"
Uwagi:
Wyjątek rzucany przy próbie dodania wartości innych niż typy atomowe
wynika z braku koncepcji, co konkretnie miałoby być wynikiem takiej
„konkatenacji”.
11.3.Operatory logiczne
11.3.1 Operatory „AND”, „OR”
Ilość argumentów: 2
Zachowanie:
Operator pobiera dwa górne elementy ze stosu rezultatów. Jeśli oba są
łańcuchami tekstowymi, równymi (z dokładnością do wielkości znaków) true
(dla prawdy) lub false (dla fałszu), na odpowiadającym im wartościom
logicznym wykonywana jest odpowiednia operacja logiczna, a następnie
wynik skonwertowany na łańcuch tekstowy odkładany jest na stos. Jeśli
chociaż jeden z pobranych elementów nie jest łańcuchem tekstowym, lub
jego wartość jest inna niż true lub false, podnoszony jest wyjątek
TypeMismatchException.
Strona 67
Język zapytań dla XML oparty na podejściu stosowym
Stos środowiskowy
Przed
Stos rezultatów
‘true’
‘false’
Stos środowiskowy
Stos rezultatów
Po
‘false’
Rysunek 5 - 4 przykład działania operatora "AND"
Uwagi:
Przyjęte rozwiązanie wprowadzające możliwość obsługi wartości logicznych
jest jednym z kilku możliwych. Podobnie jak pozostałe prowadzi do różnego
rodzaju problemów (takich jak możliwość przypadkowego wstawienia do
pliku XML w miejsca, w których użytkownik oczekuje wartości
„logicznych” innych danych. Umiejętne wykorzystanie DTD lub XML
Schema może pozwolić na uniknięcie przynajmniej części problemów).
11.3.2 Operator „!”
Ilość argumentów: 1
Zachowanie:
Operator pobiera górny element ze stosu rezultatów. Jeśli jest on łańcuchem
tekstowym, równym (z dokładnością do wielkości znaków) true (dla prawdy)
lub false (dla fałszu), na odpowiadającej wartości logicznej zostaje
wykonana operacja negacji, a wynik skonwertowany na łańcuch tekstowy
odkładany jest na stos. Jeśli pobrany element nie jest łańcuchem tekstowym,
lub jego wartość jest inna niż true lub false, podnoszony jest wyjątek
TypeMismatchException.
Stos środowiskowy
Stos rezultatów
Przed
‘false’
Stos środowiskowy
Stos rezultatów
Po
‘true’
Rysunek 5 - 5 przykład działania operatora "!"
Uwagi:
Do tego operatora odnoszą się te same uwagi, co do operatorów „AND” i
„OR”
Strona 68
Język zapytań dla XML oparty na podejściu stosowym
11.4.Operatory porównań
11.4.1 Operator„=”
Ilość argumentów: 2
Zachowanie:
Operator pobiera dwa górne elementy ze stosu rezultatów. Jeśli oba mogą
zostać skonwertowane na typ liczbowy, są konwertowane i porównywane
jako liczby. Jeśli konwersja na typ liczbowy jest niemożliwa, ale możliwe
jest potraktowanie obu elementów jako łańcuchów tekstowych, elementy są
porównywane jako łańcuchy tekstowe. W przeciwnym wypadku
porównywane są referencje do elementów. Wynik porównania (true/false),
zamieniony na łańcuch tekstowy umieszczany jest na stosie rezultatów. Jeśli
przynajmniej jeden z pobranych elementów jest tablicą o długości większej
niż 1, podnoszony jest wyjątek TypeMismatchException.
Stos środowiskowy
Stos rezultatów
Przed
12
12
Stos środowiskowy
Stos rezultatów
Po
‘true’
Rysunek 5 - 6 przykład działania operatora "="
Uwagi:
Porównywanie referencji odbywa się zgodnie z zasadami opisanymi w części
dotyczącej struktur danych.
11.4.2 Operatory „<”, „>”
Ilość argumentów: 2
Zachowanie:
Operator pobiera dwa górne elementy ze stosu rezultatów. Jeśli oba mogą
zostać skonwertowane na typ liczbowy, są konwertowane i porównywane
jako liczby. Jeśli konwersja na typ liczbowy jest niemożliwa, ale możliwe
jest potraktowanie obu elementów jako łańcuchów tekstowych, elementy są
porównywane jako łańcuchy tekstowe – elementy większe są łańcuchami
tekstowymi dalszymi w porządku alfabetycznym. W przeciwnym wypadku
podnoszony jest wyjątek TypeMismatchException. Wynik porównania
(true/false), zamieniony na łańcuch tekstowy umieszczany jest na stosie
rezultatów. Jeśli przynajmniej jeden z pobranych elementów jest tablicą o
długości większej niż 1, podnoszony jest wyjątek TypeMismatchException.
Strona 69
Język zapytań dla XML oparty na podejściu stosowym
Stos środowiskowy
Stos rezultatów
Przed
13
12
Stos środowiskowy
Stos rezultatów
Po
‘false’
Rysunek 5 - 7 przykład działania operatora ">"
Uwagi:
Wynik porównania łańcuchów tekstowych może zależeć od wersji systemu
operacyjnego, JRE, lokalnych ustawień i innych czynników.
11.4.3 Operator „!=”
Ilość argumentów: 2
Zachowanie:
Operator wywołuje najpierw operator „=” a następnie operator „!”.
Stos środowiskowy
Stos rezultatów
Przed
12
12
Stos środowiskowy
Stos rezultatów
Po
‘false’
Rysunek 5 - 8 przykład działania operatora "!="
Uwagi:
Informacje odnoszące się do działania operatorów „=” i „!” odnoszą się
również do działania tego operatora.
11.4.4 Operatory „<=”, „>=”
Ilość argumentów: 2
Zachowanie:
Najpierw wywoływany jest odpowiedni operator („>” dla „<=”, „<” dla
„>=”) a następnie operator „!”.
Strona 70
Język zapytań dla XML oparty na podejściu stosowym
Stos środowiskowy
Stos rezultatów
Przed
12
12
Stos środowiskowy
Stos rezultatów
Po
‘true’
Rysunek 5 - 9 przykład działania operatora ">="
Uwagi:
Informacje odnoszące się do działania operatorów „>”, „<” i „!” odnoszą się
również do działania tego operatora.
11.5.Operatory działające na kolekcjach
11.5.1 Operator „count”
Ilość argumentów: 1
Zachowanie:
Operator pobiera górny element ze stosu rezultatów i zlicza zawarte w nim
węzły, wartości liczbowe i tekstowe (bez schodzenia w dół ich struktury)
jakie zawiera ten element. Wynik – ilość znalezionych węzłów - zostaje
zwrócony na stos rezultatów.
Stos środowiskowy
Stos rezultatów
Przed
<pracownik>Kowalski</pracownik>
<pracownik>Malinowski</pracownik>
<pracownik>Wierzbowski</
pracownik>
Stos środowiskowy
Stos rezultatów
Po
3
Rysunek 5 - 10 przykład działania operatora "count"
Uwagi:
11.5.2 Operator „exists”
Ilość argumentów: 1
Zachowanie:
Operator pobiera górny element ze stosu rezultatów. Jeśli element ten jest
niepusty (zawiera przynajmniej jeden węzeł, wartość liczbową lub tekstową)
zwraca na stos rezultatów wartość logiczną true, w przeciwnym wypadku
Strona 71
Język zapytań dla XML oparty na podejściu stosowym
zwraca wartość logiczną false (wartości te są skonwertowane na łańcuchy
tekstowe).
Stos środowiskowy
Stos rezultatów
Przed
<pracownik>Kowalski</pracownik>
<pracownik>Malinowski</pracownik>
<pracownik>Wierzbowski</
pracownik>
Stos środowiskowy
Stos rezultatów
Po
‘true’
Rysunek 5 - 11 przykład działania operatora "exists"
Uwagi:
11.5.3 Operator „sum”
Ilość argumentów: 1
Zachowanie:
Operator pobiera górny element ze stosu rezultatów i sumuje zawarte w nim
wartości liczbowe. Jeśli napotka węzeł lub wartość tekstową, podnosi
wyjątek TypeMismatchException. Wynik – suma - zostaje zwrócony na stos
rezultatów.
Stos środowiskowy
Przed
Stos rezultatów
2
3
3.4
4
12
Stos środowiskowy
Stos rezultatów
Po
24.4
Rysunek 5 - 12 przykład działania operatora "sum"
Uwagi:
11.6.Operatory zmiany nazwy
11.6.1 Operator „as”
Ilość argumentów: 2
Strona 72
Język zapytań dla XML oparty na podejściu stosowym
Zachowanie:
Operator pobiera dwa górne elementy ze stosu rezultatów. Element
znajdujący się na szczycie stosu rezultatów traktowany jest jako łańcuch
tekstowy odpowiadający nowej nazwie. Element znajdujący się bezpośrednio
pod nim zawiera tablicę węzłów, których nazwa ma ulec zmianie. Następnie
stworzone zostają węzły odpowiadające węzłom oryginalnym. Dodatkowo w
celu umożliwienia porównywania referencyjnego oryginału z węzłem o
zmienionej nazwie (jest on tworzony, w związku inna jest jego referencja),
dodajemy do klasy ReferenceManager informacje o tym, że nowo utworzone
węzły są klonami już istniejących. Operator odkłada na stosie rezultatów
tablicę węzłów o nowej nazwie. Liczba węzłów w zwracanej tablicy jest
równa liczbie węzłów, którym zmieniono nazwę.
Stos środowiskowy
Przed
Stos rezultatów
‘x’
<pracownik>Kowalski</pracownik>
Stos środowiskowy
Stos rezultatów
Po
<x>Kowalski</x>
Rysunek 5 - 13 przykład działania operatora "as"
Uwagi:
11.6.2 Operator „group as”
Ilość argumentów: 2
Zachowanie:
Operator pobiera dwa górne elementy ze stosu rezultatów. Element
znajdujący się na szczycie stosu rezultatów traktowany jest jako łańcuch
tekstowy odpowiadający nowej nazwie. Element znajdujący się bezpośrednio
pod nim zawiera tablicę węzłów, których mają znaleźć się węźle o nowej
nazwie. Następnie tworzony jest nowy węzeł o nowej nazwie. W kolejnym
kroku wszystkie węzły podane jako drugi operator dodawane są jako
elementy-dzieci do nowego węzła. Operator odkłada na stosie rezultatów
jednoelementową tablicę zawierającą nowo utworzony węzeł.
Strona 73
Język zapytań dla XML oparty na podejściu stosowym
Stos środowiskowy
Przed
Stos rezultatów
‘x’
<pracownik>Kowalski</pracownik>
<pracownik>Malinowski</pracownik>
Stos środowiskowy
Po
Stos rezultatów
<x>
<pracownik>Kowalski</pracownik>
<pracownik>Malinowski</pracownik>
</x>
Rysunek 5 - 14 przykład działania operatora "group as"
Uwagi:
11.7.Złączenia
11.7.1 Operator „,”
Ilość argumentów: 2
Zachowanie:
Operator pobiera dwa górne elementy ze stosu rezultatów. Oba są traktowane
jako tablice węzłów. Wynikiem działania jest tablica węzłów o nazwie
„StructNode”. Każdy z węzłów „StructNode” odpowiada jednemu z
wyników zmodyfikowanego iloczynu kartezjańskiego (patrz Uwagi)
parametrów. Na stos rezultatów odkładana jest tablica węzłów „StructNode”.
Jeżeli aktualnie przetwarzany element jest typu „StructNode” to wtedy
zamiast niego używana jest tablica wszystkich węzłów-dzieci znajdujących
się w tym aktualnie przetwarzanym elemencie.
Stos środowiskowy
Przed
Stos rezultatów
<firma>Pracodawca S.A.<firma>
<pracownik>Kowalski</pracownik>
<pracownik>Malinowski</pracownik>
Stos środowiskowy
Stos rezultatów
<StructNode>
<pracownik>Kowalski</pracownik>
<firma>Pracodawca S.A.<firma>
</StructNode>
<StructNode>
<pracownik>Malinowski</pracownik>
<firma>Pracodawca S.A.<firma>
</StructNode>
Po
Rysunek 5 - 15 przykład działania operatora ","
Strona 74
Język zapytań dla XML oparty na podejściu stosowym
Uwagi:
Różnica w działaniu tego operatora ze standardowym iloczynem
kartezjańskim polega na tym, że gdy jeden z elementów jest pusty, iloczyn
kartezjański zwraca zbiór pusty, natomiast operator „,” zwraca tablicę
węzłów „StructNode”, w których znajdują się pojedyncze elementy
niepustego zbioru.
12. Rozwiązania implementacyjne – implementacja operatorów
nie-algebraicznych
Operatory nie-algebraiczne stanowią istotę podejścia stosowego. Podstawową różnica między
nimi a operatorami algebraicznymi jest wykonywanie operacji na stosie środowisk.
12.1.Operatory selekcji
12.1.1 Operator „where”
Ilość argumentów: 2
Zachowanie:
Operator pobiera górny element ze stosu rezultatów, jako drugi argument
otrzymuje poddrzewo rozbioru gramatycznego zapytania. Dla każdej
wartości (węzła, wartości liczbowej, łańcucha tekstowego) z pobranego
elementu ewaluuje otrzymane podzapytanie. Jeśli w wyniku ewaluacji
podzapytania dla danego elementu otrzymano przynajmniej jeden łańcuch
tekstowy o wartości true, dana wartość dodawana jest do zbioru wyników.
Następnie otrzymany zbiór wyników odkładany jest na stos rezultatów.
Stos środowiskowy
Stos rezultatów
Przed
<pracownik>Kowalski</pracownik>
<pracownik>Malinowski</pracownik>
Stos środowiskowy
Podczas
Po
Stos rezultatów
<TextValue>Kowalski</TextValue>
<pracownik>Kowalski</pracownik>
<pracownik>Malinowski</pracownik>
‘true’
<pracownik>Kowalski</pracownik>
<pracownik>Malinowski</pracownik>
<pracownik>Kowalski</pracownik>
Rysunek 5 - 16 przykład działania operatora "where"
Uwagi:
Strona 75
Język zapytań dla XML oparty na podejściu stosowym
12.2.Kwantyfikatory
12.2.1 Operator „for any holds”
Ilość argumentów: 2
Zachowanie:
Operator pobiera górny element ze stosu rezultatów, jako drugi argument
otrzymuje poddrzewo rozbioru gramatycznego zapytania. Dla każdej
wartości (węzła, wartości liczbowej, łańcucha tekstowego) z pobranego
elementu podnosi stos środowisk, wstawiając jego zawartość na szczyt tego
stosu, a następnie ewaluuje otrzymane podzapytanie. Jeśli w wyniku
ewaluacji podzapytania dla dowolnego elementu otrzymano przynajmniej
jeden łańcuch tekstowy o wartości true, operator zwraca na stos rezultatów
wartość true (zamienioną na łańcuch tekstowy), w przeciwnym wypadku
zwraca wartość false.
Stos środowiskowy
Stos rezultatów
Przed
<pracownik>Kowalski</pracownik>
<pracownik>Malinowski</pracownik>
Stos środowiskowy
Podczas
Stos rezultatów
<TextValue>Kowalski</TextValue>
Po
<pracownik>Kowalski</pracownik>
<pracownik>Malinowski</pracownik>
‘true’
<pracownik>Kowalski</pracownik>
<pracownik>Malinowski</pracownik>
‘true’
Rysunek 5 - 17 przykład działania operatora "for any holds"
Uwagi:
12.2.2 Operator „for all holds”
Ilość argumentów: 2
Zachowanie:
Operator pobiera górny element ze stosu rezultatów, jako drugi argument
otrzymuje poddrzewo rozbioru gramatycznego zapytania. Dla każdej
wartości (węzła, wartości liczbowej, łańcucha tekstowego) z pobranego
elementu podnosi stos środowisk, wstawiając jego zawartość na szczyt tego
stosu, a następnie ewaluuje otrzymane podzapytanie. Jeśli w wyniku
ewaluacji podzapytania dla każdego z elementów otrzymano przynajmniej
jeden łańcuch tekstowy o wartości true, operator zwraca na stos rezultatów
wartość true (zamienioną na łańcuch tekstowy), w przeciwnym wypadku
zwraca wartość false.
Strona 76
Język zapytań dla XML oparty na podejściu stosowym
Stos środowiskowy
Stos rezultatów
Przed
<pracownik>Kowalski</pracownik>
<pracownik>Malinowski</pracownik>
Stos środowiskowy
Podczas
Stos rezultatów
<TextValue>Kowalski</TextValue>
Po
<pracownik>Kowalski</pracownik>
<pracownik>Malinowski</pracownik>
‘false’
<pracownik>Kowalski</pracownik>
<pracownik>Malinowski</pracownik>
‘false’
Rysunek 5 - 18 przykład działania operatora "for all holds"
Uwagi:
12.3.Złączenia
12.3.1 Operator „depjoin”
Ilość argumentów: 2
Zachowanie:
Operator nie-algebraiczny realizujący zależne złączenie. Dla każdego
elementu z pierwszego parametru podnoszony jest stos środowisk, na który
wstawiane są bindery z wnętrza elementu. Następnie względem takiego stosu
środowisk, wykonywane jest pod-zapytanie. Wynik tego pod-zapytania jest
łączony poprzez węzeł „StructNode” z aktualnie przetwarzanym elementem
z pierwszego parametru. Po wykonaniu operatora na stosie wyników
znajduje się tablica węzłów typu „StructNode”.
Strona 77
Język zapytań dla XML oparty na podejściu stosowym
Stos środowiskowy
Stos rezultatów
Przed
<pracownik>Kowalski</pracownik>
<pracownik>Malinowski</pracownik>
Stos środowiskowy
Podczas
Stos rezultatów
<TextValue>Kowalski</TextValue>
<pracownik>Kowalski</pracownik>
<pracownik>Malinowski</pracownik>
Po
<pracownik>Kowalski</pracownik>
<pracownik>Malinowski</pracownik>
<StructNode>
‘Kowalski’
<pracownik>Kowalski</pracownik>
</StructNode>
<StructNode>
‘Malinowski’
<pracownik>Malinowski</pracownik>
</StructNode>
Rysunek 5 - 19 przykład działania operatora "depjoin"
Uwagi:
12.4.Inne operatory
12.4.1 Operator „.”
Ilość argumentów: 2
Zachowanie:
Operator pobiera górny element ze stosu rezultatów, jako drugi argument
otrzymuje poddrzewo rozbioru gramatycznego zapytania. Dla każdej
wartości (węzła, wartości liczbowej, łańcucha tekstowego) z pobranego
elementu podnosi stos środowisk, wstawiając jego zawartość na szczyt tego
stosu, a następnie ewaluuje podzapytanie. Wyniki ewaluacji podzapytania
dodawane są do zbioru rezultatów, który na koniec ewaluacji umieszczany
jest na stosie rezultatów.
Strona 78
Język zapytań dla XML oparty na podejściu stosowym
Stos środowiskowy
Stos rezultatów
Przed
<pracownik>Kowalski</pracownik>
<pracownik>Malinowski</pracownik>
Stos środowiskowy
Podczas
Stos rezultatów
<TextValue>Kowalski</TextValue>
<pracownik>Kowalski</pracownik>
<pracownik>Malinowski</pracownik>
Po
<pracownik>Kowalski</pracownik>
<pracownik>Malinowski</pracownik>
‘Kowalski’
Rysunek 5 - 20 przykład działania operatora "."
Uwagi:
Implementacja tego operatora różni się od istniejącej w SBQL – w
szczególności zapytania typu „zapytanie.” nie jest poprawnym zapytaniem.
Ten sposób implementacji nie ogranicza znacząco możliwości ekspresji
języka (jedyną klasą zapytań, jaka nie może zostać zadana jest ta z
powyższego przykładu), zwiększając jednocześnie czytelność kodu i
zapytań.
13. Rozwiązania implementacyjne – operacje ellipse i $
W języku zaimplementowano również dwa dodatkowe sposoby wiązania do elementów na
stosie środowisk (dla wygody nazwane operacjami). Poniżej znajduje się opis ich implementacji.
13.1.Implementacja operacji
13.1.1 Operacja ellipse
Operacja ellipse realizowana jest przez wykorzystanie stosu środowisk. Podczas wstępnego
przechodzenia drzewa tworzone są na spodzie stosu środowisk bindery do węzła będącego
„korzeniem” dokumentu XML oraz do wszystkich węzłów znajdujących się w dokumencie XML.
Binder do węzła będącego korzeniem jest tworzony zarówno pod nazwą tożsamą z nazwą węzła (np.
baza_pracowników), jak i pod nazwą ellipse nazwa_węzła (np. ellipse baza_pracowników). Bindery
do wszystkich pozostałych węzłów tworzone są tylko pod nazwą ellipse nazwa_węzła. Jako że XML
nie dopuszcza nazw tagów lub atrybutów o nazwach zawierających spację, nie ma możliwości
utworzenia bindera o takiej nazwie poprzez jakiekolwiek operacje w ramach języka zapytań (np. przy
operacji „as” podniesiony zostanie przez parser DOM wyjątek informujący o próbie nadania
niedozwolonej nazwy). Podczas parsowania zapytania wyrażenie ellipse identyfikator zostanie
Strona 79
Język zapytań dla XML oparty na podejściu stosowym
rozpoznane jako identyfikator węzła, a następnie związane na spodzie stosu środowisk (w jedynym
miejscu, w którym wystąpi).
13.1.2 Operacja $
Jeśli identyfikator węzła rozpoczyna się znakiem $, metoda PutTableOnStack rozpozna nazwę
jako mającą być wiązaną płytko – tylko na szczycie stosu środowisk i odpowiednio ograniczy zakres
poszukiwania węzłów o tej nazwie.
13.2.O czym należy pamiętać przy rozszerzaniu funkcjonalności języka o
operacje aktualizacji
W razie rozszerzania języka o operacje aktualizacji należy pamiętać o dodaniu bindera do węzła
o nazwie ellipse nazwa_węzła przy dodawaniu nowych węzłów do bazy – w przeciwnym wypadku
niemożliwe będzie dotarcie do tych węzłów przy pomocy operacji ellipse. Podobnie w wypadku
zmiany nazw węzłów należy usunąć jeden binder i dodać drugi.
14. Rozwiązania implementacyjne – implementacja linków
Poniżej znajduje się opis struktur danych i algorytmów użytych w celu wprowadzenia obsługi
linków do języka zapytań.
14.1.Zebranie informacji o węzłach z identyfikatorami
Podczas ładowania pliku XML obchodzone jest całe drzewo XML. Jedną z czynności
wykonywanych podczas obchodzenia drzewa jest zebranie identyfikatorów węzłów (wartości ich
atrybutów id) i referencji do nich. Jeśli identyfikator jest już umieszczony w wektorze idVector,
oznacza to iż obiekt o danym identyfikatorze istnieje już w systemie i obsługa linków zostaje
wyłączona. W przeciwnym wypadku identyfikatory dodawane są do wektora idVector, zaś referencje
do węzła umieszczone zostają w tablicy haszującej relatedNodes, z numerem węzła jako
identyfikatorem.
14.2.Obsługa linków w trakcie wykonywania zapytań
Podczas wykonywania metody getInnards, wywoływanej przez każdy operator niealgebraiczny, analizowane jest wnętrze węzła. Jeśli węzeł ma atrybut pointer o wartości true (z
dokładnością do wielkości liter), a obsługa linków jest włączona, w tablicy haszującej relatedNodes
wyszukiwany jest węzeł o identyfikatorze (wartości atrybutu id) równym danej tekstowej (TextValue)
zawartej w węźle. Jeśli taki węzeł zostanie znaleziony, zostaje on umieszczony na stosie środowisk
razem z innymi węzłami potomnymi.
14.3.O czym należy pamiętać przy rozszerzaniu funkcjonalności języka o
operacje aktualizacji
Przy rozszerzaniu języka o operacje aktualizacji należy pamiętać o aktualizacji wektora
idVector, tablicy haszującej relatedNodes oraz zmiennej logicznej useRelations w wypadku, gdy
dokonywane są operacje na węzłach posiadających identyfikatory. W wyniku operacji
aktualizacyjnych identyfikatory mogą ulec zmianie, powstać nowe obiekty posiadające identyfikatory,
mogą też zostać usunięte już istniejące obiekty z identyfikatorami.
Strona 80
Język zapytań dla XML oparty na podejściu stosowym
15. Rozwiązania implementacyjne – interpretacja zapytań
Parser zapytań został zrealizowany przy pomocy narzędzi JFlex i CUP. Łańcuch tekstowy z
treścią zapytania zostaje przez parser zamieniony na drzewo rozbioru gramatycznego.
15.1.Konstrukcja skanera
Skaner został stworzony przy pomocy narzędzia JFlex. Narzędzie to generuje skanery
wykorzystujące automaty skończone to dopasowywania łańcuchów tekstowych do wzorców,
zdefiniowanych przy pomocy wyrażeń regularnych. Szczegółowe informacje o zasadach działania
JFlex i innych narzędzi tej klasy znajdują się w dokumentacji tego programu. Plik z definicją wzorców
użyty do wygenerowania skanera za pomocą JFlex znajduje się poniżej.
package edu.t2r.magisterka;
import java_cup.runtime.Symbol;
%%
%class Lexer
%unicode
%ignorecase
%cup
%implements sym
%{
private Symbol sym(int sym) {
return new Symbol(sym);
}
private Symbol sym(int sym, Object val) {
return new Symbol(sym, val);
}
%}
/* floating point literals */
DoubleLiteral = ({FLit1}|{FLit2}|{FLit3}) {Exponent}?
FLit1
= [0-9]+ \. [0-9]*
FLit2
= \. [0-9]+
FLit3
= [0-9]+
Exponent = [eE] [+-]? [0-9]+
/*string literal*/
StringLiteral = '[^']*'
/*table identifier*/
Shallow = \$
Deep = "ellipse "
Identifier = ({Shallow}|{Deep})?[:jletter:][:jletterdigit:]*
%%
<YYINITIAL> {
"+" { return (sym(OP_ADD)); }
"-" { return (sym(OP_SUB)); }
"*" { return (sym(OP_MUL)); }
"/" { return (sym(OP_DIV)); }
"," { return (sym(COMMA)); }
"(" { return (sym(LPAR)); }
Strona 81
Język zapytań dla XML oparty na podejściu stosowym
")" { return (sym(RPAR)); }
"&" { return (sym(OP_CONC)); }
">=" { return (sym(OP_GRQ)); }
"<=" { return (sym(OP_LEQ)); }
"=" { return (sym(OP_EQ)); }
"!=" { return (sym(OP_NEQ)); }
">" { return (sym(OP_GR)); }
"<" { return (sym(OP_LE)); }
"!" { return (sym(OP_NOT)); }
"AND" {return (sym(OP_AND));}
"OR" {return (sym(OP_OR));}
"FOR ANY" { return (sym(OP_FORANY)); }
"FOR ALL" { return (sym(OP_FORALL)); }
"HOLDS" { return (sym(OP_HOLDS)); }
"EXISTS" { return (sym(OP_EXISTS)); }
"WHERE" { return (sym(OP_WHERE)); }
"COUNT" { return (sym(OP_COUNT)); }
"SUM" { return (sym(OP_SUM)); }
"AS" { return (sym(OP_AS)); }
"DEPJOIN" { return (sym(OP_DEPJOIN)); }
"GROUP AS" { return (sym(OP_GROUPAS)); }
"." { return (sym(DOT)); }
{DoubleLiteral} { return (sym(DOUBLE_LITERAL,yytext())); }
{Identifier} {return(sym(TABLE_ID,yytext())); }
{StringLiteral} {return(sym(STRING_LITERAL,yytext())); }
" " {}
. {throw new Error("Ilegal character <"+yytext()+">");}
}
15.2.Konstrukcja parsera
Parser został stworzony przy pomocy narzędzia CUP. Narzędzie to generuje parsery typu
LALR(1) na podstawie dostarczonej definicji gramatyki. Jako że dla każdej konstrukcji gramatycznej
możliwe jest zdefiniowanie podejmowanych akcji, możliwości parserów stworzonych w ten sposób są
w zasadzie zależne tylko od programisty. Proponowane rozwiązanie opiera się na konstrukcji drzewa
rozbioru gramatycznego – rozwiązanie to umożliwia przyszłą rozbudowę systemu o optymalizację
zapytań na drodze analizy i przekształcania drzewa rozbioru. Plik z definicją gramatyki użyty do
wygenerowania parsera za pomocą CUP znajduje się poniżej.
package edu.t2r.magisterka;
//arithmetic operators
terminal OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_UMINUS;
//text operator
terminal OP_CONC;
//comparision operators
terminal OP_EQ, OP_NEQ, OP_LE, OP_GR, OP_LEQ, OP_GRQ;
//boolean operators
terminal OP_AND, OP_OR, OP_NOT;
//collection operators
terminal OP_COUNT, OP_EXISTS, OP_SUM;
//selection operator and quantifiers
terminal OP_WHERE, OP_FORANY, OP_FORALL, OP_AS, OP_DEPJOIN,
OP_GROUPAS, OP_HOLDS;
//parenthesis et al
Strona 82
Język zapytań dla XML oparty na podejściu stosowym
terminal LPAR, RPAR, COMMA, DOT;
//literals and table identifiers
terminal STRING_LITERAL, DOUBLE_LITERAL, TABLE_ID;
//query tree root
non terminal TreeNode queryel;
//binary operator
non terminal BinaryOperator binop;
//unary operator
non terminal UnaryOperator unop;
non terminal LiteralValue stringLiteral;
non terminal LiteralValue tableLiteral;
non terminal LiteralValue doubleLiteral;
//precendence lists
//selection and quantifiers go last
precedence left OP_WHERE, OP_FORANY, OP_FORALL, OP_DEPJOIN;
precedence left COMMA;
//logical operators go third
precedence left OP_AND, OP_OR;
precedence left OP_EQ, OP_NEQ, OP_LE, OP_LEQ, OP_GR, OP_GRQ;
//arithmetic operators go second
precedence left OP_ADD, OP_SUB;
precedence left OP_MUL, OP_DIV;
precedence left OP_CONC;
//unary operators go first
precedence left OP_GROUPAS, OP_AS;
precedence left OP_UMINUS;
precedence left OP_SUM, OP_COUNT, OP_EXISTS;
precedence left OP_NOT;
precedence left DOT;
//rules
//query ::= DOUBLE_LITERAL binop DOUBLE LITERAL {::};
queryel ::=
stringLiteral:l {: RESULT = new TreeNode (l); :}|
doubleLiteral:l {: RESULT = new TreeNode (l); :}|
tableLiteral:l {: RESULT = new TreeNode (l); :}|
LPAR queryel:l RPAR {: RESULT = new TreeNode (l);
:}|
binop:l {: RESULT = new TreeNode (l); :}|
unop:l {: RESULT = new TreeNode (l); :};
Strona 83
Język zapytań dla XML oparty na podejściu stosowym
stringLiteral ::=
STRING_LITERAL:l {: RESULT = new LiteralValue
((String)l,sym.STRING_LITERAL); System.out.println("STRING:"+l); :};
doubleLiteral ::=
DOUBLE_LITERAL:l {: RESULT = new LiteralValue
((String)l,sym.DOUBLE_LITERAL); System.out.println("DOUBLE:"+l); :};
tableLiteral ::=
TABLE_ID:l {: RESULT = new LiteralValue
((String)l,sym.TABLE_ID); System.out.println("TABLE:"+l); :};
binop ::= queryel:l OP_ADD queryel:r {: RESULT = new BinaryOperator
(l,r,sym.OP_ADD); :}|
queryel:l OP_SUB queryel:r {: RESULT = new
BinaryOperator (l,r,sym.OP_SUB); :}|
queryel:l OP_DIV queryel:r {: RESULT = new
BinaryOperator (l,r,sym.OP_DIV); :}|
queryel:l OP_CONC queryel:r {: RESULT = new
BinaryOperator (l,r,sym.OP_CONC); :}|
queryel:l OP_MUL queryel:r {: RESULT = new
BinaryOperator (l,r,sym.OP_MUL); :}|
queryel:l OP_EQ queryel:r {: RESULT = new
BinaryOperator (l,r,sym.OP_EQ); :}|
queryel:l OP_NEQ queryel:r {: RESULT = new
BinaryOperator (l,r,sym.OP_NEQ); :}|
queryel:l OP_LE queryel:r {: RESULT = new
BinaryOperator (l,r,sym.OP_LE); :}|
queryel:l OP_LEQ queryel:r {: RESULT = new
BinaryOperator (l,r,sym.OP_LEQ); :}|
queryel:l OP_GR queryel:r {: RESULT = new
BinaryOperator (l,r,sym.OP_GR); :}|
queryel:l OP_GRQ queryel:r {: RESULT = new
BinaryOperator (l,r,sym.OP_GRQ); :}|
queryel:l OP_AND queryel:r {: RESULT = new
BinaryOperator (l,r,sym.OP_AND); :}|
queryel:l OP_OR queryel:r {: RESULT = new
BinaryOperator (l,r,sym.OP_OR); :}|
queryel:l OP_WHERE queryel:r {: RESULT = new
BinaryOperator (l,r,sym.OP_WHERE); :}|
OP_FORANY queryel:l OP_HOLDS queryel:r {: RESULT =
new BinaryOperator (l,r,sym.OP_FORANY); :}|
OP_FORALL queryel:l OP_HOLDS queryel:r {: RESULT =
new BinaryOperator (l,r,sym.OP_FORALL); :}|
queryel:l COMMA queryel:r {: RESULT = new
BinaryOperator (l,r,sym.COMMA); :}|
queryel:l OP_AS tableLiteral:r {: RESULT = new
BinaryOperator (l,r,sym.OP_AS); r.opcode=sym.STRING_LITERAL; :}|
queryel:l DOT queryel:r {: RESULT = new
BinaryOperator (l,r,sym.DOT); :}|
queryel:l OP_DEPJOIN queryel:r {: RESULT = new
BinaryOperator (l,r,sym.OP_DEPJOIN); :}|
queryel:l OP_GROUPAS tableLiteral:r {: RESULT = new
BinaryOperator (l,r,sym.OP_GROUPAS); r.opcode=sym.STRING_LITERAL;
:};
unop ::=
OP_COUNT queryel:l {: RESULT = new UnaryOperator
(l,sym.OP_COUNT); :}|
OP_EXISTS queryel:l {: RESULT = new UnaryOperator
(l,sym.OP_EXISTS); :}|
Strona 84
Język zapytań dla XML oparty na podejściu stosowym
OP_NOT queryel:l {: RESULT = new UnaryOperator
(l,sym.OP_NOT); :}|
OP_SUM queryel:l {: RESULT = new UnaryOperator
(l,sym.OP_SUM); :}|
OP_SUB queryel:l {: RESULT = new UnaryOperator
(l,sym.OP_UMINUS); :};
15.3.Konstrukcja drzewa rozbioru gramatycznego
Parser zwraca drzewo rozbioru gramatycznego, zbudowane z obiektów należących do czterech
klas:
 TreeNode – obiekty typu TreeNode to elementy, których napotkanie nie pociąga za sobą
żadnej akcji poza zejściem na niższy poziom drzewa. Obiekty tego typu tworzone są
przy napotkaniu konstrukcji takich jak nawiasy – są one konieczne, ze względu na
sposób, w jaki zorganizowany jest proces budowy drzewa. Mogłyby być one po
zbudowaniu drzewa usuwane, jednak operacja taka pociągałaby za sobą dodatkowy
koszt (obejście całego drzewa), wyższy od kosztu zachowania ich w strukturze drzewa.
Jeśli w przyszłości zostanie zaimplementowana optymalizacja zapytań przez
przebudowę drzewa, węzły typu TreeNode będą mogły być usuwane w ramach tego
procesu.
 UnaryOperator – obiekty typu UnaryOperator reprezentują operatory jednoargumentowe.
Obiekty tego typu tworzone są przy napotkaniu konstrukcji takich jak operatory „!” lub
„unarny –”.
 BinaryOperator – obiekty typu BinaryOperator reprezentują operatory dwuargumentowe.
Obiekty tego typu tworzone są przy napotkaniu konstrukcji takich jak operatory „+”
lub „where”.
 LiteralValue – obiekty typu LiteralValue reprezentują liście drzewa, będące wartościami
liczbowymi, łańcuchami tekstowymi lub nazwami węzłów.
Przykładowo, dla zapytania
(baza.Pracownik
where
((Pensja.TextValue=2000)
(Nazwisko.TextValue!='Kowalski')))
drzewo rozbioru wygląda tak, jak na następnej stronie
Strona 85
OR
Język zapytań dla XML oparty na podejściu stosowym
where
.
or
baza
Pracownik
=
!=
.
2000
.
Kowalski
Pensja
Nazwisko
TextValue
Rysunek 5 - 21 przykładowe drzewo rozbioru zapytania
Strona 86
TextValue
Język zapytań dla XML oparty na podejściu stosowym
Podczas wykonywania zapytania drzewo obchodzone jest rekurencyjnie w porządku
infiksowym, tzn:
 Ewaluowana jest lewa gałąź poddrzewa (którego korzeniem jest bieżący węzeł), jeśli jest
niepusta.
 Rozpoznawany jest operator:
o
Jeśli węzeł drzewa jest typu TreeNode, nie jest wykonywane żadne działanie.
o
Jeśli węzeł drzewa jest typu LiteralValue, na stosie rezultatów umieszczana jest
wartość uzyskana z ewaluacji prawej gałęzi poddrzewa (tzn. wartość liczbowa,
łańcuch tekstowy lub węzły XML odpowiadające podanej nazwie). W
prawidłowo skonstruowanym drzewie, dla węzłów typu LiteralValue lewa
gałąź poddrzewa jest pusta.
o
Jeśli węzeł drzewa jest typu UnaryOperator, wywoływany jest odpowiedni
operator jednoargumentowy.
o
Jeśli węzeł drzewa jest typu BinaryOperator, mogą zajść dwa przypadki:

Operator reprezentowany przez ten węzeł jest operatorem
algebraicznym. W takim wypadku ewaluowana jest prawa gałąź
poddrzewa, a następnie wywołany zostaje odpowiedni operator
dwuargumentowy.

Operator reprezentowany przez ten węzeł jest operatorem niealgebraicznym. W takim wypadku wywoływany jest odpowiedni niealgebraiczny operator dwuargumentowy, z prawą gałęzią poddrzewa
jako argumentem – jej ewaluacja będzie następnie wywoływana z
wnętrza tego operatora.
Strona 87
Język zapytań dla XML oparty na podejściu stosowym
VI. Zakończenie
16. Trudności przy realizacji pracy
W trakcie realizacji pracy napotkaliśmy na szereg trudności związanych zarówno z narzędziami
jak i strukturą dokumentów XML. Trudności te są opisane poniżej.
16.1.Wpływ DOM na sposób realizacji pracy
Wybór DOM jako standardu dostępu do dokumentu XML, w znaczący sposób wpłynął na
implementację. DOM stanowi bardzo wygodne narzędzie dostępu do struktury i danych zawartych w
dokumencie XML, wprowadza jednak szereg ograniczeń utrudniających implementację algorytmów
zastosowanych w naszej pracy.
16.1.1 DOM a stos rezultatów
W związku z tym, iż wyniki zapytań, przechowywane na stosie rezultatów mają postać węzłów
DOM, które mogą pochodzić z kilku różnych dokumentów, potrzebne było przenoszenie węzłów
(referencji węzłów) między dokumentami. Niestety standard DOM nie przewiduje możliwości
umieszczenia tej samej instancji węzła w kilku dokumentach. W związku z powyższym konieczne jest
tworzenie kopii węzłów („klonów”). Niestety w momencie tworzenia kopii, kopia otrzymuje inną
referencję niż oryginalny węzeł. Podobna konieczność zachodzi przy operacji zmiany nazwy. Aby
działanie operatora porównania na równość w przypadku węzłów, gdy chcemy porównywać
referencje, było możliwe konieczne było wprowadzenie mechanizmu odzyskiwania referencji
oryginalnych węzłów.
16.1.2 Kolekcje w DOM
Ponieważ istnieją implementacje DOM dla wielu języków programowania, kolekcje DOM nie
są zgodne z kolekcjami zaimplementowanymi w Javie. W związku z tym konieczna jest konwersja
jednych struktur na inne.
16.1.3 Wartości tekstowe w DOM
Opis standardu DOM określa sposób zwracania wartości tekstowych znajdujących się wewnątrz
węzłów XML. W ramach jednego węzła może wystąpić dowolna liczba wartości tekstowych. Ponadto
znaki końca linii są traktowane jako pełnoprawne znaki, co może kłócić się z intuicją niektórych
użytkowników. Ponieważ zamierzeniem twórców nie było wprowadzanie zmian do sposobu obsługi
dokumentów XML przez DOM, nie dokonano żadnych zmian w stosunku do DOM. Użytkownik
może w łatwy sposób dokonać tej zmiany samodzielnie (poprzez edycję dokumentu XML, lub
wprowadzenie zmian do kodu źródłowego aplikacji).
16.2.Inne napotkane trudności
16.2.1 Brak typów danych w XML
Jako, że postanowiliśmy nie ograniczać się tylko do obsługi dokumentów ze zdefiniowanym
XML Schema określającym typy, poważnym problemem było zdecydowanie się na strategię
wnioskowania o typach danych tekstowych zawartych w dokumencie XML. Ponieważ ograniczanie
się tylko do wartości tekstowych wydawało się zbyt mocnym ograniczeniem, wprowadzono obsługę
danych liczbowych – zmiennoprzecinkowych, oraz danych logicznych. W tym celu wykorzystano
istniejące w języku Java metody konwersji łańcuchów znakowych na odpowiednie typy. Jeśli
Strona 88
Język zapytań dla XML oparty na podejściu stosowym
konwersja udaje się, dane traktowane są jako dane odpowiedniego typu, w przeciwnym wypadku
traktowane są jako łańcuch znaków. W celu dokonaniu zmiany typu z liczbowego na tekstowy należy
dokonać konkatenacji z pustym łańcuchem.
16.2.2 Linki
Mimo istnienia wielu potencjalnych rozwiązań problemu tworzenia powiązań między węzłami
w dokumentach XML, żaden z nich nie wydał się zadowalający. W związku z tym, zdecydowano się
na implementację własnego modelu tworzenia powiązań (opis rozwiązania znajduje się w Rozdziale
Czwartym niniejszej pracy).
17. Wady i zalety przyjętego rozwiązania
17.1.Zalety przyjętego rozwiązania
Stworzony język zapytań jest językiem zdefiniowanym znacznie dokładniej niż inne znane
magistrantom języki zapytań do XML. Jest językiem w pełni ortogonalnym, łatwo poddającym się
rozbudowie, zwięzłym oraz czytelnym dla użytkownika i opartym na bardzo mocnych podstawach
teoretycznych. Wykorzystanie standardowych narzędzi do parsowania zapytań umożliwia bardzo
łatwą adaptację składni do potrzeb użytkownika. Wykorzystanie standardu DOM umożliwia
korzystanie z potencjalnych udogodnień wprowadzonych w kolejnych wersjach standardu oraz
implementacjach parserów. Zastosowanie podejścia stosowego w implementacji języka zapytań
pozwala na skorzystanie z algorytmów optymalizacji zapytania zaproponowane przez Jacka
Płodzienia ([30]).
17.2.Wady przyjętego rozwiązania
Wykorzystanie drzewa DOM jako składu obiektów, co opisano powyżej. Stworzony przez
autorów język nie stosuje się w pełni do wymagań XML Query Requirements, co może być
argumentem dla krytyków tego rozwiązania, aczkolwiek autorzy pracy nie uważają tego za wadę. Za
wadę może być również uważana niewielka liczba zaimplementowanych operatorów oraz brak
operacji aktualizacyjnych. Wada ta może być jednak łatwo usunięta, gdyż język ten jest bardzo prosty
w rozbudowie, a celem autorów było pokazanie możliwości stworzenie języka zapytań dla XML w
oparciu o podejście stosowe.
18. Potencjalne zastosowania pracy
18.1.Możliwości wykorzystania rezultatu pracy w konstrukcji repozytorium
dokumentów
Jednym z celów niniejszej pracy jest stworzenie podstaw do budowy nowoczesnych,
efektywnych i wygodnych w użytkowaniu repozytoriów dokumentów. Efektem naszej pracy jest w
pełni działający, zaimplementowany język zapytań dla XML. W jaki sposób język ten może zostać
wykorzystany w konstrukcji repozytoriów? Co należy zrobić, aby mógł być jeszcze lepszy w takich
zastosowaniach?
Jak pokazaliśmy w Rozdziale 2, istniejące obecnie systemy do tworzenia repozytoriów
dokumentów są bardzo dopracowane w większości obszarów. Ich największą słabością jest mało
wygodny system wyszukiwania danych, nierzadko wymagający długiego nawigowania po
powiązaniach między dokumentami. Język zapytań obsługujący strukturę danych tak elastyczną jak
XML, rozbudowany o mechanizm powiązań może znacząco ułatwić wyszukiwanie interesujących
Strona 89
Język zapytań dla XML oparty na podejściu stosowym
danych. Ilość systemów używających danych zapisanych w formacie XML rośnie z dnia na dzień, zaś
konwersja danych z baz danych do XML jest stosunkowo mało skomplikowana, tak więc nie należy
spodziewać się z tej strony problemów z adaptacją języka zapytań do istniejących systemów.
W przypadku dużych repozytoriów danych pliki XML mogą okazać się zbyt nieefektywne, z
przyczyn objętościowych - znaczną część pliku XML zajmują znaczniki (co powoduje duże zużycie
miejsca na dysku), zaś przyjęty system zakładający załadowanie całej bazy do pamięci może nie być
najlepszym rozwiązaniem dla dużych zbiorów danych. W celu efektywnej obsługi takich systemów
należy stworzyć implementację języka zapytań wykorzystującą bardziej zaawansowany model składu,
z użyciem plików w formacie binarnym z indeksowaniem (i innymi rozwiązaniami znanymi z baz
relacyjnych).
18.2.Możliwości wykorzystania pracy w konstrukcji aplikacji
Poza repozytoriami, istnieje szereg innych zastosowań, w których magistranci widzą możliwość
zastosowania rezultatu swoich prac lub ich rozwinięcia:
 Wiele aplikacji używa XML jako standardu wymiany danych. Język zapytań
umożliwiający przetwarzanie dokumentów XML może posłużyć jako bardzo przydatny
komponent służący do budowy takich systemów.
 Często spotyka się aplikacje wykorzystujące proste, lekkie bazy klasy MySQL lub
Hypersonic SQL. Język (i jego implementacja) będący rezultatem pracy ma przewagę
nad tymi produktami pod względem uniwersalności, przy zbliżonej wydajności.
Przejście na inny model składu (rezygnacja z XMLowej reprezentacji danych) może
dodatkowo poprawić wydajność i możliwości systemu. Co prawda magistranci nie
uważają XML jako idealnego, lekkiego rozwiązania bazodanowego, jednak w
porównaniu z rozwiązaniami zastosowanymi w wymienionych (bardzo popularnych)
bazach jest on co najmniej równie dobry. Wskazane byłoby w takim przypadku
rozbudowanie języka o konstrukcje służące do modyfikacji danych.
 Magistranci dostrzegli problemy ze zrozumieniem idei działania języków opartych na
semantyce stosowej wśród studentów. W obecnej wersji system jest na tyle prosty, że
możliwe jest stosunkowo łatwe zmodyfikowanie go w celu stworzenia narzędzia
edukacyjnego, prezentującego sposób działania tej klasy języków, i możliwość
zapoznania się z ich możliwościami.
19. Możliwości rozwoju pracy
Rezultat pracy – język zapytań do XML oparty na semantyce stosowej jest w swojej obecnej
wersji rozwiązaniem stosunkowo prostym. Możliwości jego rozwoju, mające na celu zwiększenie
możliwości i poszerzenie obszaru zastosowań są bardzo duże. Możliwe jest wprowadzenie
dodatkowych cech takich jak:
 Perspektywy – zarówno zmaterializowane jak i niezmaterializowane,
 Wykorzystanie informacji zawartych w DTD lub XML Schema, w celu wnioskowania o
typach danych, kontroli struktury itd.
 Wprowadzenie cech obiektowych takich jak klasy, dynamiczne role itp. (wiązałoby się to
również z rozszerzeniem języka o możliwość definiowania metod)
 Wprowadzenie optymalizatora zapytań
W toku prac magistranci doszli do wniosku, iż pomimo powierzchownej atrakcyjności, XML, w
skutek różnych związanych z nim problemów, nie jest dobrym rozwiązaniem dla aplikacji typu
bazodanowego. W związku z tym atrakcyjna wydaje się przebudowa systemu w celu zmiany modelu
Strona 90
Język zapytań dla XML oparty na podejściu stosowym
składu obiektów. Poza ułatwieniem realizacji wspomnianych już rozszerzeń, umożliwiłoby to
następujące udoskonalenia:
 Wprowadzenie mocnej kontroli typów
 Możliwość obsługi dużych zbiorów danych przez zastosowanie indeksowania i innych
technik znanych z istniejących systemów bazodanowych
 Zwiększenie zgodności implementacji z teorią – w chwili obecnej można wskazać
miejsca, w których istniejące rozwiązania są rezultatem kompromisów między teorią a
ograniczeniami wykorzystanych narzędzi (przede wszystkim przebudowa modelu
składu obiektów oraz stosu rezultatów). Dzięki ich usunięciu możliwe byłoby dalsze
uproszczenie kodu i struktur danych.
 Dodanie obsługi znaków diaktrycznych dla standardów kodowania innych niż Unicode.
Podsumowując, możliwości rozszerzenia i kontynuacji prac są bardzo duże – wskazane obszary
to tylko wierzchołek góry lodowej.
Strona 91
Język zapytań dla XML oparty na podejściu stosowym
Podsumowanie
Niniejsza praca magisterska osiągnęła stawiane przed nią zadania. Stworzono język zapytań dla
XML oparty na podejściu stosowym, udowadniając przydatność tego podejścia do tworzenia języków
zapytań również dla danych pół-strukturalnych. Pomimo napotkanych trudności stworzono w pełni
działający prototyp języka zapytań, którego łatwość użycia i rozbudowy jest znacznie wyższa niż
innych znanych autorom rozwiązań.
Rezultat niniejszej pracy daje możliwość prowadzenia dalszych prac mających na celu
stworzenie jeszcze silniejszych i znacznie bardziej rozbudowanych narzędzi mogących znaleźć
zastosowanie w wielu istotnych (również z biznesowego punktu widzenia) obszarach.
Strona 92
Język zapytań dla XML oparty na podejściu stosowym
Bibliografia
[1]. Ricardo Baeza-Yates, Berthier Ribeiro-Neto Modern Information Retrieval strony 99-116
Addison-Wesley Longman Limited, New York 1999.
[2]. Ian H. Witten, Alistair Moffat, Timothy C. Bell Managing Gigabytes: Compressing and
Indexing Documents and Images, Second Edition strony 469-483 Morgan Kaufmann
Publishers, San Francisco 1999
[3]. Kazimierz Subieta Teoria I Konstrukcja obiektowych języków zapytań
[4]. http://www.objectivity.com
[5]. http://www.db4o.com
[6]. http://www.versant.com
[7]. Kazimierz Subieta Wprowadzenie do standardu ODMG część 4.
[8]. William Y. Mars, Christophe Blanche, Edward A. Overly Architecture for Information in
Digital Libraries, D-Lib Magazine, February 1997
[9]. Chris Marlin Commercial CM Systems http://see.cs.flinders.edu.au/seweb/scm/comtools.html
[10]. www.apache.org
[11]. www.compiler-construction.org
[12]. www.jflex.de
[13]. www.cs.princeton.edu/~appel/modern/java/CUP/
[14]. Zdzisław Płoski Słownik Encyklopedyczny – Informatyka, Wydawnictwa Europa.
ISBN 83-87977-16-0. Rok wydania 1999
[15]. www.w3c.org
[16]. http://www.cogneticsystems.com/xquery/xquery.html
[17]. http://www.w3.org/TR/NOTE-xml-ql/
[18]. http://www-db.stanford.edu/lore/
[19]. http://www.ibiblio.org/xql/
[20]. belllabs.com/user/simeon/icfp.ps
[21]. http://www.w3.org/1999/09/ql/docs/xquery.html
[22]. http://xerox.elet.polimi.it/xml-gl/
[23]. http://www.cs.toronto.edu/~gus/weboql/
[24]. http://www.w3.org/TandS/QL/QL98/pp/wql.html
[25]. Simon North XML Dla Każdego, Helion 2000
[26]. McLaughlin Brutt Java i XML, Helion 2001
[27]. http://java.sun.com/docs/white/langenv/
[28]. Andrew W. Appel Modern Compiler Implementation in Java, Cambridge University Press
1999
[29]. Aho Alfred V., Sethi Ravi, Ullman Jeffrey D Kompilatory. Reguły, metody i narzędzia, WNT
2002
[30]. http://www.ipipan.waw.pl/~jpl/
[31]. K. Subieta, J. Leszczylowski. A Critique of Object Algebras ,November 1995, dostępne pod
adresem http://www.ipipan.waw.pl/~subieta/EngPapers/index.html
[32]. K. Subieta, Y. Kambayashi, J. Leszczylowski, K. Yokota. Object Algebras: What is Wrong?,
July 1995, dostępne pod adresem http://www.ipipan.waw.pl/~subieta/EngPapers/index.html
Strona 93
Download