Implementace cásti jazyka XQuery v rámci projektu CellStore JanˇZák

Transkript

Implementace cásti jazyka XQuery v rámci projektu CellStore JanˇZák
České vysoké učenı́ technické v Praze
Fakulta elektrotechnická
Diplomová práce
Implementace části jazyka XQuery v rámci projektu CellStore
Jan Žák
Vedoucı́ práce: Ing. Michal Valenta, Ph.D.
Studijnı́ program: Elektrotechnika a informatika
Obor: Výpočetnı́ technika
leden 2007
ii
Poděkovánı́
Na tomto mı́stě bych rád poděkoval za poskytnuté rady, podporu a zázemı́ během mé práce
celému týmu projektu CellStore na Katedře počı́tačů FEL ČVUT, zvláště pak Ing. Michalu
Valentovi, Ph.D. a Ing. Janu Vranému.
iii
iv
Prohlášenı́
Prohlašuji, že jsem svou diplomovou práci vypracoval samostatně a použil jsem pouze podklady
uvedené v přiloženém seznamu.
Nemám závažný důvod proti užitı́ tohoto školnı́ho dı́la ve smyslu §60 Zákona č. 121/2000 Sb.,
o právu autorském, o právech souvisejı́cı́ch s právem autorským a o změně některých zákonů
(autorský zákon).
V Praze dne 18.1.2007
.............................................................
v
vi
Abstract
This work concerns a subject of design and implementation of part of the XQuery language
in environment of native XML database CellStore. It analyses features of the language and
describes a way of its processing in the implementation. Besides issues related to the XQuery
implementation it also explains principles, technologies and practical applications in the world
of XML, which includes the XQuery language.
Abstrakt
Tato práce pojednává o problematice návrhu a implementace části jazyka XQuery v prostředı́
nativnı́ XML databáze CellStore. Analyzuje vlastnosti tohoto jazyka a popisuje způsob, jakým
je v implementaci zpracováván. Kromě záležitostı́ spojených s implementacı́ XQuery také
vysvětluje základnı́ pojmy, technologie a praktické aplikace ve světě XML, do kterého jazyk
XQuery patřı́.
vii
viii
Obsah
Seznam obrázků
xi
Seznam tabulek
xiii
1 Úvod
2 Svět XML
2.1 Formát XML . . . . . . . . . . .
2.2 Jazyky světa XML . . . . . . . .
2.3 XQuery . . . . . . . . . . . . . .
2.4 Aplikace formátu XML . . . . . .
2.5 Způsoby ukládánı́ XML dat . . .
2.6 Nativnı́ XML databáze CellStore
1
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3
3
6
10
11
12
15
3 Analýza a návrh implementace XQuery
3.1 Úvod do konceptů jazyka XQuery . . . . . . . . .
3.2 Vybrané konstrukce jazyka XQuery . . . . . . . .
3.3 Omezenı́ implementace XQuery v rámci CellStore
3.4 Implementačnı́ platforma . . . . . . . . . . . . .
3.5 Funkčnı́ celky implementace . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
19
19
23
31
32
33
4 Realizace implementace XQuery
4.1 Funkčnı́ třı́dy a datové struktury . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2 Zpracovánı́ vybraných výrazů jazyka XQuery . . . . . . . . . . . . . . . . . . .
4.3 Vstupnı́ a výstupnı́ datový formát . . . . . . . . . . . . . . . . . . . . . . . . .
39
39
45
47
5 Testovánı́ implementace XQuery
5.1 Jednotkové testy pro XQueryExecutor . .
5.2 Jednotkové testy pro document providery
5.3 Jednotkové testy pro XQueryParser . . .
5.4 XML Query Test Suite . . . . . . . . . . .
49
49
49
50
50
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
6 Závěr
51
7 Seznam literatury
53
A Gramatika XQuery
57
B Implementovaná část gramatiky XQuery
63
C Přehled implementovaných funkcı́
67
D UML diagramy
69
E Uživatelská / instalačnı́ přı́ručka
73
F Obsah přiloženého CD
75
ix
x
Seznam obrázků
2.1
2.2
XPath osy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Model architektury databáze CellStore . . . . . . . . . . . . . . . . . . . . . . .
9
16
3.1
Typová hierarchie XQuery 1.0 a XPath 2.0 . . . . . . . . . . . . . . . . . . . .
22
D.1
D.2
D.3
D.4
D.5
UML
UML
UML
UML
UML
69
70
71
72
72
-
XQuery executor . . .
Databáze CellStore . .
Repository . . . . . .
Transaction manager .
Cache manager . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
xi
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
xii
Seznam tabulek
B.1 Přehled implementovaných pravidel gramatiky XQuery - 1. část . . . . . . . . .
B.2 Přehled implementovaných pravidel gramatiky XQuery - 2. část . . . . . . . . .
B.3 Přehled implementovaných pravidel gramatiky XQuery - 3. část . . . . . . . . .
63
64
65
C.1 Přehled implementovaných funkcı́ XQuery . . . . . . . . . . . . . . . . . . . . .
67
xiii
xiv
KAPITOLA 1. ÚVOD
1
1 Úvod
Značkovacı́ jazyk XML je jednou z dominant současného světa softwarového inženýrstvı́.
Vznikl na bázi jazyka SGML jako jeho zjednodušený dialekt se záměrem vytvořit jazyk, který
by mohl sloužit pro snadné poskytovánı́, přijı́mánı́ a zpracovávánı́ informacı́ na Webu. Tuto
úlohu již v té době zastával jazyk HTML, který ovšem nebyl plně soustředěn na popis logické
vnitřnı́ struktury prezentovaných informacı́, ale do značné mı́ry se zabýval popisem vzhledu
dokumentu při zobrazovánı́. Sada značek HTML byla konečná, jednoúčelová a neumožňovala
přizpůsobit se konkrétnı́m potřebám uživatele při popisu dat v dokumentu.
Cı́lem tvůrců XML bylo vytvořit nový jazyk, který by tento popis logické vnitřnı́ struktury
podle konkrétnı́ch potřeb uživatele umožňoval. Současně měl omezit obtı́žně uchopitelnou komplexnost jazyka SGML a mělo by ho být dı́ky tomu mnohem snazšı́ implementovat. Tohoto cı́le
jazyk XML nepochybně dosáhl a rozsah oblastı́ jeho nasazenı́ původnı́ záměr v mnoha směrech
překračuje.
Dokument ve formátu XML je členěn na malé dı́ly - jednotlivé elementy. Ty jsou pojmenovány
a mohou mı́t obsah: text, dalšı́ vnořené elementy nebo některé jiné, speciálnı́ prvky. Dı́ky
vnořovánı́ elementů do jiných elementů vzniká hierarchická - stromová - struktura. Kořenem
takto vzniklého stromu je samotný dokument. Tento typ struktury je v mnoha přı́padech velmi
vhodný pro vyjádřenı́ vztahů mezi jednotlivými elementy.
V současné době se formát XML použı́vá nejen pro poskytovánı́ dat a jejich vzájemnou výměnu,
ale také pro jejich dlouhodobějšı́ uchovávánı́ a hromadné strojové zpracovávánı́. Oblı́benou
aplikacı́ je transformace z jednoho zdroje dat ve formátu XML do vı́ce různých cı́lových formátů.
Zajı́mavé možnosti formátu XML spolu s bouřlivým vývojem jeho aplikacı́ a navazujı́cı́ch technologiı́ podnı́tily i výzkumnou práci ve skupině Softwarového inženýrstvı́ na Katedře počı́tačů
FEL ČVUT, která vyústila v projekt vlastnı́mi silami vyvı́jené nativnı́ XML databáze - projekt
CellStore.
U databáze jakéhokoli druhu je samozřejmě nutné poskytnout jejı́mu uživateli možnost se
na uložená data dotazovat a přı́padně je modifikovat. Ve světě relačnı́ch databázı́ tuto potřebu
uspokojuje jazyk SQL. Ve světě XML existuje několik dotazovacı́ch a transformačnı́ch jazyků.
Standardem je použitı́ jazyků XPath pro dotazovánı́ a XSLT pro transformace. Situace u jazyků
pro modifikaci dat je zatı́m neustálená. Rozsáhlými ambicemi ve všech těchto oblastech je však
zajı́mavý návrh jazyka XQuery, který se mnoha svými koncepty a vlastnostmi stává blı́zkým
přı́buzným SQL v XML světě. V této práci se pokusı́m popsat právě tento jazyk tak, jak jsem
jej v podstatných částech implementoval v rámci XML databáze CellStore.
V kapitole 2 se důkladněji seznámı́me s některými pojmy, které jsou s formátem XML spojeny.
Nastı́nı́me dostupné technologie pro zpracovánı́ XML dat, zmı́nı́me několik ukázek praktických
aplikacı́ formátu XML a budeme diskutovat možné přı́stupy k ukládánı́ XML dat v persistentnı́ch úložištı́ch, zejména pak otázku nativnı́ch XML databázı́. Na závěr si jako zástupce
této rodiny představı́me architekturu nativnı́ XML databáze CellStore.
Kapitolu 3 věnujeme analýze a návrhu architektury pro implementaci jazyka XQuery v rámci
této databáze. Nejprve rozebereme klı́čové konstrukce jazyka XQuery a některé základnı́ koncepty, které se k němu vážı́. Vysvětlı́me stávajı́cı́ omezenı́ databáze a jak se promı́tnou do našı́
implementace tohoto dotazovacı́ho jazyka, předevšı́m v oblasti datového modelu.
2
KAPITOLA 1. ÚVOD
Rozhodneme o implementačnı́ platformě a zvážı́me, které nástroje lze použı́t k dosaženı́ vyššı́
produktivity vývoje. Krátce se zmı́nı́me o výhodách a nedostatcı́ch, které z jejich použitı́
plynou. Rozdělı́me odpovědnost za zpracovánı́ dotazu na jednotlivé funkčnı́ celky a ukážeme,
jakým způsobem spolu budou spolupracovat. Předvedeme si také některé návrhové vzory,
kterými bude architektura implementace ovlivněna a vysvětlı́me jejich filosofii.
Kapitolu 4 zasvětı́me popisu provedené implementace. Představı́me důležité datové struktury a seznámı́me se s jednotlivými funkčnı́mi třı́dami. Důkladněji si rozebereme zpracovánı́
některých zajı́mavých pravidel gramatiky jazyka XQuery. Pozornost budeme věnovat také
otázkám spojeným s modulárnı́m a otevřeným řešenı́m komunikace s nižšı́mi vrstvami databáze
stejně jako formátu, ve kterém implementace poskytuje výsledek vrstvám vyššı́m.
V kapitole 5 zmı́nı́me metody, použité pro testovánı́ správného chovánı́ implementace. V dodatcı́ch jsou pak k nalezenı́ gramatika XQuery, přehled implementovaných pravidel gramatiky,
přehled implementovaných funkcı́, UML diagramy a instalačnı́ přı́ručka.
KAPITOLA 2. SVĚT XML
3
2 Svět XML
2.1
2.1.1
Formát XML
Cı́le návrhu formátu XML
Jak jsme se dozvěděli již v úvodu, XML vzniklo jako zjednodušený dialekt jazyka SGML. Norma
SGML byla přijata v roce 1986 jako ISO norma, definujı́cı́ standard obecného značkovacı́ho
jazyka. Dı́ky své složitosti a zbytečné komplexnosti se však v širšı́m měřı́tku neprosadila. Od
roku 1996 se potom datujı́ prvnı́ práce na novém jazyku XML, který měl tyto nedostatky
odstranit.
Byl navrhován s cı́lem vytvořit jazyk, který vyhovı́ následujı́cı́m principům:
• XML musı́ být použitelné na Internetu.
• XML musı́ podporovat široké rozpětı́ aplikacı́.
• XML musı́ být kompatibilnı́ s SGML.
• Musı́ být snadné vytvářenı́ programů, zpracovávajı́cı́ch XML dokumenty.
• Množstvı́ volitelných vlastnostı́ XML by mělo být minimálnı́, nejlépe žádné.
• XML dokumenty by měly být čitelné člověkem a přiměřeně přehledné.
• Norma jazyka XML by měla být připravena rychle.
• Norma jazyka XML musı́ být přesná a stručná.
• XML dokumenty musı́ být snadné vytvářet.
• Na úspornost při použitı́ XML značkovánı́ nenı́ kladen silný důraz.
Výsledkem návrhu byla norma jazyka XML 1.0 [9], s jejı́ž v současné době již čtvrtou edicı́ je
možné se seznámit na stránkách zastřešujı́cı́ organizace W3C. Na rozdı́l od jazyka HTML [32],
který je rovněž odvozen od SGML, nemá pevnou množinu značek a ta tak může být pro různé
druhy dokumentů definována odlišně. Poznamenejme, že jazyk HTML se dočkal reformulace své
normy směrem ke kompatibilitě s požadavky kladenými XML a výsledná norma XHTML [30]
je jednou z nejběžněji použı́vaných praktických aplikacı́ XML.
2.1.2
Základnı́ pojmy při popisu XML dokumentu
Prostředkem pro označenı́ určitých prvků v dokumentu je značka (tag), rozpoznatelná dı́ky
použitı́ špičatých závorek:
<titul>Hlava XXII</titul>
4
KAPITOLA 2. SVĚT XML
Tı́mto způsobem je pomocı́ otevı́racı́ značky <titul> a zavı́racı́ značky </titul> vymezen element. Pokud bychom značkami uzavı́rali pouze prázdný text, použijeme prázdný element
<titul />. Norma XML vyžaduje, aby si jména elementu v otevı́racı́ a zavı́racı́ značce
vzájemně odpovı́dala, přičemž se rozlišujı́ malá a velká pı́smena. Použitı́ diakritiky ve značkách
nelze doporučit pro možné problémy zpracujı́cı́ch aplikacı́ (XML procesorů).
XML dokument jako takový je tvořen uspořádanou posloupnostı́ znaků. Implicitně norma
předpokládá použitı́ Unicode, tedy kódovánı́ UTF-8 nebo UTF-16. Pro češtinu lze uvažovat
také o kódovánı́ ISO-8859-2 nebo Windows-1250, ne vždy je pak ale možné zaručit podporu ze
strany XML procesoru.
XML dokument se fyzicky skládá z prvků nazývaných entity. Entita obsahuje rozpoznatelná
data (elementy, znaková data) nebo nerozpoznatelná data. Entity mohou odkazovat na jiné
entity, samotný dokument je entitou nazývanou kořen.
Z hlediska logické struktury v XML dokumentu rozlišujeme deklarace, elementy, komentáře,
instrukce pro zpracovánı́ apod. Tyto prvky přehledově popı́šeme v dalšı́m textu.
O XML dokumentu prohlásı́me, že je dobře vytvořen (well-formed), pokud splňuje tato pravidla:
• Rozpoznatelné entity v dokumentu jsou správně vytvořeny.
• Rozpoznatelné entity, na které jsou v dokumentu odkazy, jsou správně vytvořeny.
• Element je považován za dobře vytvořený, pokud je správně uzávorkován a je dodržena
shoda otevı́racı́ a zavı́racı́ značky.
• Značky se nesmı́ křı́žit.
Dı́ky aplikaci těchto pravidel je XML dokument možné vnı́mat jako stromovou strukturu, jejı́mž
kořenem je objekt typu dokument.
Dobře vytvořený XML dokument můžeme také označit jako správný (valid). V takovém přı́padě
splňuje určitá omezenı́, zpravidla se týkajı́cı́ výskytu značek a jejich vzájemných vazeb. Tato
omezenı́ bývajı́ specifická pro konkrétnı́ aplikaci XML. Vyjádřena mohou být napřı́klad pomocı́
DTD nebo XML schémat. Stručný přehled těchto jazyků podáme později.
2.1.3
Elementy
Elementy jsou základnı́m stavebnı́m kamenem, který tvořı́ strukturu XML dokumentu. Element má svůj název, který je uveden v jeho otevı́racı́ a uzavı́racı́ značce. Obsahem elementu
mohou být dalšı́ prvky v libovolné posloupnosti: text, vnořené elementy, komentáře, sekce
CDATA nebo instrukce pro zpracovánı́. Text v obsahu elementu je v XML procesoru vnitřně
reprezentován pomocı́ tzv. textového uzlu, který nenese jméno a jehož obsahem jsou samotná
znaková data. V některých přı́padech jsou obsahem elementu pouze vnořené elementy (element
content). Pokud v obsahu elementu docházı́ k výskytu textu a současně vnořených elementů,
mluvı́me o elementu se smı́šeným obsahem (mixed content). Platı́ některá omezujı́cı́ pravidla,
napřı́klad výskyt dvou textových uzlů za sebou v posloupnosti obsahu elementu je vyloučen.
<a>Text v elementu a<b>Text v elementu b</b><c /></a>
KAPITOLA 2. SVĚT XML
2.1.4
5
Atributy
K bližšı́mu charakterizovánı́ elementů mohou sloužit atributy. Každý atribut má svůj název
a hodnotu. Hodnota je vždy umı́stěna mezi dvojici uvozovek nebo apostrofů. Zapisujı́ se ve
formátu nazev = "hodnota" do otevı́racı́, přı́padně prázdné značky elementu. Mohou sloužit
pro jemnějšı́ rozlišovánı́ elementů se stejným jménem. Lze je použı́t také pro uchovávánı́
informacı́, které s elementem sice souvisı́, ale z logického hlediska nenı́ vhodné uvažovat o nich
jako o obsahu elementu.
<element1 atribut1 = "hodnota1"><element2 atribut2 = ’hodnota 2’ /></element1>
2.1.5
Komentáře
Komentáře jsou v XML dokumentu označeny dı́ky použitı́ značek <!-- na začátku a --> na
konci komentáře. Znaky -- se v textu komentáře nesmějı́ vyskytovat. Komentář nenı́ přı́pustný
uvnitř značek. Text komentáře se žádným způsobem neinterpretuje. XML procesor může
v některých přı́padech pracovat s vnitřnı́ reprezentacı́ ve formě komentářového uzlu, ve kterém
uchovává obsah komentáře.
<!-- Text komentáře se neinterpretuje:
<element>toto nebude element</element>. -->
2.1.6
Instrukce pro zpracovánı́
Do XML dokumentu je možné umı́stit tzv. instrukce pro zpracovánı́ (processing instructions).
Do nich lze vložit přı́kazy, které jsou určeny pro zpracovánı́ externı́m programem. Instrukce pro
zpracovánı́ jsou uzavřeny mezi značky <?appname a ?>, kde appname označuje cı́lový externı́
program, kterému je instrukce určena.
<?php echo "Zprava"; ?>
2.1.7
Sekce CDATA
V některých přı́padech je nutné umı́stit do XML dokumentu textovou informaci, která ovšem
obsahuje části značek nebo dokonce celé značky XML. Aby se v takových přı́padech předešlo
nežádoucı́ interpretaci těchto znakových dat ve smyslu XML syntaxe, umisťujı́ se do tzv. sekce
CDATA. Ta je ohraničena pomocı́ značek <![CDATA[ a ]]>. Obdobně jako v přı́padě komentáře
se v obsahu sekce CDATA nesmı́ opakovat uzavı́racı́ značka ]]>.
<![CDATA[Toto je sekce CDATA, bude interpretována jako text:
<element>toto nebude element, ale součást textu</element>. ]]>
6
2.2
2.2.1
KAPITOLA 2. SVĚT XML
Jazyky světa XML
Jazyky definujicı́ schéma XML dokumentů
DTD - Document Type Definition byl do návrhu XML převzat z SGML a provázı́ tuto
normu už od prvnı́ch návrhů jako jejı́ nedı́lná součást. Umožňuje definovat schéma XML
dokumentu pro přı́slušnou konkrétnı́ aplikaci. Lze tedy s jeho pomocı́ určit, které značky jsou
přı́pustné, v kterých mı́stech dokumentu se mohou vyskytovat, v jakém pořadı́ a počtu, jaké
atributy se k nim mohou vázat apod. Konkrétnı́ XML dokument pak můžeme proti této definici
zkontrolovat obecnými nástroji a rozhodnout, zde jı́ vyhovuje a je tedy správný (valid).
O elementu určitého typu (tento pojem splývá s názvem elementu) můžeme prohlásit, že má
být prázdný pomocı́ zápisu <!ELEMENT br EMPTY>, v tomto přı́padě pro element s názvem br.
Pokud se jako návrháři některé praktické aplikace XML rozhodneme, že element set může
obsahovat libovolná data, deklarujeme to pomocı́ zápisu <!ELEMENT set ANY>. Pouze textový
obsah určı́me jako validnı́ pro element popis zápisem <!ELEMENT popis (#PCDATA)>.
Jak jsme uvedli již dřı́ve, elementy je možné do sebe vzájemně vnořovat. K popisu složitějšı́ch
struktur lze využı́t regulárnı́ch výrazů s notacı́ pomocı́ značek , (posloupnost), | (výběr
z možnostı́), ? (nepovinnost položky), + (možnost opakovánı́ položky - nejméně jednou) a *
(možnost opakovánı́ položky - libovolným počtem opakovánı́, tedy i žádným).
Přı́kladem může být následujı́cı́ deklarace seznamu osob.
<!ELEMENT osoby(osoba*)>
<!ELEMENT osoba(jmeno, prijmeni, firma?, mail+, telefon*)>
<!ELEMENT jmeno (#PCDATA)>
...
Povolené atributy elementů jsou určeny jménem, typem a povinnostı́ výskytu. Nejběžnějšı́m
typem atributů jsou znaková data, tedy typ CDATA. Speciálnı́mi typy jsou ID, IDREF a IDREFS.
Tyto typy sloužı́ pro jednoznačnou identifikaci elementu a odkazovánı́ se na tuto jednoznačnou
identifikaci. Atributu je možné rovněž přiřadit výčtový typ. Klı́čové slovo #REQUIRED určuje,
že atribut musı́ být u elementu uveden. #IMPLIED naproti tomu řı́ká, že atribut se u elementu
nemusı́ vyskytovat. Pokud chybı́ oba tyto modifikátory, musı́ mı́t element stanovenu implicitnı́
hodnotu. Je-li tato implicitnı́ hodnota doprovázena klı́čovým slovem #FIXED, je tato hodnota
atributu konstantnı́ a nenı́ možné ji v dokumentu změnit.
Jako přı́klad uveďme opět deklaraci seznamu osob.
<!ELEMENT osoby(osoba*)>
<!ELEMENT osoba (cv, popis)>
<!ATTLIST osoba
jmeno CDATA #REQUIRED
prijmeni CDATA #REQUIRED
pohlavi (neuvedeno | muž | žena) ’neuvedeno’>
...
KAPITOLA 2. SVĚT XML
7
XSD - XML Schema Definition [34] byl rovněž vytvořen pod patronacı́ organizace W3C.
Je odpovědı́ na některé nedostatky, které byly vytýkány jazyku DTD. Na rozdı́l od DTD
nepoužı́vá speciálnı́, ale přı́mo XML syntaxi - každá definice schématu pomocı́ XML Schema
je tak současně XML dokumentem a může tak s nı́ být nakládáno. Definuje rozsáhlou sadu
datových typů (vestavěných i uživatelsky definovatelných). Umožňuje opakovaně použı́vat již
definované prvky. Počet výskytů elementu v daném mı́stě je možné definovat v přesném,
čı́selně vyjádřeném intervalu. Rozlišuje mezi posloupnostı́ s přesně daným pořadı́m a množinou,
v jejı́mž rámci je pořadı́ libovolné.
Možnosti tohoto jazyka jsou velmi silné a jejich důkladnějšı́ popis by překračoval možnosti
tohoto textu. Kromě nesporných výhod, které tento jazyk přinášı́, skrývá také určité stinné
stránky. Vytýkána mu bývá předevšı́m délka a nepřehlednost zápisu. Pro automatické zpracovánı́ schématu se nevýhodou stává i možnost zapsat jednu definici několika možnými způsoby.
Obdobné funkce nabı́zı́ s vı́ce či méně odlišným přı́stupem i jazyky RelaxNG nebo Schematron. Podrobnějšı́ informace v češtině lze k tématu jazyků pro definici schémat XML dokumentů nalézt v knihách [28] a [23].
Mohli bychom nabýt dojmu, že možnosti, které skýtá mechanismus obecné validace XML dokumentů proti danému schématu, budou široce využı́vány zvláště v prostředı́ Internetu, kde se vystavené či zası́lané XML dokumenty stávajı́ prostředkem komunikace mezi různými informačnı́mi
systémy. Podle statistik se však tvůrci těchto dokumentů zatı́m spoléhajı́ spı́še na neformálně
stanovené definice, neboť až 95% XML dokumentů zveřejněných na Webu neobsahuje odkaz na
své schéma [36].
2.2.2
Dotazovacı́ a transformačnı́ jazyky
XPath - XML Path Language je ve své verzi 1.0 [13] poměrně známým, použı́vaným
a vcelku jednoduchým jazykem. Sloužı́ pro výběr nebo adresovánı́ části XML dokumentu.
Datový model XPath reprezentuje XML dokument pomocı́ sedmi typů uzlů: kořen dokumentu,
uzel elementu, uzel atributu, textový uzel, komentářový uzel, uzel instrukce pro zpracovánı́ a
uzel jmenného prostoru. Tyto uzly jsou uspořádány do stromové struktury. Ve verzi XPath
2.0 [5] je použit datový model XDM [16], který je sdı́lený i v jazyku XQuery 1.0 [6].
Pro výběr určité části XML dokumentu se použı́vá cesta, která se skládá z jednotlivých kroků,
oddělených znakem /. V každém kroku je na aktuálnı́ kontext (posloupnost obsahujı́cı́ aktuálně
vybrané uzly) aplikována osa a test, čı́mž vznikne kontext nový.
Na jeden uzel z aktuálnı́ho kontextu je možné aplikovat jednotlivé osy s výsledky, které lze
shrnout takto:
• self - výsledkem je aktuálnı́ uzel samotný
• parent - výsledkem je prvnı́ uzel, ležı́cı́ na cestě z aktuálnı́ho uzlu do kořene (rodič)
• child - výsledkem jsou bezprostřednı́ následnı́ci aktuálnı́ho uzlu vyjma atributových uzlů
(děti)
• attribute - výsledkem jsou atributové uzly aktuálnı́ho uzlu
• namespace - výsledkem jsou uzly jmenných prostorů aktuálnı́ho uzlu
8
KAPITOLA 2. SVĚT XML
• ancestor - výsledkem jsou všechny uzly na cestě z aktuálnı́ho uzlu do kořene (předci)
• ancestor-or-self - ve výsledku je kromě předků zahrnut i aktuálnı́ uzel
• descendant - výsledkem jsou uzly, jejichž předkem je aktulnı́ uzel (potomci)
• descendant-or-self - ve výsledku je kromě potomků zahrnut i aktuálnı́ uzel
• preceding - výsledkem jsou uzly, které nejsou předkem aktuálnı́ho uzlu a v dokumentu
mu předcházejı́ (předchůdci)
• preceding-sibling - výsledkem jsou předchůdci, kteřı́ s aktuálnı́m uzlem sdı́lı́ rodiče
(předcházejı́cı́ sourozenci)
• following - výsledkem jsou uzly, které nejsou dětmi aktuálnı́ho uzlu a v dokumentu ho
následujı́ (následovnı́ci)
• following-sibling - výsledkem jsou následovnı́ci, kteřı́ s aktuálnı́m uzlem sdı́lı́ rodiče
(následujı́cı́ sourozenci)
Pokud osu explicitně neuvedeme, použije se implicitně osa child. Znak @ je zástupcem osy
attribute, znak .. osy parent a znak . osy self. Pokud mı́sto znaku / použijeme jako
oddělovač jednotlivých kroků znak //, provede se ještě před přechodem do dalšı́ho kroku aplikace osy descendant-or-self.
Na posloupnost uzlů, vzniklou aplikacı́ osy, je následně aplikován test. Pomocı́ testu vybereme
z posloupnosti uzlů, vrácených po aplikaci osy, jen ty, které nás zajı́majı́. Testovat můžeme
podle jména elementu (např. /knihovna/kniha/descendant::kapitola), kdy znak * značı́
libovolný název. Jinou možnostı́ je testovánı́ podle druhu elementu - test node() povoluje
všechny uzly, zatı́mco test text() pouze textové uzly a test comment() pouze komentářové
uzly. Přı́kladem takového dotazu je /knihovna/kniha/@* nebo /knihovna//text().
K ještě podrobnějšı́mu filtrovánı́ uzlů sloužı́ predikáty. Jde se o booleovské nebo čı́selné výrazy,
zapisované do hranatých závorek na konec kroku. V přı́padě čı́selného predikátu dojde k výběru
položky z posloupnosti uzlů aktuálnı́ho kontextu, jejı́ž pořadı́ v této posloupnosti odpovı́dá
hodnotě predikátu. Jedná se o dotaz typu /knihovna/kniha[5], s jehož pomocı́ je možné zı́skat
pátý element s názvem kniha, který je potomkem elementu knihovna. Booleovské predikáty
vybı́rajı́ ty uzly, pro které je splněna podmı́nka, zapsaná v predikátu. K dispozici jsou operátory
pro porovnávánı́ =, !=, <, <=, >, >=. Dále jsou dostupné aritmetické operátory +, -, *, div a mod.
V neposlednı́ řadě je možné použı́vat řadu zabudovaných funkcı́ jako např. sum, count nebo
not. Uveďme několik přı́kladů dotazů s použitı́m predikátů:
/knihovna/kniha[price > 20]
count(/knihovna/kniha[price * 0.5 >= 10])
/knihovna/kniha[last()]
Svou roli plnı́ XPath také ve spolupráci s jinými jazyky, do kterých je zahrnut jako prostředek
pro zı́skávánı́ dat z XML dokumentu. Lze ho tak nalézt např. v XSLT, XPointer nebo XQuery.
V rámci XQuery se uplatňuje jeho verze 2.0, která přinášı́ mnoho nových funkcı́ včetně nového,
podrobnějšı́ho datového modelu sdı́leného s jazykem XQuery.
KAPITOLA 2. SVĚT XML
9
Obrázek 2.1: XPath osy
XSLT - Extensible Stylesheet Language Transformations [12] je jazykem pro transformaci XML dokumentů. Přiřazuje syntakticky správnému XML dokumentu sémantiku tı́m,
že ho pomocı́ sady pravidel (nazývaných šablony) převede na dokument, použı́vajı́cı́ některou
jinou sémantiku, která je známa (např. převod do formátu (X)HTML nebo PDF).
Pravidla popisujı́ převod vstupnı́ho dokumentu na výstupnı́. Jsou tvořena vzorkem a akcı́, která
má být provedena při nalezenı́ vzorku ve vstupnı́m dokumentu. Jinou možnostı́ je pravidlo
pojmenovat a volat ho jeho jménem.
XPointer - XML Pointer Language [14] sloužı́ pro adresaci částı́ XML dokumentů na
Internetu. Využı́vá se identifikátoru fragmentu, připojeného za URL. Přı́kladem může být zápis
http://xquery.ked.cz/diplomka.xml#xpointer(/diplomka/kapitola[1]/odstavec[3]).
XLink - XML Linking Language [15] můžeme použı́t pro vytvářenı́ vazeb (odkazů) mezi
jednotlivými mı́sty v XML dokumentech. Tyto vazby mohou být tradičnı́, tj. jednosměrné
nebo rozšı́řené. Rozšı́řené vazby umožňujı́ seskupovat vı́ce směrů v rámci jedné vazby, blı́že
popisovat vzdálené zdroje nebo přiřazovat jednotlivým vazbám role.
XUpdate [24] je návrh jazyka, sloužı́cı́ho pro modifikaci XML dokumentů. Byl vytvořen
v rámci sdruženı́ XML:DB, z jehož dı́lny vyšel také návrh jednotného programového rozhranı́
XML databázı́ XML:DB API. Zaštiťujı́cı́ organizace bohužel již několik let nevyvı́jı́ podstatnějšı́
10
KAPITOLA 2. SVĚT XML
činnost a přestože jsou obě normy několika XML databázemi implementovány, dajı́ se považovat
v podstatě za mrtvé.
XML:DB API už nereflektuje dynamický vývoj v oblasti dotazovacı́ch jazyků a také XUpdate
nenı́ dále rozvı́jen ani široce implementován. Nejnadějnějšı́m kandidátem na jazyk pro modifikaci XML data se tak stává návrh rozšı́řenı́ jazyka XQuery nazvané XQuery Update Facility,
o kterém se zmı́nı́me i v následujı́cı́ části.
2.3
XQuery
Zmı́nili jsme se o oblı́benosti dotazovacı́ho jazyka XPath, která spolu s relativnı́ jednoduchostı́
implementace vedla k jeho širokému uplatněnı́. Jazyk XQuery [6] v sobě integruje všechny
vlastnosti a syntaxi XPath. Má však proti němu mnohem většı́ ambice, které pokrývajı́ většinu
požadavků, které na zpracovánı́ XML dat klade uživatel uvyklý komfortu soudobých verzı́
jazyka SQL. Vycházı́ z konceptů svých předchůdců jako jsou návrhy jazyků Quilt nebo XMLQL. Přehledově uvedeme některé zajı́mavé prvky jazyka, který dále podrobněji rozebereme
v kapitole 3.
Jednı́m z nejzajı́mavějšı́ch stavebnı́ch kamenů jazyka XQuery je tzv. FLWOR konstrukce.
Posloupnost přı́kazů for-let-where-order by-return, která dala svými počátečnı́mi pı́smeny
název této vlastnosti, se svou funkčnostı́ velmi blı́žı́ notoricky známé posloupnosti přı́kazů
select-from-where-order by jazyka SQL.
Přı́kazy for a let přiřazujı́ hodnoty proměnných, které jsou v jejich rámci deklarovány.
Přiřazované hodnoty mohou být zapsány přı́mo v dotazu jako literály, mohou být výsledkem
výpočtu nebo dotazu pomocı́ XPath. Zatı́mco přı́kaz let přiřazuje do proměnné jako jejı́ hodnotu celou posloupnost, for iteruje přes posloupnost a přiřazuje do proměnné prvky posloupnosti jeden za druhým.
Na hodnotu proměnné je možné se dále odkazovat v celém lokálnı́m rozsahu jejı́ platnosti, který
končı́ vyhodnocenı́m přı́kazu return. Proměnná může být překryta opakovanou deklaracı́.
Jednotlivé přı́kazy for a let lze řetězit přı́mo za sebou.
Klauzule where sloužı́ pro filtrovánı́ vracených hodnot podle stanovené podmı́nky. Podobně
jako v SQL lze výstupnı́ posloupnost řadit pomocı́ přı́kazu order by, pomocı́ kterého lze
stanovit sadu kritériı́, které budou k řazenı́ použity. Závěrečná klauzule return je určena
k sestavenı́ výsledku vyhodnocenı́ celé konstrukce.
Podmı́něné výrazy jsou v XQuery řešeny s pomocı́ známé trojice if-then-else. Ve vyhodnocovánı́ podmı́nky se může uplatnit koncept efektivnı́ boolean hodnoty, který popisuje
převod některých nebooleovských hodnot a posloupnostı́ hodnot na booleovskou hodnotu,
použitelnou k rozhodnutı́ podmı́nky.
K dispozici jsou také tři druhy operátorů porovnávánı́. Obecné porovnávánı́ připouštı́
na obou stranách operátoru posloupnosti a ke splněnı́ stačı́ existence jedné dvojice, složené
z prvku na jedné a druhé straně operátoru, pro kterou je deklarovaný vztah splněn. Hodnotové
porovnávánı́ stejně jako uzlové porovnávánı́ porovnávajı́ právě jeden prvek na obou stranách
operátoru.
K použitı́ v if-then-else konstrukci a where podmı́nce se přı́mo nabı́zı́ kvantifikátory.
KAPITOLA 2. SVĚT XML
11
K dispozici je jak existenčnı́ kvantifikátor some stejně jako obecný kvantifikátor every. Je
tedy možné zı́skat vyjádřenı́, zda některý přı́padně všechny prvky v množině vyhovujı́ zadané
podmı́nce.
Ke zpracovánı́ údajů nabı́zı́ XQuery kromě běžných aritmetických a logických operátorů
(sčı́tánı́, odčı́tánı́, násobenı́, dělenı́, modulo, logický součin a součet) také operátory sloužı́cı́
pro množinové operace: sjednocenı́, průniky apod.
Paletu možnostı́ v nakládánı́ s daty rozšiřujı́ také funkce, z nichž několik desı́tek je normou
předepsáno k zabudovánı́ do interpreteru XQuery dotazů a dalšı́ si může uživatel specifikovat
o své vůli, třeba přı́mo v samotném dotazu.
V rámci zpracovánı́ dotazu je možné vytvářet vlastnı́ elementy, jejich atributy a obsahy. K tomuto účelu sloužı́ konstruktory. Existujı́ dva druhy konstruktorů: přı́mé konstruktory (direct) ve svém zápisu přı́mo uvádějı́ XML značky, zatı́mco ”vypočtené” konstruktory (computed)
použı́vajı́ specifický pseudofunkčnı́ tvar volánı́.
Jazyk XQuery je tedy v současné podobě jazykem dotazovacı́m a dı́ky konstruktorům i jazykem
transformačnı́m. Ve fázi prvnı́ch návrhů se nacházı́ dvě jeho rozšı́řenı́: XQuery Update
Facility [11] navrhuje rozšı́řenı́ stávajı́cı́ gramatiky XQuery o přı́kazy umožnujı́cı́ modifikaci
dat, zatı́mco XQuery 1.0 and XPath 2.0 Full-Text [3] přinášı́ možnost full-textového
vyhledávánı́ v rozsáhlých XML dokumentech při současném využitı́ výhody, kterou skýtá jejich
dobrá strukturovanost. Jazyku XQuery bývá někdy vyčı́táno, že jeho syntaxe sama neodpovı́dá
syntaxi XML. Reformulacı́ XQuery do XML syntaxe se zabývá norma XQueryX [27].
2.4
Aplikace formátu XML
Jak jsme již uvedli, reformulacı́ normy HTML směrem ke shodě s požadavky kladenými na
XML vznikl formát XHTML - The Extensible HyperText Markup Language [30].
Je zaměřen na stejnou oblast jako původnı́ HTML, tedy na prezentaci informacı́ na Webu.
Existujı́ tři varianty této normy: Transitional se zaměřuje na minimalizaci rozsahu změn proti
HTML za účelem usnadněnı́ přechodu na XHTML, Frameset podporuje stránky s rámci a Strict
je cı́lovou variantou normy, která do značné mı́ry omezuje značky použı́vané pro určovánı́
vzhledu dokumentu a soustřeďuje se na použı́vánı́ značek pro definici struktury dokumentu.
Pro formátovánı́ vzhledu jednotlivých prvků dokumentu na koncovém zobrazovacı́m zařı́zenı́ je
doporučeno použı́vánı́ jazyka CSS - Cascading Style Sheets [25].
Verze XHTML 1.1 [2] vycházı́ z varianty Strict a původně nedoporučované značky pro
formátovánı́ vzhledu zcela vypouštı́. Výhodou použitı́ jazyka XHTML pro tvorbu dokumentů
na Webu je možnost zpracovávat XHTML dokumenty obecnými nástroji pro XML. Dokumenty jsou přehledněji strukturovány. Oddělenı́ struktury a informacı́ o vzhledu také umožnuje
snadno přiřazovat různé formátovánı́ vzhledu dokumentu v závislosti např. na typu zobrazovacı́ho zařı́zenı́ pouhým přiřazenı́m jiného CSS stylu, aniž by byl nutný zásah do struktury
samotného dokumentu.
Formát RSS sloužı́ k syndikaci obsahu. Syndikacı́ obsahu rozumı́me automatizované sumarizovánı́ a zpřı́stupňovánı́ nových informacı́ na webovém sı́dle prostřednictvı́m jednoho nebo
několika kanálů (feeds), které mohou být dále strojově zpracovávány. Velmi často je možné se
s jeho použitı́m setkat na zpravodajském webu nebo weblogu. Na klientské straně se použı́vajı́
RSS čtečky ve formě samostatného programu nebo webové stránky - ty odebı́rajı́ a zobrazujı́
12
KAPITOLA 2. SVĚT XML
data ze zvolených kanálů. Formát trpı́ určitou roztřı́štěnostı́, má několik současně platných
verzı́ a dokonce i několik výkladů své zkratky.
V poslednı́ch letech se začala věnovat pozornost pojmu semantický web. V podstatě se jedná
o doplněnı́ sémantických informacı́ k jednotlivým prvkům dokumentů na Webu. To umožňuje
počı́tačové zpracovánı́ psaného textu, snadné vyhledávánı́ a kategorizaci. Podrobnějšı́ rozbor
tohoto pojmu by byl nad rámec tohoto textu. Za jazyky z této oblasti můžeme jmenovat RDF
- Resource Description Framework [4], což je metadatový standard konsorcia W3C.
Dalšı́m jazykem postaveným nad XML z lı́hně této organizace je SOAP - Simple Object
Access Protocol [18], který definuje rámec vzájemné online komunikace informačnı́ch systémů
a jejich komponent na bázi volánı́ tzv. webových služeb. Tyto technologie jsou v současné
době velmi populárnı́ a použı́vané při vývoji rozsáhlých informačnı́ch systémů a XML se zde
v mnoha ohledech dobře uplatňuje.
Nelze nezmı́nit dvě zajı́mavé aplikace XML, vzešlé z dı́lny konsorcia OASIS. Prvnı́ je DocBook
[37] - jazyk, který usnadňuje vytvářenı́ strukturovaných textů jako články, knihy nebo skripta
a pomocı́ připravených skriptů jejich ”sazbu” do mnoha různých cı́lových formátů.
Druhá, ODF - Open Document Format for Office Applications, [7] je definicı́ na XML
postavených, otevřených formátů pro běžné kancelářské aplikace. V současné době se již jedná
o přijatý standard ISO. Tento formát je výchozı́m pro ukládánı́ dokumentů v kancelářském
balı́ku OpenOffice.org. V rámci projektu nativnı́ XML databáze CellStore byl zpracován use
case, demonstrujı́cı́ použitı́ této databáze pro ukládánı́ dat v tomto formátu.
Jako zajı́mavé perličky na závěr uveďme jazyky SVG - Scalable Vector Graphics [17]
(formát pro vektorovou grafiku, ukládaný samozřejmě v XML syntaxi) nebo MathML - Mathematical Markup Language (jazyk pro zápis matematické notace v XML) [21], tentokrát
opět od konsorcia W3C. Existuje dokonce i jazyk MusicML, určený k uchovávánı́ notového
zápisu v XML syntaxi. Všechny tyto speciálnı́ druhy dat, navzájem značně odlišné, lze tedy
zpracovávat pomocı́ obecných XML nástrojů.
2.5
Způsoby ukládánı́ XML dat
V předcházejı́cı́ kapitole jsem si přehledově přiblı́žili, jak rozmanité jsou oblasti, ve kterých
vznikajı́ XML dokumenty. Je zřejmé, že s rostoucı́m počtem XML dokumentů v oběhu mezi
uživateli se budou zvyšovat také nároky na způsoby jejich dlouhodobějšı́ uchovávánı́ a na komfortnost práce s takovými úložišti. V této části textu se tedy budeme krátce věnovat jednotlivým
možným přı́stupům k ukládánı́ XML dat. Pro podrobnějšı́ seznámenı́ s touto problematikou
lze doporučit [28].
2.5.1
Systém souborů
Zřejmě nejjednoduššı́m způsobem, jak řešit problém ukládánı́ XML dokumentů, je jejich uloženı́
v podobě prostého textového souboru, umı́stěného v klasickém systému souborů operačnı́ho
systému. S takto uloženým dokumentem zpravidla nelze v přı́padě potřeby ihned pracovat,
ale musı́ se nejdřı́ve převést do paměťové reprezentace - zpravidla strom s uzly, odpovı́dajı́cı́
specifikaci W3C DOM.
KAPITOLA 2. SVĚT XML
13
Výhodou tohoto přı́stupu je kromě jednoduchosti implementace také snadné zı́skánı́ celého
XML dokumentu přesně ve tvaru, jak byl uložen. Nevýhodou je paměťová náročnost, která je
důsledkem nutného načtenı́ celého dokumentu do paměti. To může být problematické zejména
v přı́padě obsáhlých XML dokumentů (stovky MB).
Nevýhodou je i zbytečná režie, která vzniká při opakovaných dotazech, jejichž výsledkem je
pouze malá část dokumentu. I v těchto situacı́ch je totiž třeba přečı́st celý původnı́ dokument.
Proti oběma těmto nevýhodám se lze bránit zavedenı́m některé formy indexovánı́. Zpravidla
však docházı́ k problémům při pokusu o modifikace takto zaindexovaných dokumentů.
2.5.2
Relačnı́ databáze
Uloženı́ XML dat do relačnı́ch databázı́ nabı́zı́ v současné době téměř každý významnějšı́ dodavatel těchto systémů. Pokud nabı́zejı́ dotazovánı́ na tyto data v některém běžném dotazovacı́m
jazyku pro XML (zřejmě XPath nebo XQuery), docházı́ na pozadı́ k převodu do dotazů jazyka
SQL. Pro uloženı́ použı́vajı́ relačnı́ databáze několik přı́stupů: uloženı́ hran XML stromu, strukturálnı́ uloženı́ dat podle DTD nebo uloženı́ XML fragmentů do polı́ typu BLOB.
Mezi výhody ukládánı́ XML dokumentů do relačnı́ch databázı́ patřı́ nenáročnost implementace
a osvědčená škálovatelnost. Na relačnı́ch databázı́ch jsou již také vyřešeny otázky transakcı́.
Složitějšı́ dotazy však vyžadujı́ dı́ky častému zkoumánı́ vzájemných vztahů elementů mnoho
operacı́ nad většı́m počtem tabulek, čı́mž docházı́ k rychlému poklesu výkonu.
Problémem jsou i dotazy nad dokumenty popsanými cyklickými DTD. V takových přı́padech
vede převod do SQL dotazů k hluboce zahnı́zděným konstrukcı́m dotazů nebo k iteracı́m
v některé procedurálnı́ nadstavbě jazyka SQL.
2.5.3
Objektové databáze
Pokud ukládáme XML data do objektově orientovaných databázových systémů, můžeme
s výhodou využı́t existujı́cı́ mechanismy serializace objektů a jejich vazeb, na kterých je perzistence dat v těchto systémech postavena. Jednotlivé uzly XML stromů zde tedy ukládáme jako
kterýkoli jiný objekt. Zřejmou výhodou je plné využitı́ již existujı́cı́ technologie, nevýhodou
je jejı́ přı́lišná a zbytečná obecnost. Otázkou také zůstává, jak do obecné objektové databáze
vhodně implementovat indexy specifické pro XML data.
2.5.4
Objektově relačnı́ databáze
Rozšı́řenı́m stávajı́cı́ch relačnı́ch databázı́ jsou databáze s objektově relačnı́m přı́stupem. Jejich schopnosti ukládat ukládat bohatšı́ datové struktury jako abstraktnı́ datové typy (struktura i s zapouzdřenými funkcemi a operacemi) lze využı́t i k uloženı́ XML dat. Zpravidla se
vyžaduje, aby struktura takto ukládaného dokumentu byla definována pomocı́ DTD nebo aby
bylo možné takové DTD odvodit přı́mo z dokumentu. Problémy nastávajı́ opět s ukládánı́m
dokumentů se složitějšı́mi, zejména rekurzivnı́mi, DTD a také pokud dokument obsahuje elementy se smı́šeným obsahem.
14
KAPITOLA 2. SVĚT XML
2.5.5
Nativnı́ XML databáze
Popsané výhody a nevýhody při ukládánı́ dat některým z dřı́ve uvedených přı́stupů vedou
k otázce, zda si specifické vlastnosti XML dat nezasloužı́ také specifické nakládánı́ v rámci
databázového systému.
Odpovědı́ na tuto otázku jsou nativnı́ XML databáze (NXD), tedy databáze specializované
výhradně na ukládánı́ XML dat.
Iniciativa XML:DB definovala nativnı́ XML databáze pomocı́ třı́ základnı́ch vlastnostı́:
• Nativnı́ XML databáze definujı́ logický model pro XML dokument a ukládajı́ a poskytujı́
dokumenty v souladu s tı́mto modelem.
Modelů tohoto typu je celá řada, jmenujme napřı́klad DOM, datový model XPath 1.0,
datový model XPath 2.0 a XQuery 1.0 (XDM), XML Infoset nebo Post-Schema Validation
Infoset (PSVI).
• XML dokument je základnı́ logickou jednotkou nativnı́ XML databáze, stejně jako řádek
tabulky je základnı́ logickou jednotkou relačnı́ databáze.
• Nenı́ vyžadován žádný konkrétnı́ model vlastnı́ho fyzického uloženı́ dat nižšı́mi vrstvami
DB. Nativnı́ XML databáze může použı́t relačnı́ch, hierarchických nebo objektově orientovaných struktur stejně dobře jako proprietárnı́ho formátu uloženı́ (např. indexované
komprimované soubory).
Výhodou nativnı́ch XML databázı́ je možnost přizpůsobit systém, ve kterém jsou data uložena,
potřebám vyplývajı́cı́m z požadavků na rychlý přı́stup k částem uložených stromových struktur,
ideálně v přı́mé návaznosti na zpracovávánı́ některé konstrukce dotazovacı́ho jazyka, který daná
databáze podporuje (XPath, XQuery).
K urychlenı́ přı́stupu k datům se nabı́zı́ využitı́ indexů, které lze dělit na hodnotové (hledá se
konkrétnı́ hodnota), strukturálnı́ (hledá se hodnota v rámci souvisejı́cı́ okolnı́ struktury elementů) a fulltextové (s XML dokumentem se při hledánı́ zacházı́ jako s čistým textem).
Tato oblast se poměrně bouřlivě rozvı́jı́, lze jmenovat některé indexy pro XML data: DataGuide,
T-index, SphinX nebo APEX. Informace o těchto typech indexů lze nalézt v [28]. Jako zajı́mavý
způsob indexovánı́ XML dat je uváděn také tzv. C-strom. Ani jeden z těchto způsobů indexovánı́ však nelze prohlásit za plně prozkoumané, definitivnı́ řešenı́.
Jak je vidět, teoretické základy těchto databázı́ zatı́m nejsou plně dopracovány a teprve se
rozvı́jejı́. S tı́m souvisı́ i hlavnı́ nevýhoda stávajı́cı́ch nativnı́ch XML databázı́, kterou je nižšı́
propustnost a výkon ve srovnánı́ s výsledky, na které je zvyklý dnešnı́ uživatel klasických
relačnı́ch databázı́.
V současné době existuje několik projektů nativnı́ch XML databázı́. Mezi nejznámějšı́ patřı́
databáze eXist, XHive/DB, Sedna, Timber, Tamino, Berkeley DB XML nebo Apache Xindice.
Tato diplomová práce se zabývá popisem implementace jazyka XQuery v rámci nativnı́ XML
databáze CellStore. V následujı́cı́ části se proto pokusı́me o podrobnějšı́ pohled do architektury
právě této databáze.
KAPITOLA 2. SVĚT XML
2.6
2.6.1
15
Nativnı́ XML databáze CellStore
Historie projektu CellStore
Projekt CellStore má své počátky v semestrálnı́ práci, zpracované v rámci předmětu Realizace programových systémů. Cı́lem této práce bylo implementovat XML:DB API, tedy jednotné API pro přı́stup k XML databázı́m. Jako programovacı́ jazyk byl zvolen plně objektový
Smalltalk, konkrétně dialekt Smalltalk/X. V průběhu práce dospěli jejı́ řešitelé k rozhodnutı́
vytvořit si vlastnı́ datový sklad pro ukládánı́ XML dat, inspirovaný systémem uloženı́ dat
v databázı́ch Gemstone a Oracle. Testy implementovaného návrhu prokázaly dobré výsledky,
čı́mž byl položen životaschopný základ projektu CellStore.
Dalšı́ rozvoj projektu je pod vedenı́m Ing. Michala Valenty, Ph.D. a Ing. Jana Vraného (jednoho
z původnı́ch autorů, který se na vývoji nadále intenzivně podı́lı́) zajišťován prostřednictvı́m
zpracovánı́ bakalářských a diplomových pracı́. Bc. Pavel Strnad tak tı́mto způsobem dı́ky své
bakalářské práci [35] rozšı́řil databázi CellStore o transakčnı́ manažer s podporou vlastnostı́
ACID nad XML daty, lock manažer se sofistikovanou podporou uzamykánı́ stromových struktur
a log manažer spolu s cache manažerem pro zlepšenı́ výkonu. Bc. Karel Přı́hoda rozšı́řil ve své
bakalářské práci [31] cache manažer a log manažer zapojil do tzv. recovery modulu, sloužı́cı́ho
k zotavenı́ databáze do konzistentnı́ho stavu po přı́padné havárii. Oba svoje oblasti působenı́
dále propracovávajı́ v rámci diplomových pracı́.
V rámci projektu byly zpracovány i práce, které se databáze přı́mo nedotýkaly. Bc. Tomáš
Hájek vytvořil a ve své bakalářské práci popsal nástroj StDoc, použitelný pro automatické
generovánı́ dokumentace programů ve Smalltalku. Ing. Ondřej Kašpar ve své diplomové práci
zpracoval use case databáze CellStore, když prozkoumal možnost použı́t tuto databázi jako
úložiště dokumentů ve formátu ODF.
Implementace části dotazovacı́ho a transformačnı́ho jazyka XQuery je cı́lem této diplomové
práce.
2.6.2
Cı́le projektu CellStore
Současným cı́lem projektu CellStore je vývoj experimentálnı́ nativnı́ XML databáze, na které
by bylo možné zkoumat, vyvı́jet a vyučovat v těchto oblastech:
• ukládánı́ XML dat
• vyhodnocovánı́ dotazů, operace manipulujı́cı́ s daty
• optimalizace dotazů, indexovánı́
• transakčnı́ zpracovánı́
• zotavenı́ databáze po havárii
• vývoj a testovánı́ aplikacı́ nad XML databázemi (zejména v oblastech semantického webu
a specializovaných úložišť XML dat)
16
2.6.3
KAPITOLA 2. SVĚT XML
Architektura databáze CellStore
Databáze CellStore je tvořena několika spolupracujı́cı́mi moduly na různých vrstvách, které si
vzájemně poskytujı́ služby. Tyto moduly si popı́šeme v následujı́cı́m textu, nynı́ se spokojı́me
s přehledovým obrázkem.
Obrázek 2.2: Model architektury databáze CellStore
2.6.4
Low level storage
Nejnižšı́ vrstvou databáze je tzv. low level storage, který je zodpovědný za přı́stup k datovým
souborům na disku a jejich správu. Na disku jsou data ukládány do dvou typů souborů: cell
file obsahuje strukturu XML stromu, text file uchovává obsah a jména elementů a atributů.
V cell file jsou data uchovávána v jednotlivých buňkách (cells) o fixnı́ délce, což vysvětluje
název celé databáze. Buňky obsahujı́ DOM nebo XML:DB API objekty a jsou organizovány
do bloků, jejichž délku lze měnit při zakládánı́ DB.
Bloky jsou dále organizovány do segmentů, přičemž platı́, že segment obsahuje data týkajı́cı́ se
pouze jednoho dokumentu.
Obdobné bloky a segmenty lze spatřit také v text file.
překladová tabulka (translation table).
S organizacı́ dat zde vypomáhá
KAPITOLA 2. SVĚT XML
2.6.5
17
Cache manager
Cache manager zvyšuje výkon databáze. Prostřednictvı́m optimálnı́ správy vyrovnávacı́ paměti
databáze poskytuje možnost rychlého načtenı́ položky z databáze, připadně uloženı́ změněné
položky bez nutnosti okamžitých a velmi zdržujı́cı́ch diskových operacı́, které tak mohou být
vhodně rozloženy v čase.
2.6.6
Log manager
Úkolem log manageru je udržovánı́ žurnálu (logu), což je sekvenčnı́ soubor, ve kterém jsou
uložena redundatnı́ data vztahujı́cı́ se k probı́hajı́cı́m transakcı́m. Změny, prováděné v rámci
transakce, jsou uloženy v žurnálu a původnı́ hodnota tak nenı́ ohrožena přı́padnou haváriı́.
2.6.7
Recovery module
Recovery module řešı́ zotavenı́ databáze ze selhánı́ a to jak selhánı́ jednotlivé transakce, tak
selhánı́ celého databázového systému včetně možnosti selhánı́ paměťového média. Těžiště jeho
práce spočı́vá ve vhodné komunikaci mezi cache managerem, log managerem a databázı́, tak
jak je uložena ve stálé paměti.
2.6.8
Transaction manager, lock manager
Tato část systémů je zodpovědná za řı́zenı́ práce s transakcemi, nastavovánı́ zámků a komunikaci
s cache managerem. V rámci transaction manageru je implementován uzamykacı́ protokol taDOM2 [20], vyvinutý pro specifické potřeby uzamykánı́ stromových struktur XML dat. Zámky
jsou spravovány pomocı́ tabulky zámků, kterou obhospodařuje lock manager.
2.6.9
Document provider, document adaptor
Součásti databáze, které jsou zodpovědné za vyhodnocovánı́ dotazů, potřebujı́ zajištěný přı́stup
k mnoha XML dokumentům, které jsou v databázi uloženy. V rámci databáze CellStore je
uživatelům umožněno dotazovat se nejen na dokumenty, uložené přı́mo v databázi, ale také
na dokumenty uložené na souborovém systému klasického operačnı́ho systému a dokonce i na
dokumenty, dostupné na Internetu prostřednictvı́m protokolů HTTP a FTP. Komunikaci s jednotlivými datovými zdroji zajišťujı́ document adaptory specifické pro každý druh datového
zdroje (dokument v databázi, dokument v souborovém systému, dokument na Webu, . . . ).
Document adaptory poskytuje ostatnı́m součástem databáze na vyžádánı́ document provider.
2.6.10
XQuery executor
Za zpracovánı́ dotazů v jazyce XQuery (a v jeho podmnožině XPath) je zodpovědný modul
XQuery executor. Popis jeho struktury a principů práce je hlavnı́ náplnı́ této diplomové práce
a věnujeme mu přı́štı́ dvě kapitoly.
18
KAPITOLA 2. SVĚT XML
KAPITOLA 3. ANALÝZA A NÁVRH IMPLEMENTACE XQUERY
19
3 Analýza a návrh implementace XQuery
3.1
Úvod do konceptů jazyka XQuery
Vyložme si na úvod této kapitoly některé základnı́ koncepty jazyka XQuery 1.0 [6], které jsou
podchyceny v jeho normě a které nás budou provázet v mnoha jeho konstrukcı́ch.
Základnı́ zněnı́ normy dovoluje v mnoha přı́padech zapsat dotaz stejného významu několika
různými způsoby. Redukci této nadbytečné košatosti jazyka nabı́zı́ dokument, popisujı́cı́
formálnı́ sémantiku jazyků XQuery 1.0 a XPath 2.0 [29]. Definuje omezenou gramatiku jazyka
XQuery Core se stejnou vyjadřovacı́ silou jako základnı́ a sadu přepisovacı́ch pravidel, která
převádějı́ základnı́ gramatiku XQuery na gramatiku XQuery Core.
Značná složitost práce s přepisovacı́mi pravidly spolu s komplikovanostı́ a neprůhlednostı́ zápisu
po převodu do XQuery Core je důvodem, proč se při analýze a implementaci XQuery přidržı́me
základnı́ normy.
3.1.1
Základnı́ pojmy
Základnı́m stavebnı́m blokem jazyka XQuery je výraz - ve své podstatě textový řetězec (dle
normy v kódovánı́ Unicode), který je složen z klı́čových slov, symbolů a operandů. Operandy
výrazu mohou být dalšı́ výrazy jazyka XQuery, v mnoha ohledech tak XQuery připomı́ná
funkcionálnı́ programovacı́ jazyk.
Stejně jako samotné XML je i XQuery citlivé na velikost znaků, klı́čová slova jsou uváděna
v malých pı́smenech a nejsou rezervována - jako jména mohou tedy být v XQuery až na výjimky
použita také klı́čová slova.
Hodnota je podle použitého datového modelu XDM [16] vždy sekvencı́, tedy uspořádanou
kolekcı́ prvků. Za prvky považujeme buď atomické hodnoty, které jsou instancı́ atomického
typu (např. xs:integer), nebo uzly, které jsou instancı́ uzlových typů (např. element). Uzly
majı́ každý jedinečnou uzlovou identitu, hodnotu (norma rozlišuje řetězcovou - prostý textový
obsah uzlu a typovou - podle typu, který je uzlu přiřazen napřı́klad pomocı́ XML Schema)
a v některých přı́padech také jméno.
Sekvence o jednom prvku jsou nazývány singleton, prvek je identický se singletonem, který
obsahuje právě tento prvek. Prázdná sekvence samozřejmě neobsahuje žádný prvek. Sekvence
jsou zásadně jednorozměrné. Pokud by se jednı́m prvkem sekvence měla stát jiná sekvence,
budou na mı́sto, kam je tato sekvence vkládána, vloženy všechny prvky vkládané sekvence.
3.1.2
Kontext
Každý výraz je vyhodnocován v určitém prostředı́ (kontextu), které tvořı́ soubor informacı́
ovlivňujı́cı́ch toto vyhodnocenı́. Norma dělı́ tyto informace mezi statický a dynamický kontext.
Statický kontext zahrnuje informace zı́skané ještě před počátkem vyhodnocovánı́ výrazu.
Zpravidla jde o implicitnı́ hodnoty některých nastavenı́ jako mód řazenı́, implicitnı́ namespace,
apod.
20
KAPITOLA 3. ANALÝZA A NÁVRH IMPLEMENTACE XQUERY
Dynamický kontext je reprezentacı́ informacı́, které jsou dostupné v době vyhodnocovánı́
výrazu. Zahrnuje informace statického kontextu a přidává některé dalšı́. Za nejzajı́mavějšı́
součásti dynamického kontextu lze považovat hodnoty proměnných, implementace funkcı́
včetně uživatelsky definovaných a v neposlednı́ řadě fokus.
Fokus určuje, který prvek ve vstupnı́ sekvenci je právě výrazem vyhodnocován. Skládá se
z kontextového prvku (context item), tedy právě zpracovávaného prvku, kontextové pozice (context position), tedy pořadového čı́sla tohoto prvku v rámci sekvence, a konečně velikosti kontextu (context size) neboli celkového počtu prvků ve vstupnı́ sekvenci.
3.1.3
Document order
Document order je způsob řazenı́ definovaný mezi uzly, zpracovávanými v rámci dotazu. Jedná
se o úplné a stabilnı́ uspořádánı́, které se v rámci jednoho stromu XML dokumentu řı́dı́
následujı́cı́mi pravidly:
• Kořenový uzel je vždy prvnı́m uzlem.
• Každý uzel má přednost před všemi svými dětmi a potomky.
• Atributové uzly se umisťujı́ bezprostředně za uzel elementu, ke kterému náležı́; jejich
pořadı́ je stabilnı́, ale závislé na implementaci.
• Vzájemné pořadı́ sourozenců je závislé na pořadı́, ve kterém jsou uvedeny v posloupnosti
dětı́ svého rodiče.
• Děti a potomci majı́ přednost před následujı́cı́mi sourozenci.
Vzájemné pořadı́ mezi uzly, pocházejı́cı́mi ze stromů různých dokumentů, je závislé na implementaci a musı́ dodržovat jediné pravidlo: všechny uzly jednoho stromu musı́ předcházet
všechny uzly druhého stromu.
3.1.4
Atomizace
Některé operátory jazyka XQuery závisı́ na procesu atomizace. Atomizace je uplatňována
na hodnoty (obecně buď atomická hodnota nebo uzel), pokud sémantika operátoru vyžaduje
sekvenci atomických hodnot. Pro atomizaci (která je v podstatě volánı́m funkce fn:data na
každý prvek posloupnosti), platı́ tato pravidla:
• Je-li prvek atomickou hodnotou, je vrácen beze změny.
• Je-li prvek uzlem, je vrácena jeho typová hodnota; nenı́-li možné zı́skat typovou hodnotu,
končı́ vyhodnocenı́ chybou.
Atomizace se uplatňuje v aritmetických výrazech, výrazech porovnávajı́cı́ch hodnoty, při volánı́
funkcı́, při výrazech přetypovánı́ (toto nebude pro popisovanou implementaci zajı́mavé, jak
budeme dokumentovat dále v části věnované omezenı́m implementace), při konstrukci nových
uzlů a v klauzuli order by FLWOR výrazu.
KAPITOLA 3. ANALÝZA A NÁVRH IMPLEMENTACE XQUERY
3.1.5
21
Efektivnı́ booleovská hodnota
Stejným způsobem, jakým sémantika některých operátorů vyžadovala v předchozı́m přı́padě
sekvenci atomických hodnot, požaduje v jiných přı́padech určenı́ efektivnı́ booleovské hodnoty.
Pro tento přı́pad (který je skrytým volánı́m funkce fn:boolean na každý prvek posloupnosti)
platı́ následujı́cı́ pravidla:
• Pokud operandem je prázdá sekvence, je vrácena hodnota false.
• Pokud operandem je sekvence, jejı́mž prvnı́m prvkem je uzel, je vrácena hodnota true.
• Pokud operandem je singleton typu xs:boolean nebo odvozený od xs:boolean, je
vrácena hodnota operandu beze změny.
• Pokud operandem je singleton typu xs:string, xs:anyURI nebo xs:untypedAtomic nebo
od nich odvozený, je vrácena hodnota true je-li délka hodnoty operandu většı́ než nula,
jinak je vrácena hodnota false.
• Pokud operandem je singleton některého numerického typu, je vrácena hodnota false
je-li hodnota operandu NaN nebo je rovna 0, jinak je vrácena hodnota true.
• V jiných přı́padech končı́ vyhodnocenı́ chybou.
Efektivnı́ booleovská hodnota sekvence je implicitně uvažována při vyhodnocovánı́ logických
výrazů (and, or), volánı́ funkce fn:not, vyhodnocovánı́ klauzule where FLWOR výrazu,
u některých druhů predikátů (např. a[b]), v podmı́něných výrazech (if) a výrazech s kvantifikátory (some, every).
3.1.6
Datové zdroje
XQuery disponuje funkcemi, které poskytujı́ přı́stup k datovým zdrojům. Tyto funkce majı́
velký význam, neboť umožňujı́ jednotlivým výrazům odkazovat se na dokumenty nebo kolekce
dokumentů. Norma mluvı́ o dvou funkcı́ch tohoto typu:
• fn:doc přijı́má jako parametr textový řetězec obsahujı́cı́ URI požadovaného dokumentu.
Implementace XQuery realizovaná v rámci databáze CellStore přijı́má URI s prefixy
xmldb: pro dokumenty uložené v databázi, file: pro dokumenty uložené v systému
souborů a http: a ftp: pro dokumenty uložené na Internetu. Jako výsledek jejı́ho volánı́
je vracen singleton, nesoucı́ uzel dokumentu (document node). V přı́padě dotazu na
neexistujı́cı́ datový zdroj je vyvolána chyba.
• fn:collection přijı́má jako parametr textový řetězec obsahujı́cı́ URI požadované kolekce.
Dotazovánı́ kolekcı́ nenı́ v popisované implementaci XQuery podporováno.
3.1.7
Typový model
Jazyk XQuery je silně založen na základech položených typovým modelem XDM [16], který
sdı́lı́ i se svou podmnožinou - jazykem XPath 2.0. Přehled typové hierarchie je uveden na
22
KAPITOLA 3. ANALÝZA A NÁVRH IMPLEMENTACE XQUERY
přiloženém obrázku. Typový model konkrétnı́ho dokumentu je popsán v XML schématu,
vůči kterému je dokument validnı́. Tato oblast doznala v implementaci značných odchylek od
předpokladů normy vzhledem k limitům nižšı́ch vrstev databáze, které nejsou schopné k dokumentům přı́slušná XML schémata udržovat. Popis skutečně implementované typové hierarchie
je uveden v části, věnujı́cı́ se omezenı́m implementace.
Obrázek 3.1: Typová hierarchie XQuery 1.0 a XPath 2.0
KAPITOLA 3. ANALÝZA A NÁVRH IMPLEMENTACE XQUERY
3.2
23
Vybrané konstrukce jazyka XQuery
V této pasáži textu si podrobněji rozebereme některé zajı́mavé konstrukce jazyka XQuery.
3.2.1
Řetězenı́ výrazů, literály, odkazy na proměnné
Výsledky zpracovánı́ dvou výrazů lze zřetězit za sebou s použitı́m operátoru ’,’ do jedné
sekvence.
Jazyk podporuje použitı́ literálů, tedy přı́mého zápisu atomických hodnot. Podporovány jsou
dva druhy literálů, numerické a řetězcové. Numerické literály jsou podle normy rozřazovány do
několika typů (xs:integer, xs:decimal, xs:double) podle přı́tomnosti znaků ’.’ a ’E’ nebo
’e’. V provedené implementaci jsou vzhledem k jejı́m dále popsaným omezenı́m sdruženy pod
jeden typ number. Řetězcové literály jsou ohraničeny znaky ’”’ nebo ”’”. Obsahovat mohou
také odkazy na definice znaků nebo předdefinované znaky (např. &lt;). V implementaci jsou
řetězcové literály zahrnuty pod typ string.
Odkazy na proměnné jsou uvozeny znakem ’$’, který je následován QName nesoucı́m jméno
proměnné. Jméno proměnné, odkazované tı́mto způsobem, musı́ odpovı́dat jménu některé
deklarované proměnné, což zahrnuje:
• Proměnné deklarované v úvodnı́ch částech dotazu (prolog, modul, importovaný modul) v této implementaci nenı́ tento způsob podporován.
• Proměnné automaticky deklarované implementacı́ - tato implementace žádné takové
proměnné nedeklaruje. Stejně tak se této implementace netýká situace, kdy jsou hodnoty do proměnných přiřazovány v rámci volánı́ uživatelsky definované funkce.
• Proměnné přiřazené některým výrazem XQuery, jmenovitě FLWOR konstrukce, kvantifikované výrazy a v této implementaci nepodporovaný přı́kaz typeswitch.
Při odkazech na proměnné je důležité mı́t na paměti jejich lokálnı́ platnost a možnost nově
deklarovat již existujı́cı́ proměnnou a tı́m v rozsahu platnosti nové deklarace překrýt jejı́ původnı́
hodnotu.
3.2.2
Uzávorkované výrazy, operátor ’.’, volánı́ funkcı́
V některých situacı́ch je velmi vhodné určit vlastnı́ pořadı́ vyhodnocovánı́ jednotlivých výrazů
ve složitějšı́m výrazu s vı́ce operandy prostřednictvı́m jeho rozdělenı́ na části. Část složeného
výrazu uzavřená mezi znaky ’(’ a ’)’ je pak v souladu s očekávánı́m z vnějšı́ho pohledu posuzována jako jeden spojitý výraz a nemusı́ být pochyb o tom, zda tak bude také vyhodnocena.
Výsledkem dotazu ve formátu 5 * 2 + 4 je čı́selná hodnota 14. Naproti tomu pro dotaz ve
formátu 5 * (2 + 4) je výsledkem čı́selná hodnota 30. Neuvedeme-li mezi otevı́racı́ a zavı́racı́
kulatou závorku žádný výraz, je výsledkem prázdná sekvence.
Operátor ’.’ odkazuje na aktuálnı́ kontextovou hodnotu. Tato konstrukce vypadá na
prvnı́ pohled nadbytečně, neboť aktuálnı́ kontextová hodnota je při vyhodnocovánı́ každého
přı́kazu dostupná v kontextu. Někdy je však žádoucı́ umožnit jejı́ předánı́ ke zpracovánı́
24
KAPITOLA 3. ANALÝZA A NÁVRH IMPLEMENTACE XQUERY
do mı́st, kde gramatika vyžaduje výraz (např. jako jeden operand binárnı́ho operátoru, jak
dokumentuje výraz (1 to 100)[. mod 5 eq 0] nebo do parametru funkce jako ve výrazu
fn:doc("bib.xml")/books/book[fn:count(./author)>1]).
Volánı́ funkcı́ je charakterizováno počátečnı́m uvedenı́m QName1 , který nese jméno funkce,
následované seznamem hodnot argumentů, oddělených znakem ’,’ a uzavřených v kulatých
závorkách. Norma specifikuje několik desı́tek vestavěných funkcı́ [26] a dovoluje uživateli definovat v rámci dotazu své vlastnı́.
3.2.3
Výrazy s cestami XPath
Jak jsme se již zmı́nili,
z jazyka XPath, které
konstrukce, popsané v
použı́t osu namespace.
zahrnuje jazyk XQuery také výrazy syntakticky i sémanticky převzaté
sloužı́ k výběru části XML dokumentu. Podporovány jsou všechny
druhé kapitole při výkladu vlastnostı́ jazyka XPath vyjma možnosti
Tuto osu jazyk XQuery nerozlišuje.
Výběr konkrétnı́ části XML dokumentu je realizován podle cesty, která je složena z jednotlivých
kroků, oddělených znakem ’/’. Vstupnı́ sekvence je pomocı́ konceptu inner focus zpracovávána
po jednotlivých prvcı́ch. V každém kroku je z aktuálnı́ kontextové hodnoty pomocı́ osy a testu
zı́skána nová výsledná sekvence uzlů.
Použı́t lze dopředné osy (forward axis) child, attribute, self, following, descendant,
following-sibling a descendant-or-self. Tyto osy vracejı́ výsledné sekvence v document
order.
Druhou možnostı́ je použitı́ zpětné osy (reverse axis), tj. parent, preceding, ancestor,
preceding-sibling nebo ancestor-or-self. Zvláštnostı́ zpětných os je, že pro následné
operace v rámci kroku (testy uzlů, predikáty) poskytujı́ výslednou sekvenci v reverse document
order, avšak výsledek celého kroku je opět v document order.
Pokud osu explicitně neuvedeme, použije se implicitně osa child. Zkrácenou syntaxı́ osy
attribute je znak ’@’, osy parent znak ’..’ a u osy self znak ’.’. Pokud mı́sto znaku ’/’
použijeme jako oddělovač jednotlivých kroků znak ’//’, provede se ještě před přechodem na
zpracovánı́ dalšı́ho kroku skrytý krok descendant-or-self::node().
Na sekvenci uzlů, vzniklou dohledánı́m podle osy, je následně aplikován test. Pomocı́ testu vybereme z této sekvence uzlů jen ty, které nás zajı́majı́. Testovat můžeme podle jména elementu
(name test, např. /knihovna/kniha/descendant::kapitola), kdy znak * značı́ libovolný
název.
Jinou možnostı́ je testovánı́ podle druhu elementu (kind test) - test node() povoluje všechny
uzly, zatı́mco test element pouze elementy, test attribute pouze atributové uzly, test text()
pouze textové uzly a test comment() pouze komentářové uzly.
K ještě podrobnějšı́mu filtrovánı́ uzlů sloužı́ predikáty. Jde se o booleovské nebo čı́selné
výrazy, zapisované do hranatých závorek na konec kroku. V přı́padě čı́selného predikátu dojde
k výběru položky ze sekvence uzlů aktuálnı́ho kontextu, jejı́ž pořadı́ v této sekvenci odpovı́dá
hodnotě predikátu. Jedná se o dotaz typu /knihovna/kniha[5], s jehož pomocı́ je možné
zı́skat pátý element s názvem kniha, který je potomkem elementu knihovna.
1
kvalifikované jméno podle pravidel definovaných v normě [8]
KAPITOLA 3. ANALÝZA A NÁVRH IMPLEMENTACE XQUERY
25
Booleovské predikáty vybı́rajı́ ty uzly, pro které je splněna podmı́nka, zapsaná v predikátu.
Podmı́nkou může být v zásadě libovolný výraz XQuery, u kterého je po jeho vyhodnocenı́
možné určit efektivnı́ booleovskou hodnotu.
3.2.4
Výrazy pro práci se sekvencemi
Pro konstrukci sekvencı́ lze využı́t již zmı́něného operátoru ’,’, který vyhodnotı́ oba své
operandy a spojı́ jejich výsledné sekvence do jedné. Ke konstrukci sekvence lze ale také využı́t
výrazu s operátorem to, který můžeme nazvat rozsahovým výrazem (range expression). Jako
oba operandy jsou očekávány celá čı́sla (typ xs:integer, v našı́ implementaci typ number).
Vznikne sekvence složená z celých čı́sel - obou operandů a všech celých čı́sel mezi nimi ve
vzestupném pořadı́.
Pokud je jeden z operandů prázdná sekvence nebo pokud je hodnota prvnı́ho operendu většı́
než druhého, vznikne prázdná sekvence. V přı́padě shody hodnoty obou operandů vznikne
singleton s touto hodnotou.
Predikáty naleznou své uplatněnı́ nejen při zpracovánı́ výrazů, převzatých z jazyka XPath.
Jazyk XQuery nabı́zı́ možnost použı́t predikáty i k filtrovánı́ sekvencı́, poskytovaných tzv.
primárnı́mi výrazy (literály, odkazy na proměnné, uzávorkované výrazy, operátor ’.’, volánı́
funkcı́, konstruktory). Tuto konstrukci označuje norma jako filtrujı́cı́ výraz (filter expression),
přı́kladem jsou výrazy $products[price gt 100], výše uvedené (1 to 100)[. mod 5 eq 0],
(21 to 29)[5] nebo $orders[fn:position() = (5 to 9)].
Ke kombinovánı́ sekvencı́ uzlů sloužı́ operátory union, ’|’, intersect a except. V podstatě
se jedná o množinové operace. Je vhodné zdůraznit, že tyto operátory jsou určeny pro zpracovávánı́ pouze sekvencı́ uzlů a pro jiné datové typy končı́ jejich vyhodnocenı́ chybou. Také je
nutné mı́t na paměti, že ve výsledné sekvenci nejsou povoleny duplicity uzlů - ty jsou vyřazovány
na základě uzlové identity (viz 3.2.6). Jednotlivé operátory majı́ následujı́cı́ sémantiku:
• Operátory union a ’|’ jsou ekvivalentnı́. Jejich výsledkem je spojenı́ dvou sekvencı́, které
jsou operandy, do jedné sekvence, obsahujı́cı́ uzly obou sekvencı́.
• Operátor intersect vracı́ sekvenci uzlů, které jsou k nalezenı́ v obou sekvencı́ch.
• except je operátorem vracejı́cı́m sekvenci uzlů, které jsou obsaženy v prvnı́m operandu
a nenacházı́ se v druhém operandu.
3.2.5
Aritmetické výrazy
Mezi aritmetické výrazy zařazujeme výrazy s operátory ’+’, ’-’, ’*’, div (běžné dělenı́, obvyklý
symbol ’/’ je použit k oddělenı́ kroků v cestě XPath), idiv (celočı́selné dělenı́) a mod (modulo,
tj. zbytek po celočı́selném dělenı́). Do této skupiny patřı́ kromě uvedených binárnı́ch operátorů
také unárnı́ operátory ’+’ a ’-’.
Každý operand je podroben atomizaci. Je-li výsledekem atomizace některého operandu
prázdná sekvence, je výsledkem vyhodnocenı́ celého operandu prázdná sekvence. Nenı́-li jeden
z operandů singletonem nebo nepodařı́-li se ho přetypovat na xs:double (v našı́ implementaci
zahrnutý pod typem number), skončı́ vyhodnocenı́ výrazu chybou.
26
KAPITOLA 3. ANALÝZA A NÁVRH IMPLEMENTACE XQUERY
3.2.6
Výrazy s porovnánı́m
Jazyk XQuery umožňuje vzájemné porovnánı́ dvou hodnot. Rozlišujı́ se celkem tři druhy
porovnánı́.
Porovnánı́ hodnot (value comparison) využı́vajı́ operátory eq, ne, lt, le, gt a ge. Jsou
určeny k porovnánı́ jedné hodnoty na každé straně operátoru. Na každý operand je aplikována
atomizace. Je-li výsledkem atomizace některého operandu prázdná sekvence, je výsledkem
vyhodnocenı́ celého operandu prázdná sekvence. Nenı́-li jeden z operandů singletonem, skončı́
vyhodnocenı́ výrazu chybou. Výsledkem je booleovská hodnota, která udává, zda operandy
vyhovujı́ požadovanému vzájemnému vztahu.
Operátory ’=’, ’!=’, ’<’, ’<=’, ’>’ a ’>=’ realizujı́ obecné porovnánı́ (general comparison).
V podstatě se jedná o aplikaci porovnánı́ nad kartézkým součinem obou sekvencı́, doplněné existenčnı́m kvantifikátorem. Může být aplikováno na sekvence libovolné délky. Na oba operandy
je nejdřı́ve aplikována atomizace. Výsledek porovnánı́ je booleovská hodnota true, pokud je
možné najı́t takový pár hodnot z jedné a druhé sekvence, který odpovı́dá požadovanému vztahu.
Jinak je výsledkem porovnánı́ hodnota false.
Poslednı́m druhem je uzlové porovnánı́ (node comparison). Zahrnuje operátory is, ’<<’
a ’>>’. Přı́pustnými hodnotami operandů je buď prázdná sekvence (kdy výsledkem vyhodnocenı́ je také prázdná sekvence) nebo singleton nesoucı́ uzel. Operátor is porovnává dva
uzly na základě uzlové identity2 . Operátory ’<<’ a ’>>’ se vyjadřujı́ o jejich vzájemném pořadı́
v dokumentu na základě document order. Tyto dva operátory nejsou do našı́ implementace
zahrnuty.
3.2.7
Logické výrazy
Za logické výrazy považujeme výrazy s operátory and nebo or. U obou operandů je určena
jejich efektivnı́ booleovská hodnota. Na tomto základě je aplikacı́ logického součinu nebo součtu
zı́skána booleovská hodnota výsledku. Logická operace not nenı́ přı́mo zahrnuta v gramatice
jazyka a je dostupná prostřednictvı́m funkce fn:not.
3.2.8
Konstruktory
Pokud tvrdı́me, že jazyk XQuery lze použı́t k transformacı́m XML dokumentů, nepochybně
máme na mysli konstruktory. S jejich pomocı́ můžeme v rámci dotazu vytvářet nové XML
struktury. Norma určuje, že konstruovat lze elementy, atributy, dokumenty (document node),
textové uzly, komentáře a instrukce pro zpracovánı́. V rámci našı́ implementace připouštı́me
konstrukci elementů, atributů, document node a textových uzlů.
Rozlišujeme dva druhy konstruktorů. Přı́mé konstruktory (direct constructors) použı́vajı́
notaci, připomı́najı́cı́ zápis elementů v samotném XML dokumentu. Umožňujı́ konstruovat
elementy a jejich atributy včetně jejich obsahu přı́mým zápisem. Uveďme přı́klad dotazu(!),
který tuto vlastnost jasně demonstruje:
<book isbn="isbn-0060229357">
2
uzlová identita je jednoznačnou a jedinečnou identifikacı́ každého uzlu ve stromu XML dokumentu
KAPITOLA 3. ANALÝZA A NÁVRH IMPLEMENTACE XQUERY
27
<title>Harold and the Purple Crayon</title>
<author>
<first>Crockett</first>
<last>Johnson</last>
</author>
</book>
Samozřejmě je žádoucı́ mı́t možnost vytvořit obsah elementu nebo atributu jako výsledek výrazu
XQuery. Podporu této konstrukce nabı́zı́ tzv. enclosed expressions, což jsou výrazy uzavřené
mezi složené závorky.
Pravidla pro převod výsledné sekvence, vzniklé vyhodnocenı́m takového výrazu, do obsahu elementu nebo atributu jsou poměrně složitá a přı́padného zájemce o jejich detailnı́ zněnı́ odkažme
na normu [6]. Pro ilustraci zde uvedeme jen jednoduchý přı́klad tohoto typu výrazu:
<example>
<p> Here is a query. </p>
<eg> $b/title </eg>
<p> Here is the result of the query. </p>
<eg>{ $b/title }</eg>
</example>
Druhou možnostı́, jak vytvářet vlastnı́ XML strukturu, jsou výpočtové konstruktory (computed constructors). Notace jejich zápisu připomı́ná pseudofunkčnı́ volánı́. Začı́ná klı́čovým
slovem, které udává typ vytvářeného uzlu. Norma uvádı́ klı́čová slova element, attribute,
document, text, processing-instruction a comment. Naše implementace připouštı́ klı́čová
slova element, attribute, document a text.
Při vytvářenı́ těch typů uzlů, které lze pojmenovat (element, atribut) následuje za klı́čovým
slovem jméno - buď v podobě přı́mo zapsaného literálu QName nebo v podobě name expression (syntakticky stejná forma jako výše zmı́něná enclosed expression, tedy výraz uzavřený
ve složených závorkách). Name expression po svém vyhodnocenı́ poskytuje textovou hodnotu
(podle normy typ xs:string, xs:QName nebo xs:untypedAtomic, v našı́ implementaci pak
string nebo QName), která se stane jménem vznikajı́cı́ho uzlu.
Ve obou přı́padech následuje výraz uzavřený v složených závorkách, jehož vyhodnocenı́m je
zı́skán obsah uzlu (dokumentu, elementu, atributu nebo textového uzlu). Pro zpracovánı́
výsledné sekvence z vyhodnoceného výrazu do obsahu uzlu platı́ stejná pravidla jako u přı́mých
konstruktorů. Na závěr uveďme opět přı́klad:
element book {
attribute isbn {"isbn-0060229357" },
element title { "Harold and the Purple Crayon"},
element author {
element first { "Crockett" },
element last {"Johnson" }
}
}
28
3.2.9
KAPITOLA 3. ANALÝZA A NÁVRH IMPLEMENTACE XQUERY
FLWOR výraz
Velmi mocnou konstrukcı́ jazyka XQuery je FLWOR výraz (zkratka vyslovována jako ”flower”),
který poskytuje podporu pro iterace, deklaraci proměnných a přiřazovánı́ jejich hodnoty. Lze
ho také účinně využı́t pro spojovánı́ dat z dvou a vı́ce dokumentů (obdoba join z SQL)
nebo pro převod dat do jiné struktury, než v jaké jsou aktuálně uspořádány. Lze tak
napřı́klad seznam skript, u kterých jsou evidováni jejich autoři, převést na seznam autorů,
kde bude u každého uveden seznam skript, na kterých se autorsky podı́lel. Posloupnost
klauzulı́ for-let-where-order by-return je inspirována velmi dobře známou posloupnostı́
select-from-where-order by jazyka SQL.
Klauzule for a let se v FLWOR výrazu použı́vajı́ k deklaraci proměnných, platných v celém
zbytku výrazu od mı́sta deklarace, a k přiřazovánı́ hodnot těmto proměnným. Norma popisuje
jejich činnost jako generovánı́ tzv. tuple stream, tedy proudu n-tic proměnných s přiřazenou
hodnotou.
Klauzule for iteruje nad jednotlivými prvky přiřazované sekvence. V každém kroku přiřadı́ do
proměnné aktuálnı́ prvek a postoupı́ tuto proměnnou do dalšı́ho zpracovánı́. Uveďme přı́klad
jednoduchého výrazu s klauzulı́ for a jeho výsledku - klauzule v tomto přı́padě vyprodukuje
3 n-tice (tuple):
for $s in (<jedna/>, <dva/>, <tri/>)
return <vystup>{$s}</vystup>
...
<vystup><jedna/></vystup>
<vystup><dva/></vystup>
<vystup><tri/></vystup>
V rámci jedné klauzule for lze přiřazovat do vı́ce proměnných, jednotlivá přiřazenı́ jsou
oddělena symbolem ’,’. Iterace nad přiřazovanými sekvencemi jsou pak vnořeny do sebe.
Celkový počet vygenerovaných n-tic lze tedy zı́skat pronásobenı́m délek přiřazovaných sekvencı́
mezi sebou - klauzule ve tvaru for $i in (1, 2), $j in (3, 4) vyprodukuje 4 n-tice.
Klauzule for umožňuje v průběhu iterace nad přiřazovanou sekvencı́ snadno zı́skávat informaci o pozici aktuálně přiřazovaného prvku v sekvenci dı́ky pozičnı́ proměnné. V přı́kladu
for $car at $i in ("Ford", "Mazda") jsou proto vyprodukovány 2 n-tice s obsahy ($car =
”Ford”, $i = 1) a ($car = ”Mazda”, $i = 2).
Klauzule let rovněž sloužı́ pro deklaraci proměnných a k přiřazovánı́ hodnot těmto proměnným.
Na rozdı́l od předchozı́ho for cyklu však nad přiřazovanými sekvencemi neiteruje a v jediném
kroku přiřazuje celou sekvenci jako hodnotu proměnné. Následujı́cı́ přı́klad jednoduchého
výrazu s klauzulı́ let tak vygeneruje pouze jedinou n-tici:
let $s := (<jedna/>, <dva/>, <tri/>)
return <vystup>{$s}</vystup>
...
<vystup><jedna/><dva/><tri/></vystup>
Při přiřazovánı́ hodnot pomocı́ klauzule let se logicky nenabı́zı́ možnost využı́t pozičnı́
proměnnou. Možnost přiřazovat hodnotu vı́ce proměnným zůstává zachována, stejně jako
KAPITOLA 3. ANALÝZA A NÁVRH IMPLEMENTACE XQUERY
29
oddělujı́cı́ symbol ’,’. Pomocı́ symbolu ’,’ můžeme řetězit i celé klauzule for a let. V rámci
klauzulı́ for a let je možné deklarovat typ vzniklé proměnné použitı́m klı́čového slova as. Tuto
možnost naše implementace, vzhledem ke svým omezenı́m (viz dále), neposkytuje.
Nepovinná klauzule where je určena pro filtrovánı́ n-tic vygenerovaných předcházejı́cı́mi
klauzulemi for a let. Výraz, následujı́cı́ za klı́čovým slovem where, je vyhodnocen pro každou
n-tici. Je-li efektivnı́ booleovská hodnota tohoto vyhodnocenı́ true, je přı́slušná n-tice použita
pro zpracovánı́ klauzule return. V opačném přı́padě je tato n-tice vyřazena z dalšı́ho zpracovánı́.
Také následujı́cı́ klauzule order by je nepovinnou složkou FLWOR výrazu. Nenı́-li přı́tomná,
řı́dı́ se pořadı́ v tuple stream na základě pořadı́ v klauzulı́ch for a let. V přı́padě jejı́ přı́tomnosti
se pořadı́ v tuple stream řı́dı́ pořadı́m vytvořeným na základě specifikacı́ řazenı́. Specifikace
řazenı́ zahrnuje výraz, který bude vyhodnocen pro každou n-tici (při přı́tomnosti klauzule
where jen ty, splňujı́cı́ podmı́nku této klauzule). Atomizovaná hodnota výsledku tohoto výrazu
se stane hodnotou, podle které budou jednotlivé tuple seřazeny.
V rámci specifikace řazenı́ lze pomocı́ klı́čových slov ascending a descending určit vzestupný nebo sestupný smysl řazenı́. Implicitně se předpokládá vzestupné řazenı́. Ve specifikaci
řazenı́ lze také pomocı́ klı́čových slov empty least a empty greatest určit způsob zacházenı́
s prázdnými hodnotami. Jednotlivé specifikace řazenı́ jsou odděleny znakem ’,’ a majı́ klesajı́cı́
prioritu.
Klauzule return uzavı́rá FLWOR výraz. Za klı́čovým slovem return následuje výraz, který je
vyhodnocen pro každou n-tici v tuple stream. Výsledné hodnoty těchto vyhodnocenı́ za všechny
n-tice jsou zřetězeny stejným způsobem, jaký předepisuje operátor ’,’. Tı́m je zkonstruován
výsledek celého FLWOR výrazu. Na závěr uveďme přı́klad dotazu, který demonstruje použitı́
všech popsaných klauzulı́:
for $d in fn:doc("depts.xml")/depts/deptno
let $e := fn:doc("emps.xml")/emps/emp[deptno = $d]
where fn:count($e) >= 10
order by fn:avg($e/salary) descending
return
<big-dept>
{
$d,
<headcount>{fn:count($e)}</headcount>,
<avgsal>{fn:avg($e/salary)}</avgsal>
}
</big-dept>
3.2.10
Podmı́něné výrazy
Podmı́něný výraz je zastoupen obvyklou triádou klı́čových slov if, then a else. Výraz za
klı́čovým slovem if, uzavřený do kulatých závorek, je vyhodnocen a následně je určena jeho
efektivnı́ booleovská hodnota. Pokud je rovna true, je vyhodnocen výraz za klı́čovým slovem
then a jeho hodnota je vrácena jako výsledek celého podmı́něného výrazu. V přı́padě, že je
hodnota podmı́nky false, je stejným způsobem vyhodnocen výraz za klı́čovým slovem else
a vrácena jeho hodnota.
30
KAPITOLA 3. ANALÝZA A NÁVRH IMPLEMENTACE XQUERY
3.2.11
Kvantifikované výrazy
XQuery poskytuje možnost využı́t existenčnı́ a obecný kvantifikátor. Kvantifikované výrazy
začı́najı́ určenı́m druhu kvantifikátoru, tj. klı́čovým slovem some pro existenčnı́ a every
pro obecný kvantifikátor. Následuje deklarace proměnných, která má stejnou strukturu jako
v klauzuli for FLWOR výrazu, tedy s použitı́m klı́čového slova in. Podobně je možné
deklarovat vı́ce proměnných - jejich deklarace jsou vzájemně odděleny znakem ’,’. Stejně jako
v for cyklu jsou také vytvářeny jednotlivé tuple, tedy n-tice proměnných s konkrétnı́ přiřazenou
hodnotou. Deklarace proměnných je ukončena klı́čovým slovem satisfies, následovaným
podmı́nkovým výrazem.
Hodnota kvantifikovaných výrazů je určena na základě následujı́cı́ch pravidel:
• Pokud je použit existenčnı́ kvantifikátor some, je hodnota celého výrazu true jedině,
pokud alespoň jedno vyhodnocenı́ podmı́nkového výrazu skončilo s efektivnı́ booleovskou
hodnotou true.
Jinak je výsledkem kvantifikovaného výrazu false. Hodnota false je výsledkem i tehdy,
když deklarace proměnných nevede k vytvořenı́ ani jednoho tuple a podmı́nkový výraz
tedy nenı́ vyhodnocen ani jednou.
• Při použitı́ obecného kvantifikátoru every je hodnota celého výrazu true tehdy, když
všechna vyhodnocenı́ podmı́nkového výrazu skončila s efektivnı́ booleovskou hodnotou
true.
V opačném přı́padě je hodnota kvantifikovaného výrazu false. V přı́padě, že na základě
deklarace proměnných nedojde ani k jednomu vyhodnocenı́ podmı́nkového výrazu, je
hodnota kvantifikovaného výrazu true.
Norma opět dovoluje definovat typ deklarované proměnné. Vzhledem k omezenı́m implementace
XQuery v rámci projektu CellStore nenı́ tato možnost podporována.
3.2.12
Dalšı́ partie jazyka XQuery
Norma jazyka XQuery poskytuje rozsáhlé možnosti při práci s typy. Je možné pomocı́
operátoru instance of ověřovat, zda výraz vracı́ sekvenci složenou z prvků se specifikovaným typem. Na základě výrazu s operátorem typeswitch lze větvit zpracovávánı́ podle typu testovaného výrazu. Hodnotu zı́skanou vyhodnocenı́m výrazu je možné přetypovat
pomocı́ operátoru cast as, přı́padně ověřit možnost jejı́ho přetypovánı́ použitı́m operátorů
castable as a treat as.
V rámci dotazu je rovněž možné definovat novou funkci a následně ji v tomto dotazu použı́t.
Dotaz může být složen z modulů, které mohou být importovány z vnějšı́ho souboru. Stejně
tak mohou být v prologu, tedy úvodnı́ části dotazu, specifikována řada nastavenı́ pro výkonné
jádro XQuery, odkazy na jmenné prostory, deklarace proměnných a funkcı́, apod.
Možnosti jazyka, popsané v tomto odstavci, nejsou v představované implementaci vzhledem
k jejı́m omezenı́m podchyceny a představujı́ tak výzvu pro jejı́ budoucı́ rozvoj.
KAPITOLA 3. ANALÝZA A NÁVRH IMPLEMENTACE XQUERY
3.3
31
Omezenı́ implementace XQuery v rámci CellStore
Nižšı́ vrstvy databáze CellStore nepodporujı́ práci s typovým modelem XML dokumentu tak,
jak jej určuje jeho schéma.
Vzhledem k tomuto faktu a také vzhledem k náročnosti implementace kompletnı́ho datového
modelu XDM byla omezena i množina typů, rozeznávaná v této pilotnı́ fázi implementace
XQuery.
Typový model v popisované implementaci rozlišuje následujı́cı́mi typy: boolean (booleovská
hodnota), number (čı́slo), string (textový řetězec), node (XML uzel), NCName a QName (XML
jména).
V rámci XML uzlů jsou povoleny uzly typu dokument, element, atribut a text. Hodnoty jiných
typů nejsou rozeznávány.
V důsledku tohoto omezenı́ byla z implementované gramatiky jazyka vypuštěna pravidla
s přı́mou návaznostı́ na práci s typy. Podporováno nenı́ ověřovánı́ typu, přetypovánı́ ani větvenı́
podle typu.
Omezena jsou také některá pravidla, dovolujı́cı́ filtrovánı́ uzlů v XPath dotazech na základě
typu - zde implementace připouštı́ pouze již uvedené typy XML uzlů, tj. dokument, element,
atribut a text.
V implementované gramatice se také nenacházejı́ pravidla, která norma shrnuje pod společnou
hlavičku prologu. Tato pravidla sloužı́ převážně pro nastavovánı́ vlastnostı́ XQuery procesoru,
import modulů a připojenı́ namespace před začátkem samotného zpracovávánı́ dotazu a také
pro zavedenı́ uživatelsky definovaných funkcı́.
Přehled skutečně implementovaných pravidel gramatiky je k nalezenı́ v přı́lohách.
Kromě uživatelsky definovaných funkcı́ udává norma několik desı́tek funkcı́ vestavěných. Vzhledem k omezené časové dotaci a také vzhledem k závislosti některých těchto funkcı́ na nepodporovaných datových typech byla z těchto funkcı́ implementována pouze množina nejběžněji
použı́vaných. Jejich seznam je k dispozici v přı́lohách.
Použitı́ nástroje SmaCC, jehož nasazenı́ je zdůvodněno nı́že, přinášı́ do implementace kromě
výhod i určitá omezenı́. Projevujı́ se zejména ve dvou oblastech.
Prvnı́ z nich je otázka klı́čových slov. Ty nejsou podle zněnı́ normy až na výjimky rezervované
a je tedy možné je použı́t také jako názvy (např. proměnných nebo elementů).
Scanner, vytvořený s pomocı́ SmaCC, však v takových přı́padech vracı́ token klı́čového slova
i v mı́stech, kde je očekáváno jméno. Důsledkem je chyba během parsovánı́ dotazu, která plyne
z nesplněnı́ pravidel gramatiky jazyka. Proto jsou v popisované implementaci považována
všechna klı́čová slova za vyhrazená.
S podobnými problémy se scanner a parser, postavený na základě tohoto nástroje, potýká i při
čtenı́ zápisu přı́mých konstruktorů, zejména těch, jejichž obsah je tzv. smı́šený (mixed content).
V takové situaci vlastně vyžadujeme po nástroji, určeném pro čtenı́ zápisu v programovacı́m
jazyku, aby byl plnohodnotným XML procesorem.
32
KAPITOLA 3. ANALÝZA A NÁVRH IMPLEMENTACE XQUERY
Pro zajištěnı́ alespoň určité funkčnosti byla gramatika jazyka v těchto pasážı́ch výrazně
zjednodušena a vytvářenı́ textového a smı́šeného obsahu elementů je výrazně omezeno.
3.4
Implementačnı́ platforma
Seznámili jsme se s možnostmi a omezenı́mi jazyka XQuery, tak jak jsou nabı́zeny budoucı́m
uživatelům našı́ implementace. Máme představu, jaké požadavky na vyvı́jený systém bude tato
norma klást.
Vı́me také, jak vypadá architektura nativnı́ XML databáze CellStore, na jejichž základech
svoji implementaci budeme stavět. V této fázi analýzy již tedy nezbývá nic jiného než popsat
nástroje, s jejichž pomocı́ se rozhodneme implementaci realizovat.
3.4.1
Smalltalk/X
Základnı́m rozhodnutı́m je samozřejmě volba programovacı́ho jazyka a vývojového prostředı́.
Dosavadnı́ kód databáze CellStore je vyvinut v jazyce Smalltalk za použitı́ vývojového prostředı́
Smalltalk/X. Použité vývojové prostředı́ určuje v tomto přı́padě i konkrétnı́ dialekt Smalltalku.
Pro bližšı́ seznámenı́ s programovacı́m jazykem Smalltalk lze doporučit [22]. Uveďme několik
základnı́ch vlastnostı́ Smalltalk/X:
• Jedná se o čistě objektový systém.
• Kompletnı́ zdrojové kódy celého systému jsou dostupné.
• Disponuje vı́ceúrovňovým garbage collectorem.
• Použı́vá inkrementálnı́ kompilátor.
• Umožňuje jednoduchou vazbu na jazyk C.
• Podporuje inkrementálnı́ a interaktivnı́ tvorbu spolu se snadným refaktoringem.
Vzhledem k těmto výhodným vlastnostem bylo pro implementaci XQuery zvoleno také prostředı́
Smalltalk/X. Jednotnost prostředı́, čistota návrhu a znovupoužitelnost existujı́cı́ho kódu projektu CellStore jsou přesvědčivé argumenty. Bylo se tak také možné vyhnout nemalým
problémům, které by přinesla volba jiného prostředı́ nebo dokonce jazyka a následná integrace
s kódem ve stávajı́cı́m prostředı́.
Kromě využitı́ mnoha základnı́ch objektů jazyka Smalltalk tak bylo možné použı́t i některé
nástroje určené pro toto prostředı́, které usnadnily zvládnutı́ značného rozsahu celého úkolu.
V následujı́cı́ch odstavcı́ch si je krátce přiblı́žı́me.
3.4.2
SmaCC
Tvorba lexikálnı́ho a syntaktického analyzátoru je pro jazyky s rozsáhlejšı́mi gramatikami
náročnou činnostı́, a to jak z pohledu nároků na čas, tak dı́ky možnosti dopustit se na základě
KAPITOLA 3. ANALÝZA A NÁVRH IMPLEMENTACE XQUERY
33
přehlédnutı́ zbytečné chyby. Přitom se jedná o činnost do značné mı́ry mechanickou a poměrně
dobře automatizovatelnou.
Nelze se proto divit značné popularitě, které se v prostředı́ programovacı́ho jazyka C a Unixu
obecně těšı́ nástroje lex, yacc, flex nebo bison. Jedná se buď o generátory lexikálnı́ch analyzátorů nebo o tzv. compiler-compiler systémy. Na základě regulárnı́ch výrazů a pravidel
gramatiky sestavujı́ lexikálnı́ a syntaktické analyzátory v jazyce C a dovolujı́ doplňovat jednotlivým pravidlům sémantický význam a výkonný kód.
Jejich obdobou pro jazyk Smalltalk je nástroj SmaCC [19], vyvinutý společnostı́ The Refactory
a uvolněný jako open source. Tento nástroj umožňuje na základě předložených regulárnı́ch
výrazů a LALR(1) gramatiky v notaci EBNF sestavit lexikálnı́ a syntaktický analyzátor,
tj. scanner a parser.
Výhody a nevýhody použitı́ tohoto nástroje jsou zřejmé z předchozı́ho textu. Zřetelnou
výhodou je časová úspora a výrazně efektivnějšı́ vývoj při úpravách a doplňovánı́ implementované gramatiky. Bez tohoto nástroje by v dané časové dotaci nebylo možné realizovat popisovanou implementaci v žádoucı́m rozsahu, neboť většina času by musela být obětována ručnı́mu
naprogramovánı́ scanneru a parseru. Nevýhodou je jen málo elegantnı́ práce s parsovánı́m
”volného” obsahu XML elementů v přı́mých konstruktorech a kolize s pravidlem o nerezervovaných klı́čových slovech.
3.4.3
SUnit
SUnit [10] je open source nástrojem pro jednotkové testovánı́ (unit testing).
testovánı́ je testovánı́ jednotlivých třı́d nebo malých funkčnı́ch celků.
Jednotkové
Výhodou se jednotkové testovánı́ stává v přı́padě rozsáhlejšı́ho refaktoringu, kdy je možné po
provedených změnách kódu rychle ověřit dopady do funkčnosti celého systému. Umožněno je
také použitı́ metodiky test driven development.
Mezi nevýhody je nutné započı́tat množstvı́ času, strávené psanı́m testů, a skutečnost, že jen
málokdy se podařı́ jednotkovým testem pokrýt všechny stavy a větve zpracovánı́, kterými může
testovaný objekt procházet. I přes tyto nevýhody je ale použitı́ SUnit značným přı́nosem.
3.5
Funkčnı́ celky implementace
Rozdělme nynı́ celou implementaci do několika funkčnı́ch celků. Každý z těchto celků se zabývá
určitou částı́ zpracovánı́ dotazu nebo poskytuje služby jiným celkům. V přı́lohách je k dispozici
UML diagram, který zachycuje jednotlivé třı́dy a vazby mezi nimi.
3.5.1
Rozhranı́ implementace
Tato implementace může být integrována do většı́ch programových celků, ve kterých bude
zajišťovat zpracovánı́ dotazů v jazyce XQuery. Přı́kladem takového rozsáhlého programového
celku je nativnı́ XML databáze CellStore. Rozhranı́m pro vývojáře těchto vyššı́ch celků pak
je hlavnı́ třı́da implementace - XQueryExecutor. Tato třı́da převezme dotaz v podobě tex-
34
KAPITOLA 3. ANALÝZA A NÁVRH IMPLEMENTACE XQUERY
tového řetězce, zajistı́ jeho zpracovánı́ a vrátı́ výsledky. V přı́padě chyby během zpracovánı́
vyvolá některou z definovaných výjimek. Rovněž je zodpovědná za správu a uvolněnı́ datových
zdrojů, použitých během dotazu. Přı́stup k datovým zdrojům zprostředkovává instance document provideru, kterou je umožněno nastavovat. XQueryExecutor deleguje většinu výkonných
činnosti na spolupracujı́cı́ třı́dy.
3.5.2
Vytvořenı́ stromu abstraktnı́ syntaxe
Prvnı́m krokem při zpracovánı́ dotazu je jeho parsovánı́ a vytvořenı́ stromu abstraktnı́ syntaxe
(abstract syntax tree, AST). Parsovánı́ dotazu zajišťujı́ dvě třı́dy, vytvořené pomocı́ SmaCC.
XQueryScanner, tj. lexikálnı́ analyzátor, který štěpı́ dotaz ve formě textového řetězce na
jednotlivé tokeny a XQueryParser, tj. syntaktický analyzátor, který kontroluje správnou
posloupnost jednotlivých tokenů podle pravidel gramatiky a vytvářı́ na jejich základě strom
abstraktnı́ syntaxe. Ten je pak objektovou reprezentacı́ dotazu v paměti. Třı́dy, jejichž instance
jej tvořı́, jsou potomky stejného předka AstNode a budou reprezentovat jednotlivé jazykové
konstrukce a vazby mezi nimi.
3.5.3
Zpracovánı́ stromu abstraktnı́ syntaxe
Zodpovědnost za zpracovánı́ stromu abstraktnı́ syntaxe nese XQueryInterpreter. Ten se
zabývá interpretacı́ jednotlivých syntaktických uzlů a tı́m i prováděnı́m jednotlivých výrazů
v celém dotazu. Pro tuto činnost je velmi vhodná aplikace návrhového vzoru (design pattern)
Visitor. Tento návrhový vzor přiblı́žı́me v dalšı́m textu.
V průběhu zpracovávánı́ jednotlivých přı́kazů XQuery je v návaznosti na jeho filosofii třeba
uchovávat kontext. Pro tento účel zavedeme samostatnou třı́du XQueryContext, v jejı́mž
rámci budeme udržovat všechny složky kontextu, které implementace použı́vá. Samostatnou
třı́du XQueryDataContextItem máme pro jednotlivé prvky datového kontextu.
3.5.4
Práce s datovými zdroji
Pro práci s datovými zdroji je použita již zmı́něná filosofie document provideru, který vracı́
na základě požadované URI document adaptory pro přı́stup k jednotlivým datovým zdrojům.
Konkrétnı́ realizace těchto třı́d jsou v kompetenci vyššı́ho programového celku, v jehož rámci
je implementace XQuery použita. Samotná implementace pouze definuje požadovaný protokol,
který musı́ tyto třı́dy splňovat. Je definována sada testů, která umožňuje vyššı́mu celku otestovat, že tento protokol implementujı́ správně.
Document adaptor poskytuje interface k datovému zdroji ve smyslu navigace v dokumentu
pomocı́ XPath os a zı́skávánı́ dat. Dı́ky otevřené možnosti implementovat dalšı́ varianty document adaptorů je možné nechat implementaci pracovat nad různými druhy datových zdrojů.
V současné době jsou implementovány document adaptory nad datovými zdroji typu databáze
CellStore (prefix URI datového zdroje xmldb:), soubor v souborovém systému (prefix file:)
nebo dokument dostupný prostřednictvı́m Internetu (např. prefix http:). Nenı́ problém zajistit, aby implementace pracovala nad jakoukoli jinou strukturou, pokud pro ni budou definovány požadované operace. Tuto vlastnost zajišťuje použitı́ návrhového vzoru Adapter, který
přehledově vysvětlı́me v textu dále.
KAPITOLA 3. ANALÝZA A NÁVRH IMPLEMENTACE XQUERY
35
Document provider je zodpovědný za poskytovánı́ document adaptorů jednotlivých datových
zdrojů podle jejich typu, identifikovaného na základě prefixu URI požadovaného dokumentu.
Jeho činnost dobře popisuje návrhový vzor Factory, který bude také vysvětlen v dalšı́m textu.
Během dotazovánı́ jednotlivých datových zdrojů zı́skává XQueryInterpreter sekvence XML
uzlů. Ty mohou být začleněny do XML struktur, nově vzniklých v rámci zpracovánı́ dotazu,
a mohou se s nově vzniklými strukturami mı́sit v jedné sekvenci. Proto je nutné, aby reprezentace uzlů bez ohledu na jejich původ sdı́lela stejný protokol a bylo proto možné s nimi pracovat
stejným způsobem.
Uzly, zı́skané přı́stupem do datových zdrojů, jsou reprezentovány instancemi třı́dy XQueryAccessedNode. Pokud nově vznikly v paměti během zpracovánı́ dotazu na základě výrazu
s konstruktorem, jsou reprezentovány instancemi třı́dy XQueryConstructedNode. Obě tyto
třı́dy jsou potomkem společného předka, kterým je třı́da XQueryAbstractNode.
3.5.5
Volánı́ funkcı́
Jazyk XQuery poskytuje uživateli možnost volat během zpracovánı́ dotazu funkce. V této
implementaci je podporována pouze část z výčtu vestavěných funkcı́ [26]. Udržovánı́m seznamu
dostupných funkcı́ se zabývá třı́da XQueryFuncTable. Požadavek na vyhodnocenı́ funkce
s danými parametry v rámci aktuálnı́ho kontextu jı́ předává XQueryInterpreter. Instance třı́dy
XQueryFuncTable vyhledá podle jména funkce v tabulce funkcı́ odpovı́dajı́cı́ funkčnı́ třı́du,
vytvořı́ jejı́ instanci a požádá ji o vyhodnocenı́ těla funkce.
Funkčnı́ třı́dy, tj. implementace konkrétnı́ch funkcı́, jsou potomkem společného předka,
kterým je třı́da XQueryFunction. Ta definuje protokol, použı́vaný při vyhodnocovánı́ funkcı́.
Výsledek volánı́ funkce je prostřednictvı́m XQueryFuncTable vrácen XQueryInterpreteru, který
o vyhodnocenı́ funkce původně požádal.
3.5.6
Výstupnı́ formát, výjimky
Výstupnı́m formátem výsledku, který rozhranı́ implementace XQuery poskytuje jako odpověď
na dotaz, je sekvence složená z instancı́ třı́dy XQueryDataContextItem. V přı́padě, že během
zpracovánı́ dotazu dojde k chybě, z nı́ž se nenı́ možné zotavit, je vyvolána výjimka a zpracovánı́
dotazu je ukončeno. Pokud došlo k takové chybě během vytvářenı́ stromu abstraktnı́ syntaxe,
vyvolá implementace výjimku XQueryParserError. Došlo-li k chybě až ve fázi interpretace
AST, pak je vyvolána výjimka XQueryInterpreterError.
3.5.7
Grafické uživatelské rozhranı́
Implementace XQuery nijak nebránı́ přizpůsobit vstup dotazu a výstup výsledku konkrétnı́m
potřebám programového celku, do kterého je integrována. Poskytuje však také své vlastnı́
jednoduché uživatelské rozhranı́ v podobě třı́dy XQueryExecutorUI. Dotaz, který uživatel
zadal prostřednictvı́m tohoto rozhranı́, je standardnı́ cestou předán třı́dě XQueryExecutor a po
zpracovánı́ dotazu jsou zobrazeny jeho výsledky, přı́padně hlášenı́ o chybě.
36
3.5.8
KAPITOLA 3. ANALÝZA A NÁVRH IMPLEMENTACE XQUERY
Návrhový vzor Visitor
Tento návrhový vzor patřı́ mezi tzv. behaviorálnı́ vzory (behavioral patterns). Umožňuje
vytvořit metodu, která bude pracovat s vı́ce objekty uspořádanými do objektové struktury.
Vytvořenı́ nové metody by si nemělo vynucovat změnu objektů, s nimiž pracuje. Dále se
chceme vyhnout dotazovánı́ se na třı́du u každého objektu ve struktuře. U typových jazyků
(což se Smalltalku netýká) se také chceme vyhnout nutnému přetypovánı́.
V implementaci XQuery je tento návrhový vzor použit při zpracovávánı́ AST. Interpreter je
označen jako visitor - má řadu výkonných metod visitXXX pro každou ze třı́d, která se může
vyskytnout ve stromu abstraktnı́ syntaxe.
Pokud chceme, aby interpreter zpracoval konkrétnı́ instanci třı́dy v AST (v terminologii
návrhového vzoru označená jako element), zavoláme jejı́ metodu acceptVisitor s parametrem, obsahujı́cı́m odkaz na visitor. Tato metoda je v každé třı́dě překryta a jejı́m účelem je
dát visitoru souhlas, aby mohl pracovat s daty daného objektu. V podstatě se provede převolánı́
té z metod visitXXX visitoru, která odpovı́dá typu objektu. Jako parametr je předán odkaz
na navštı́vený objekt. Interpreter tak zı́skává údaje o typu třı́dy objektu a odkaz na něj. Může
tedy bez problému využı́vat metody této třı́dy respektive jejı́ instance.
Tı́mto způsobem je možné nechat jeden strom abstraktnı́ syntaxe beze změny zpracovat několika
různými způsoby podle toho, jaký použijeme visitor. Popis tohoto návrhového vzoru by nemohl
být kompletnı́, pokud by nebyl zdůrazněn koncept dvojitého směrovánı́ požadavku (double dispatch). Prvnı́ směrovánı́ požadavku je od visitoru ke konkrétnı́mu elementu, který odpovědı́
zpět visitoru (druhé nasměrovánı́ požadavku) souhlası́ s návštěvou a identifikuje typ třı́dy.
3.5.9
Návrhový vzor Adapter
Návrhový vzor Adapter patřı́ mezi strukturálnı́ vzory (structural patterns). Usnadňuje u existujı́cı́ třı́dy jejı́ přizpůsobenı́ požadovanému rozhranı́. Sloužı́ k zajištěnı́ propojenosti třı́d tak,
aby pracovaly v komplexnı́m programu. Klientské třı́dy jsou přes třı́du Adapteru odstı́něny od
odlišnostı́ jednotlivých adaptovaných třı́d.
V implementaci XQuery jsou adaptovanými třı́dami druhy datových zdrojů, tak jak jsou objektově reprezentovány přı́mo jazykem Smalltalk. Pro každý druh datového zdroje existuje
Adapter v podobě přı́slušného document adaptoru, který jej adaptuje na garantovaný jednotný
protokol pro práci se všemi datovými zdroji. Volánı́ metod definovaného rozhranı́ tak document adaptor převádı́ na volánı́ metod a prováděnı́ operacı́, specifických pro danou objektovou
reprezentaci datového zdroje.
3.5.10
Návrhový vzor Factory
Návrhový vzor Factory je řazen mezi vzory pro tvorbu objektů (creational patterns). Pro jeho
použitı́ je předpokladem existence několika třı́d, které sice sdı́lejı́ stejný protokol, ale poskytujı́ různé služby nad různými daty. Tento návrhový vzor potom dovoluje vybrat v průběhu
programu vytvořenı́ instance některé z těchto třı́d.
Je definován objekt Factory, který se stará o způsob vytvářenı́ instancı́ podřı́zených třı́d
KAPITOLA 3. ANALÝZA A NÁVRH IMPLEMENTACE XQUERY
37
a poskytuje klientským třı́dám metodu, pomocı́ které mohou novou instanci podřı́zené třı́dy
vyžadovat. Odstiňuje tak klientské třı́dy od logiky při vytvářenı́ instance požadovaného objektu.
Implementace XQuery použı́vá tento návrhový vzor pro koncept document provideru. Document provider představuje Factory, která disponuje definovanou metodou - ta přijı́má URI
požadovaného dokumentu a na základě prefixu vracı́ nově vytvořenou instanci přı́slušného document adaptoru.
Podrobnějšı́ informace o návrhových vzorech ve Smalltalku lze načerpat v [1].
38
KAPITOLA 3. ANALÝZA A NÁVRH IMPLEMENTACE XQUERY
KAPITOLA 4. REALIZACE IMPLEMENTACE XQUERY
39
4 Realizace implementace XQuery
4.1
Funkčnı́ třı́dy a datové struktury
V následujı́cı́m textu se budeme věnovat popisu vlastnostı́ a účelu jednotlivých funkčnı́ch třı́d
a datových struktur, které společně tvořı́ implementaci XQuery. Všechny třı́dy, obsažené v implementaci, sdı́lejı́ jmenný prostor (namespace) XQuery. Pro přehlednost budeme členit tento
popis podle jednotlivých kategoriı́, do kterých jsou třı́dy implementace rozděleny v prostředı́
Smalltalk/X.
4.1.1
Kategorie třı́d XQuery-AST
Do této kategorie je zahrnuto velké množstvı́ třı́d, které sloužı́ k vytvořenı́ datové struktury
stromu abstraktnı́ syntaxe (abstract syntax tree, AST). Lze je rozpoznat podle společného
prefixu Ast ve jméně třı́dy, který všechny sdı́lejı́. Všechny tyto třı́dy majı́ také společného
předka AstNode.
Většině implementovaných pravidel gramatiky XQuery odpovı́dá některá z těchto třı́d. Kompletnı́ přehled implementovaných pravidel gramatiky a odpovı́dajı́cı́ch třı́d AST je k dispozici
v přı́lohách.
AstNode jako abstraktnı́ předek předepisuje všem svým potomkům implementaci metody
acceptVisitor. Tato metoda sloužı́ pro zajištěnı́ funkčnosti návrhového vzoru Visitor. Jednotlivé třı́dy AST představujı́ v terminologii toho návrhového vzoru tzv. element. Filosofie
návrhového vzoru Visitor byla představena v předcházejı́cı́m textu.
Předek také poskytuje jednotlivým potomkům podporu pro použitı́ mechanismu class type
hierarchy. Smalltalk jako beztypový jazyk nedisponuje snadným způsobem zjištěnı́, jakého
typu je daný - v zásadě obecný - objekt. V rámci omezené množiny třı́d s jednı́m společným
předkem je proto výhodné využı́t výše zmı́něného mechanismu.
Předek, tedy třı́da AstNode, je vybaven metodou pro každého potomka. Jméno metody začı́ná
prefixem is a pokračuje názvem konkrétnı́ třı́dy (např. isAstIfExpr). Předek na volánı́ každé
z těchto metod vracı́ booleovskou hodnotu false. Každý z potomků překrývá metodu se svým
jménem a vracı́ na jejı́ volánı́ booleovskou hodnotu true.
Pokud máme jistotu, že daný objekt je některým z potomků AstNode, můžeme volat kteroukoli
z těchto metod a ověřovat si tak třı́du objektu. Přitom se nevystavujeme nebezpečı́, že dojde
k výjimce dı́ky volánı́ nedefinované metody - každá z metod je definována nejméně na společném
předku.
Jednotlivı́ potomci představujı́ třı́dy, jejichž instance budou tvořit strom abstraktnı́ syntaxe,
tj. objektovou reprezentaci zadaného dotazu v paměti. Většina třı́d má definovány instančnı́
proměnné. Sloužı́ k udržovánı́ informacı́ a vazeb, které jsou vyžadovány sémantikou toho
pravidla gramatiky, kterému tato třı́da odpovı́dá.
Zpravidla se jedná o odkazy na instance jiných třı́d hierarchie AST nebo na konstantnı́ hodnoty.
Čtenı́ a manipulace s proměnnými z vnějšku třı́dy je umožněna běžnými metodami typu getter
(pro čtenı́) a setter (pro zápis).
40
4.1.2
KAPITOLA 4. REALIZACE IMPLEMENTACE XQUERY
Kategorie třı́d XQuery-DataNodes
V této kategorii lze nalézt třı́dy, které představujı́ nejdůležitějšı́ datové struktury, které implementace XQuery použı́vá. Postupně si je představı́me spolu s popisem jejich struktury, účelu
a zajı́mavých vlastnostı́. Začněme u trojice třı́d, které sloužı́ pro práci s XML uzly (XQueryAbstractNode, XQueryAccessedNode a XQueryConstructedNode).
XQueryAbstractNode
Třı́da představuje předka pro oba druhy XML uzlů, se kterými se v rámci implementace pracuje.
Společný protokol, který jim předepisuje, umožňuje jednotnou práci nad XML uzlem bez ohledu
na jeho původ. Značnou část protokolu také implementuje ve formě převolánı́ požadavku na
odpovı́dajı́cı́ metodu třı́dy XPathDocumentAdaptorProxy. Tato třı́da bude popsána dále.
Implementovaný protokol zahrnuje předevšı́m metody pro práci s osami, které lze na XML uzel
použı́t (např. metoda xpathChild). Výsledkem volánı́ těchto metod je sekvence, jejı́miž prvky
jsou výsledné uzly. Podstatné jsou také metody, s jejichž pomocı́ lze zı́skat jméno (xpathName)
nebo hodnotu (xpathValue) XML uzlu. Také je možné otestovat typ uzlu, napřı́klad pomocı́
metody xpathIsAttribute.
Dále protokol obsahuje metody pro konverzi uzlu na čistý text (asString), kopı́rovánı́ instance
uzlu při jejı́m zařazovánı́ do nově vznikajı́cı́ XML struktury (copyNodeWithParent) a pomocné
metody pro vytvářenı́ sekvence prvků při práci s osami a pro class type hierarchy.
XQueryAccessedNode
Prvnı́m druhem, který uvedeme, je třı́da reprezentujı́cı́ uzel vzniklý dotazem do datového
zdroje. Tento typ uzlu se může při práci s osami a dotazech na své jméno, hodnotu či typ
spolehnout na služby, poskytované document adaptory.
K tomuto účelu mu sloužı́ instančnı́ proměnné nodeId a documentAdaptor. V proměnné nodeId
se udržuje jednoznačná identifikace daného uzlu, tak jak ji definuje souvisejı́cı́ document adaptor. S výhodou se zde využı́vá beztypovosti jazyka Smalltalk. Třı́da instance uchovávané
v nodeId nenı́ z pohledu třı́dy XQueryAccessedNode významná a závisı́ na libovůli přı́slušného
document adaptoru, který je dostupný v proměnné documentAdaptor.
Dalšı́ instančnı́ proměnné se uplatnı́ v přı́padě, že je tento druh uzlu v rámci zpracovánı́ výrazů
s konstruktory začleněn do nově vznikajı́cı́ XML struktury. V takovém přı́padě bude zcela
jistě využita instančnı́ proměnná constructedParent, obsahujı́cı́ odkaz na jeho rodiče v této
struktuře.
Pokud budou v rámci dalšı́ho zpracovánı́ kladeny dotazy na potomky nebo atributy tohoto
uzlu, budou zodpovězeny s využitı́m document adaptoru a zároveň bude odpověď uchována
v proměnných constructedChildren a constructedAttributes pro dalšı́ obdobný dotaz.
Norma totiž předepisuje, že při začleněnı́ uzlu do nové XML struktury je vytvořena kopie tohoto
uzlu a celého XML stromu uzlů, jejichž je předkem. Popsaný postup tedy odpovı́dá požadavkům
normy a zrychluje vykonánı́ dotazu využitı́m mechanismu lazy inicializace u potomků uzlu.
Třı́da dále definuje postup kopı́rovánı́ své instance v metodě copyNodeWithParent a určuje, že
porovnánı́ dvou instancı́ pomocı́ operátoru ’=’ odpovı́dá porovnánı́ jejich nodeId.
KAPITOLA 4. REALIZACE IMPLEMENTACE XQUERY
41
XQueryConstructedNode
Pro reprezentaci uzlu, vzniklého během zpracovánı́ výrazu s konstruktorem, sloužı́ třı́da
XQueryConstructedNode. Jejı́ instančnı́ proměnné pokrývajı́ všechny údaje, které je nutné
pro uzel v našı́ implementaci udržovat.
Jde zejména o rodičovský uzel (nodeParent), seznamy uzlů potomků (nodeChildren) a
atributů (nodeAttributes). Podstatný je také typ uzlu (element, atribut, dokument, text;
nodeType), přı́padně hodnota (nodeValue) a jméno uzlu (nodeName).
Třı́da opět definuje postup kopı́rovánı́ své instance v metodě copyNodeWithParent. Navı́c se
záměrem zrychlenı́ překrývá některé metody, sloužı́cı́ pro dotazy, vztahujı́cı́ se přı́mo k uzlu.
Týká se to dotazů na typ uzlu (např. xpathIsElement) nebo na jeho jméno či hodnotu (např.
xpathValue).
Následujı́cı́ dvě třı́dy hrajı́ zásadnı́ roli při práci s kontextem během vyhodnocovánı́ jednotlivých
výrazů XQuery.
XQueryDataContext
Třı́da XQueryDataContext sloužı́ pro reprezentaci aktuálnı́ho kontextu. V popisované implementaci se skládá ze třı́ složek. Datový kontext (instančnı́ proměnná dataContext) uchovává
sekvenci prvků aktuálnı́ho kontextu. Z pohledu jazyka Smalltalk jde o OrderedCollection
složenou z instancı́ třı́dy XQueryDataContextItem.
Kontext proměnných (instančnı́ proměnná varContext) se použı́vá pro udržovánı́ seznamu
deklarovaných proměnných a jejich hodnot. Z pohledu jazyka Smalltalk se jedná o Dictionary,
kde je pod klı́čem jména proměnné uchováván datový kontext, reprezentujı́cı́ jejı́ obsah.
Pro předávánı́ informacı́, které nespadajı́ ani do jedné z těchto oblastı́, je určen volitelný kontext (optional context). V zásadě jde o implementaci dědičných a syntetizovaných atributů
některých pravidel gramatiky. Realizace ve Smalltalku je provedena pomocı́ Dictionary.
Třı́da krom očekávatelných metod typu getter a setter definuje také metody sloužı́cı́ pro
vyprázdněnı́ určité složky kontextu (např. dataContextEmpty), vytvořenı́ datového kontextu
z prvku (dataContextSingle) nebo kopı́rovanı́ kontextu (copyContext).
XQueryDataContextItem
Jednotlivé prvky v datovém kontextu jsou instancemi třı́dy XQueryDataContextItem. Tyto
instance sloužı́ jako nosič hodnoty v instančnı́ proměnné item a jejı́ho typu podle datového
modelu implementace v proměnné type. Třı́da dále nabı́zı́ metody pro konverzi prvku na čistý
text (metoda asString) a pro jeho atomizaci (metoda value).
Zbývajı́cı́ čtyři třı́dy této kategorie se uplatňujı́ v rámci volitelného kontextu.
XQueryInnerFocusItem
Třı́da se uplatňuje při zpracovánı́ částı́ gramatiky XQuery, které pracujı́ s konceptem inner focus. Jde o jednotlivé kroky cesty v XPath a vyhodnocovánı́ predikátů. Jak již bylo
zmı́něno v analýze, kontext udržuje informace o aktuálnı́m kontextovém prvku, kontextové pozici
a velikosti kontextu. Tyto informace se uchovávajı́ v odpovı́dajı́cı́ch instančnı́ch proměnných
contextItem, contextPosition a contextSize.
42
KAPITOLA 4. REALIZACE IMPLEMENTACE XQUERY
XQueryOrderByItem
Třı́da je použı́vána při sestavovánı́ výrazů, podle kterých bude řazen proud n-tic (tuple stream)
v rámci zpracovánı́ kluazule order by FLWOR výrazu. Shromažďuje pro danou n-tici vyhodnocenı́ jednotlivých řadicı́ch kritériı́ (instančnı́ proměnná orderSpecItems) a také výsledný
výraz, který n-tice produkuje podle klauzule return (instančnı́ proměnná returnValue).
XQueryOrderSpecItem
Údaje o jednom připraveném řadı́cı́m kritériu pro jednu n-tici jsou udržovány v instanci
této třı́dy. Tyto údaje zahrnujı́ smysl řazenı́ (instančnı́ proměnná ascDesc), způsob řazenı́
prázdných hodnot (emptyGreatestLeast) a samotnou hodnotu, podle které se bude řadit
(orderValue).
XQueryTupleItem
Při vyhodnocovánı́ FLWOR výrazu je třeba nejprve shromáždit údaje ze všech klauzulı́ for
a let. Na jejich základě pak dojde k vytvořenı́ proudu n-tic. Ke shromážděnı́ zmı́něných údajů
sloužı́ tato třı́da. Jejı́ instance evidujı́ druh klauzule (instančnı́ proměnná forLet), jméno
proměnné (varName) a pozičnı́ proměnné (positionalVarName), jejich hodnoty (varValue,
positionalVarValue) a tak referenci na AST stukturu, jejı́mž vyhodnocenı́m je možné hodnotu
přiřazovanou proměnné zı́skat (varExpr).
4.1.3
Kategorie třı́d XQuery-Exceptions
XQueryParserError
Tuto výjimku vyvolá XQueryExecutor v přı́padě, že dojde k chybě během fáze parsovánı́ dotazu
a vytvářenı́ stromu abstraktnı́ syntaxe. Třı́da je potomkem třı́dy Error, která je klasickou třı́dou
Smalltalku pro tento účel. Do textu výjimky je převzat text z původnı́, specifické výjimky
vyvolané nižšı́ vrstvou nebo samotným Smalltalkem.
XQueryInterpreterError
Při výskytu chyby v průběhu zpracovánı́ stromu abstraktnı́ syntaxe vyvolá XQueryExecutor výjimky XQueryInterpreterError. O jejı́ch vlastnostech platı́ veškeré informace, uvedené
k výjimce XQueryParserError.
4.1.4
Kategorie třı́d XQuery-Executor
XPathDocumentAdaptorProxy
Tato třı́da představuje specifickou formu document adaptoru. Skutečně je potomkem třı́dy
XPathDocumentAdaptor z jmenného prostoru XMLv2, která je určena jako předek implementacı́
konkrétnı́ch typů datových zdrojů. Přesto se přı́mo nezabývá jejich zpřı́stupňovánı́m. Namı́sto
toho sloužı́ jako mezivrstva mezi XML uzly (instance třı́d XQueryAccessedNode a XQueryComputedNode) a document adaptory.
XML uzly disponujı́ metodami pro práci s osami, typy uzlů, jejich jmény a hodnotami. Tyto
metody zpravidla převolávajı́ metodu z XPathDocumentAdaptor, která vyhodnotı́ stav uzlu
KAPITOLA 4. REALIZACE IMPLEMENTACE XQUERY
43
a provede zpracovánı́ žádosti. V přı́padě čistých accessed uzlů předá požadavek document
adaptoru, který přı́slušı́ datovému zdroji, odkud uzel pocházı́. Jedná-li se o constructed uzel,
jsou zı́skána a vrácena požadovaná data přı́mo z datových struktur uzlu. Pokud byl accessed
uzel začleněn do nově vznikajı́cı́ XML struktury, je vyhodnocovánı́ složitějšı́ a musı́ respektovat
pravidla, stanovená normou.
XQueryExecutor
XQueryExecutor je hlavnı́ třı́dou celé implementace XQuery a rozhranı́m, se kterým komunikujı́
vyššı́ programové celky, které implementaci použı́vajı́. Ty volajı́ metodu executeQuery, které
jako parametr předávajı́ textový řetězec s dotazem. Jako výsledek volánı́ očekávajı́ datový
kontext. Během volánı́ této metody je textový řetězec zpracován instancı́ třı́dy XQueryParser
a vytvořená struktura stromu abstraktnı́ syntaxe je uložena v instančnı́ proměnné astTree.
Strom abstraktnı́ syntaxe je dále předán ke zpracovánı́ instanci třı́dy XQueryInterpreter.
Při zpracovánı́ dotazu lze očekávat požadavky na document adaptory pro přı́stup k datovým
zdrojům. XQueryExecutor si k tomuto účelu v instančnı́ proměnné documentProvider udržuje
a také umožňuje nastavovat referenci na document provider. Implicitně je předpokládáno
použitı́ třı́dy XMLv2::XPathDocumentProvider. Document provideru jsou pak předávány
požadavky na poskytnutı́ document adaptorů na základě URI datového zdroje.
XQueryExecutoru jsou tyto požadavky zpracovávány pomocı́ metody documentAdaptorFor,
která na ně uplatňuje cachovánı́. V instančnı́ proměnné documentAdaptorsPool se udržujı́
v Dictionary pod klı́čem daného URI poskytnuté document adaptory. V přı́padě shody URI
jsou poskytovány z této cache namı́sto nového dotazu document provideru. XQueryExecutor
také poskytuje metodu releaseDocumentAdaptors. Sloužı́ pro uvolněnı́ document adaptorů,
použitých během dotazu, a korektnı́ uzavřenı́ souvisejı́cı́ch datových zdrojů. Jejı́ použitı́ vyššı́m
programovým celkem je předepsáno ve chvı́li, kdy uvolňujı́ referenci na datový kontext, zı́skaný
jako výsledek předchozı́ho dotazu.
XQueryFuncTable
Volánı́ funkcı́, tj. provedenı́ metody evaluate dané funkčnı́ třı́dy, provádı́ XQueryInterpreter prostřednictvı́m třı́dy XQueryFuncTable. Ta udržuje ve své instančnı́ proměnné table
Dictionary, jehož klı́čem jsou jména funkcı́ a obsahem reference na přı́slušné funkčnı́ třı́dy.
Tabulky využı́vá také metoda evaluate: inContext: withParameters: fromInterpreter:,
které dohledá na základě názvu funkce odpovı́dajı́cı́ funkčnı́ třı́du a zajistı́ vyhodnocenı́ jejı́ho
těla.
XQueryInterpreter
XQueryInterpreter zodpovı́dá za provedenı́ jednotlivých pravidel gramatiky, tak jsou jsou
v paměti reprezentována strukturou abstraktnı́ho stromu syntaxe. Je to tzv. visitor v terminologii stejnojmenného návrhového vzoru.
Kromě metody interpretTree, které je předána struktura AST a tak je zahájeno jejı́ zpracovávánı́, disponuje tedy v duchu filosofie tohoto návrhového vzoru řadou metod s prefixem
visit, které sloužı́ ke zpracovánı́ jednotlivých pravidel gramatiky. Podrobnějšı́mu popisu se
věnujeme v dalšı́ části této kapitoly. Ve svých instančnı́ch proměnných uchovává aktuálnı́ kontext (currentContext) a reference na nadřı́zený XQueryExecutor (xqueryExecutor) a tabulku
funkcı́ v XQueryFuncTable (funcTable).
44
KAPITOLA 4. REALIZACE IMPLEMENTACE XQUERY
Kromě již zmı́něných metod disponuje i řadou metod pomocných. Některé usnadňujı́ práci
s proměnnými v zadaném kontextu (napřı́klad metody boundVar: withValue: toContext:
nebo valueOfVar: inContext:), jiné poskytujı́ specifické služby pro zpracovánı́ konkrétnı́ch
pravidel gramatiky.
XQueryParser, XQueryScanner
Třı́dy XQueryParser a XQueryScanner jsou produkovány nástrojem SmaCC na základě pravidel
gramatiky jazyka XQuery a představujı́ syntaktický a lexikálnı́ analyzátor. Popis jejich fungovánı́ přesahuje rozsah i téma tohoto textu.
4.1.5
Kategorie třı́d XQuery-Functions
V této kategorii jsou sdruženy všechny třı́dy souvisejı́cı́ s implementacı́ vestavěných funkcı́.
Každá ze třı́d, jak plyne z jejich názvů, představuje jednu vestavěnou funkci. Seznam implementovaných funkcı́ je k dispozici v přı́lohách. Jejich společným předkem je třı́da XQueryFunction.
Na počátku vyhodnocenı́ volánı́ funkce je třeba předat funkci potřebné informace. V praxi
to znamená naplnit hodnotami přı́slušné instančnı́ proměnné. Předat je třeba informace
o aktuálnı́m kontextu, v němž je funkce volaná (instančnı́ proměnná givenContext), stejně jako
informaci o XQueryInterpreteru, který si vyhodnocenı́ funkce vyžádal (xqueryInterpreter).
Bezpodmı́nečně nutná je ale kolekce hodnot parametrů, reprezentovaná OrderedCollection
datových kontextů (parametersCollection).
XQueryFunction jako abstraktnı́ předek předepisuje svým potomkům implementaci metody
evaluate, která vyhodnotı́ se zadanými parametry a v zadaném kontextu tělo funkce a vrátı́
výsledek v podobě datového kontextu.
4.1.6
Kategorie třı́d XQuery-Tests
Třı́dy XQueryDocumentAdaptorTests, XQueryExecutorTests a XQueryParserTests
jsou součástı́ jednotkových testů implementace XQuery. Testovánı́ implementace se podrobněji
věnuje kapitola 5, kam odkážeme zájemce o dalšı́ informace, souvisejı́cı́ s těmito třı́dami.
4.1.7
Kategorie třı́d XQuery-UI
XQueryExecutorUI
Jediná třı́da této kategorie sloužı́ pro zobrazovánı́ jednoduchého grafického uživatelského
rozhranı́, které implementace poskytuje pro možnost názornějšı́ ilustrace své činnosti. Jinak se
obecně předpokládá zapojenı́ do komplexnějšı́ho GUI vyššı́ho programového celku, který v sobě
implementaci XQuery integruje.
Uživatelské rozhranı́ lze zobrazit přı́kazem XQuery::XQueryExecutorUI open.
KAPITOLA 4. REALIZACE IMPLEMENTACE XQUERY
4.2
45
Zpracovánı́ vybraných výrazů jazyka XQuery
V této části textu se budeme věnovat popisu postupu zpracovánı́ vybraných výrazů jazyka
XQuery, na kterých lze demonstrovat filosofii implementace.
4.2.1
Podmı́něné výrazy
Podmı́něné výrazy jsou výrazy s trojicı́ klı́čových slov if-then-else. V struktuře stromu
abstraktnı́ syntaxe se k reprezentaci tohoto výrazu použı́vá instance třı́dy AstIfExpr. Jejı́m
zpracovánı́m se v rámci třı́dy XQueryInterpreter zabývá metoda visitAstIfExpr.
Nejdřı́ve je do lokálnı́ proměnné givenContext odložena reference na aktuálnı́ kontext z instančnı́ proměnné currentContext třı́dy XQueryInterpreter. Pak je zpracován výraz za
klı́čovým slovem if, který je uložen v instančnı́ proměnné expr třı́dy AstIfExpr. Z aktuálnı́ho
kontextu po zpracovánı́ tohoto výrazu je pomocı́ metody effectiveBooleanValueOf třı́dy
XQueryInterpreter určena efektivnı́ booleovská hodnota.
Po obnovenı́ hodnot aktuálnı́ho kontextu z reference odložené v lokálnı́ proměnné givenContext
je zpracován buď výraz v instančnı́ proměnné trueExprSingle (výraz po klı́čovém slově
then) nebo falseExprSingle (výraz po klı́čovém slově else) v závislosti na určené efektivnı́
booleovské hodnotě. Aktuálnı́ kontext po vyhodnocenı́ zvoleného výrazu je ponechán beze
změny a je tak výsledkem vyhodnocenı́ celého podmı́něného výrazu.
4.2.2
Literály
Literály jsou podle typu ve struktuře stromu abstraktnı́ syntaxe reprezentovány instancemi třı́d
AstIntegerLiteral, AstDoubleLiteral, AstDecimalLiteral, AstStringLiteral, AstQName
a AstNCName. Jim odpovı́dajı́ přı́slušné metody s prefixem visit ve třı́dě XQueryInterpreter.
Princip práce všech těchto metod je shodný, postačı́ proto jeho vysvětlenı́ na přı́kladu metody
visitAstIntegerLiteral. Podstatou zpracovánı́ tohoto typu výrazů je vytvořenı́ nového
aktuálnı́ho kontextu kopiı́ stávajı́cı́ho. Modifikace stávajı́cı́ho kontextu nenı́ možná, neboť by
docházelo k ovlivňovánı́ nadřazených pravidel. U vytvořené kopie je do datového kontextu
umı́stěn jediný prvek s odpovı́dajı́cı́ hodnotou a typem (v tomto přı́padě number).
4.2.3
Reference na proměnné
Reference na proměnné se do značné mı́ry chovajı́ obdobně jako literály. Instance třı́dy
AstVarRef ve struktuře stromu abstraktnı́ syntaxe jsou v rámci třı́dy XQueryInterpreter
zpracovávány pomocı́ metody visitAstVarRef.
Vyhodnocenı́ výrazu začı́ná uchovánı́m reference na aktuálnı́ kontext v lokálnı́ proměnné
givenContext. Následně je vyhodnocen výraz v instančnı́ proměnné varName třı́dy AstVarRef.
Tı́m je v aktuálnı́m kontextu zı́skán literál s jménem proměnné.
Z kontextu, odloženého do lokálnı́ proměnné givenContext, je pořı́zena volánı́m metody
copyContext kopie a jako datový kontext je nastaven obsah proměnné. Obsah proměnné je
46
KAPITOLA 4. REALIZACE IMPLEMENTACE XQUERY
dostupný volánı́m metody valueOfVar. Nově vzniklý kontext je vrácen jako aktuálnı́ kontext
po vyhodnocenı́ výrazu s referencı́ na proměnnou.
4.2.4
Porovnánı́
Výrazy s porovnánı́m se ve struktuře AST reprezentujı́ instancı́ třı́dy AstComparisonExpr,
která je zpracovávána metodou visitAstComparisonExpr třı́dy XQueryInterpreter.
Na úvod je odložena reference na aktuálnı́ kontext do lokálnı́ proměnné givenContext.
Následuje vyhodnocenı́ výrazu vlevo od operátoru (instančnı́ proměnná rangeExprLeft objektu
třı́dy AstComparisonExpr), obnovenı́ aktuálnı́ho kontextu ke stavu v givenContext a vyhodnocenı́ výrazu vpravo od operátoru (instančnı́ proměnná rangeExprRight). Aktuálnı́ kontexty
po vyhodnocenı́ těchto výrazů jsou uchovány v lokálnı́ch proměnných zpracujı́cı́ metody.
Rozlišujı́ se tři druhy porovnávánı́. Porovnánı́ hodnot signalizuje neprázdná instančnı́ proměnná
valueComp objektu třı́dy AstComparisonExpr. V přı́padě, že datový kontext z levého i pravého
operandu je prázdný, tak se jako výsledek vrátı́ prázdný kontext. Jinak se provede ověřenı́, že
oba kontexty majı́ právě jeden prvek.
Tyto prvky jsou porovnány požadovaným operátorem, výsledkem je booleovská hodnota.
Z kontextu, uchováváného v lokálnı́ proměnné givenContext, je vytvořena kopie jako nový
aktuálnı́ kontext. Jako datový kontext je jı́ přiřazen singleton s výsledkovou hodnotou.
Obecné porovnánı́ připouštı́ jako operandy sekvence. Neprázdná je v tomto přı́padě u objektu
AstComparisonExpr instančnı́ proměnná generalComp. Vztah sekvencı́ je splněn, pokud alespoň jedna dvojice prvků z každé sekvencı́ tento vztah splňuje. S výhodou se v implementaci
využı́vá volánı́ metody anySatisfy třı́dy OrderedCollection. Práce s výslednou hodnotou je
stejná jako v předchozı́m přı́padě.
Porovnánı́ uzlů využı́vá uzlové identity, tak jak ji definujı́ jednotlivé třı́dy XML uzlů (accessed,
constructed).
4.2.5
FLWOR výraz
Vyhodnocenı́ FLWOR výrazů patřı́ mezi nejsložitějšı́ partie celé implementace. Z tohoto
důvodu probereme postup jejich zpracovánı́ pouze přehledově. Tento typ výrazů je ve struktuře
AST reprezentován instancemi třı́dy AstFLWORExpr a dalšı́ch návazných třı́d. Zpracovánı́m se
zabývá metoda visitAstFLWORExpr třı́dy XQueryInterpreter.
Reference na aktuálnı́ kontext je na začátku zpracovánı́ odložena do obligátnı́ lokálnı́ proměnné
givenContext. Aktuálnı́m kontext je nastaven na kopii stávajı́cı́ho kontextu. Následně jsou
volána zpracovánı́ uzlů AST reprezentujı́cı́ch jednotlivé klauzule for a let. Do aktuálnı́ho
kontextu, konkrétně do složky volitelného kontextu pod klı́čem flworTuple jsou jako výsledek
jejich zpracovánı́ ukládány instance třı́dy XQueryTupleItem.
Tyto instance jsou poté metodou forLetClauseBlooming třı́dy XQueryInterpreter rozvedeny
do podoby tuple streamu. Jednotlivé n-tice v tuple streamu jsou zpracovány postupně. Nejprve
jsou v kontextu přiřazeny hodnoty všem proměnným v n-tici včetně přı́padných pozičnı́ch
proměnných.
KAPITOLA 4. REALIZACE IMPLEMENTACE XQUERY
47
Pokud je součástı́ FLWOR výrazu klauzule where, je vyhodnocena přı́slušná instance uzlu
AST. Z kontextu je volánı́m metody effectiveBooleanValueOf zı́skána efektivnı́ booleovská
hodnota. V přı́padě hodnoty true je n-tice dále zpracovávána.
Pokud se ve výrazu nevyskytuje klauzule order by, je zpracován přı́mo výraz za klauzulı́
return a datový kontext po jeho vyhodnocenı́ je přidán k obsahu lokálnı́ proměnné, která
reprezentuje nově vznikajı́cı́ datový kontext, tj. resultDataContext.
Když výraz požadavek na specifické pořadı́ n-tic v tuple streamu obsahuje, provede se vyhodnocenı́ odpovı́dajı́cı́ instance třı́dy AST. Z volitelného kontextu je pod klı́čem orderSpecList
zı́skán seznam specifikacı́ řazenı́ v podobě instancı́ třı́dy XQueryOrderSpecItem. Vyhodnotı́ se výraz klauzule return a spolu se zı́skanými specifikacemi řazenı́ je uchován v objektu třı́dy XQueryOrderByItem. Po kompletnı́m vyhodnocenı́ všech n-tic je seznam instancı́
XQueryOrderByItem srovnán podle zadaných specifikacı́ řazenı́ a výsledné výrazy přeneseny do
lokálnı́ proměnné resultDataContext.
Na závěr vyhodnocenı́ se novým aktuálnı́m kontextem stává kopie původnı́ho kontextu. Ten
je dostupný v lokálnı́ proměnné givenContext. Jako datový kontext je přiřazen výsledek
shromažďovaný v lokálnı́ proměnné resultDataContext.
4.3
4.3.1
Vstupnı́ a výstupnı́ datový formát
Vstupnı́ datový formát
Vstupnı́m datovým formátem pro implementaci XQuery je dotaz v čistém textu. Nutná je
také spolupráce vyššı́ho programového celku, do kterého je implementace integrovaná, v otázce
poskytnutı́ třı́d document provideru a document adaptorů s odpovı́dajı́cı́mi protokoly.
4.3.2
Výstupnı́ datový formát
Výstupnı́m datovým formátem implementace XQuery je datový kontext, tj. jedna ze složek
aktuálnı́ho kontextu, po vyhodnocenı́ hierarchicky nejvyššı́ho výrazu v dotazu. Datový kontext
je OrderedCollection složená z instancı́ třı́dy XQueryDataContextItem. Po využitı́ informacı́
z výsledku má vyššı́ programový celek uloženo uvolnit datové zdroje, použité ke zpracovánı́
dotazu, volánı́m metody releaseDocumentAdaptors třı́dy XQueryExecutor.
48
KAPITOLA 4. REALIZACE IMPLEMENTACE XQUERY
KAPITOLA 5. TESTOVÁNÍ IMPLEMENTACE XQUERY
49
5 Testovánı́ implementace XQuery
Pro ověřenı́ funkčnosti a správnosti implementace je použı́vána metodika jednotkového testovánı́
(unit testing). Automatizovaně je tedy testováno chovánı́ jednotlivých funkčnı́ch třı́d, přı́padně
jednotlivých funkčnı́ch celků. Využita je podpora nástroje SUnit, který je dostupný v prostředı́
programovacı́ho jazyka Smalltalk.
Jednotlivé jednotkové testy jsou rozčleněny do třı́ třı́d v balı́čku XQuery-Tests. Všechny tyto
třı́dy jsou potomkem třı́dy TestCase. Jednotlivé testy jsou implementovány jako metody,
jejichž název začı́ná prefixem test.
Každá třı́da může kromě samotných testů implementovat také metody setUp pro přı́pravu
prostředı́ testu a tearDown pro uvedenı́ prostředı́ do původnı́ho stavu.
Zodpovědnost za správné pořadı́ volánı́ metod testu nese nástroj SUnit, který také nabı́zı́
grafické uživatelské rozhranı́ pro spouštěnı́ testů a přehlednou reprezentaci výsledků.
5.1
Jednotkové testy pro XQueryExecutor
Testovánı́m chovánı́ celé implementace se zabývá třı́da XQueryExecutorTests. Disponuje
řadou testů na jednotlivé jazykové konstrukce XQuery: FLWOR výrazy, výrazy s cestami
XPath, predikáty, podmı́něné výrazy, kvantifikované výrazy, konstruktory a řada dalšı́ch.
Tyto testy se chovajı́ k implementaci XQuery stejně jako uživatel. Položı́ XQueryExecutoru
dotaz v podobě čistého textu a převezmou výsledek v podobě datového kontextu, tedy sekvence
prvků představovaných instancemi třı́dy XQueryDataContextItem. Obdržený výsledek je
následně v rámci testu porovnán s předpokladem, jak má vypadat správný výsledek.
Metody setUp a tearDown se zabývajı́ vytvořenı́m a uvolněnı́m instance XQueryExecutoru. Pro
ověřenı́ správné funkčnosti některých výrazů je nutné pokládat dotazy nad XML dokumentem
z některého dostupného datového zdroje. URI dokumentu, který lze k těmto dotazům využı́t,
vracı́ metoda testedURI.
5.2
Jednotkové testy pro document providery
Vyššı́ programové celky, které integrujı́ implementaci XQuery, mohou prostřednictvı́m mechanismu document provideru a document adaptorů zpřı́stupňovat implementaci XQuery různé
druhy datových zdrojů podle vlastnı́ potřeby a volby.
Pro ověřenı́ správného chovánı́ dohodnutého protokolu sloužı́ testy, shromážděné ve třı́dě
XQueryDocumentAdaptorTests. Sada testů provádı́ nad zadaným dokumentem z testovaného
druhu datového zdroje množstvı́ dotazů, založených na osách XPath, a kontroluje správnost
a úplnost odpovědı́ document adaptoru.
URI testovaného dokumentu je opět přı́stupné prostřednictvı́m metody testedURI. Metody
setUp a tearDown se kromě vytvářenı́ a uvolňovánı́ instance XQueryExecutoru zabývajı́
zı́skánı́m instance přı́slušného document adaptoru.
50
5.3
KAPITOLA 5. TESTOVÁNÍ IMPLEMENTACE XQUERY
Jednotkové testy pro XQueryParser
Několik jednoduchých testů bylo vytvořeno i pro oblast parsovánı́ dotazu a vytvořenı́ stromu
abstraktnı́ syntaxe. Podstata jejich činnosti spočı́vá v předloženı́ dotazu v podobě čistého textu
třı́dě XQueryParser a kontrola struktury vzniklého AST proti předpokladu.
5.4
XML Query Test Suite
Kromě využitı́ testů, vytvořených specificky pro kontrolu implementace XQuery v rámci
databáze CellStore, existuje i možnost využı́t obecnou sadu testů pro implementace XQuery.
Tato sada testů je poskytována organizacı́ W3C pod názvem XML Query Test Suite [33].
Obsahuje vı́ce než 15 000 testů. Nabı́zı́ v samostatných souborech s definovaným formátem
jednotlivé dotazy, předpokládané výsledky a XML dokumenty, které jsou v rámci dotazů zpracovávány.
XML Query Test Suite také definuje formát, v němž může výsledek testovánı́ zaslán zpět
organizaci W3C. Kromě zveřejněnı́ výsledků na stránkách této organizace, což sloužı́ pro zı́skánı́
přehledu o mı́ře shodnosti implementacı́ s normou, může tato zpětná vazba ovlivňovat i dalšı́
vývoj normy.
Stávajı́cı́ implementace XQuery v rámci databáze CellStore využitı́ XML Query Test Suite
nepodporuje. Pro rozvoj oblasti jejı́ho testovánı́ však tato sada testů představuje zajı́mavou
výzvu, která by neměla zůstat nevyslyšena. Umožňuje otestovat implementaci v rozsahu, jehož
dosaženı́ vlastnı́mi silami vývojového týmu nenı́ vzhledem k dostupným prostředkům reálné.
Také je možné dı́ky jednotným testům srovnat kvalitu našı́ implementace s jinými implementacemi na světové úrovni.
KAPITOLA 6. ZÁVĚR
51
6 Závěr
V této práci jsme se pokusil shrnout úsilı́, které vedlo k vytvořenı́ pilotnı́ implementace dotazovacı́ho jazyka XQuery v rámci databáze CellStore. Seznámil jsem čtenáře s historiı́ formátu
XML, základnı́mi pojmy této oblasti a jazyky pro práci s XML dokumenty. Zmı́nil jsem některé
z praktických aplikacı́. Rozebral jsem otázku ukládánı́ XML dat a zejména nativnı́ch XML
databázı́. Přehledově jsem popsal architekturu nativnı́ XML databáze CellStore.
Přiblı́žil jsem čtenáři základnı́ koncepty dotazovacı́ho jazyka XQuery a důkladněji popsal jednotlivé konstrukce tohoto jazyka. Analyzoval jsem požadavky, které norma na implementaci
klade a navrhl rozdělenı́ implementace na funkčnı́ celky včetně jejich spolupráce mezi sebou
a s ostatnı́mi částmi databáze. Uvedl jsem výčet funkčnı́ch třı́d a datových struktur, které
implementace zahrnuje, a popsal jejich účel. Vysvětlil jsem postup, jakým jsou zpracovávány
vybrané jazykové konstrukce. Zmı́nil jsem, jakým způsobem byla implementace testována.
Přestože je tato implementace XQuery označována za pilotnı́, zpracovává většinu podstatných
konstrukcı́ jazyka včetně klı́čového FLWOR výrazu. Z gramatiky jazyka byla s ohledem na
omezenı́ nižšı́ch vrstev databáze vypuštěna pravidla pro práci s typy.
Důsledná implementace normou předepsaného datového modelu je logickým krokem v dalšı́m
rozvoji implementace. Stejné možnosti pro rozšı́řenı́ implementace se nabı́zı́ při ošetřovánı́
chybových stavů s důrazem na vyvolávánı́ výjimek s normou stanovenými chybovými kódy.
V koncepci návrhu je podchycen také prostor pro dalšı́ části jazyka, které zatı́m součástı́ implementace nejsou. Jedná se zejména o realizaci implementaci plné škály vestavěných funkcı́
nebo o partie prologu dotazu.
Během vývoje se ukázalo, že přes nesporné výhody nástroje SmaCC docházı́ při jeho použitı́
v oblasti XML k určitým omezenı́m, které si v budoucnosti mohou vyžádat ručnı́ vytvořenı́
lexikálnı́ho a syntaktického analyzátoru.
Pro experimentálnı́ a výukové využitı́ je však stávajı́cı́ stav implementace XQuery vyhovujı́cı́
a představuje dobrý základ pro budoucı́ vývoj. Soudı́m, že práce zcela splnila zadánı́. Doufám,
že jsem tı́m přispěl k dalšı́mu rozvoji projektu CellStore.
52
KAPITOLA 6. ZÁVĚR
KAPITOLA 7. SEZNAM LITERATURY
53
7 Seznam literatury
[1] Sherman R. Alpert, Kyle Brown, and Bobby Woolf. The Design Patterns Smalltalk
Companion. Addison Wesley, 1998.
[2] Murray Altheim and Shane McCarron. XHTML 1.1 - Module-based XHTML. W3C,
2001. http://www.w3.org/TR/xhtml11/.
[3] Sihem Amer-Yahia, Chavdar Botev, Stephen Buxton, Pat Case, Jochen Doerre,
Mary Holstege nad Darin McBeath, Michael Rys, and Jayavel Shanmugasundaram.
XQuery 1.0 and XPath 2.0 Full-Text. W3C, 2006.
http://www.w3.org/TR/xquery-full-text/.
[4] Dave Beckett and Brian McBride. RDF/XML Syntax Specification (Revised). W3C,
2004. http://www.w3.org/TR/rdf-syntax-grammar/.
[5] Anders Berglund, Scott Boag, Don Chamberlin, Mary Fernandez, Michael Kay, Jonathan
Robie, and Jerome Simeon. XML Path Language (XPath) 2.0. W3C, 2006.
http://www.w3.org/TR/xpath20/.
[6] Scott Boag, Don Chamberlin, Mary Fernandez, Daniela Florescu, Jonathan Robie, and
Jerome Simeon. XQuery 1.0: An XML Query Language. W3C, 2006.
http://www.w3.org/TR/xquery/.
[7] Michael Brauer, Patrick Durusau, Gary Edwards, David Faure, Tom Magliery, and
Daniel Vogelheim. Open Document Format for Office Aplications (OpenDocument) v1.0.
OASIS, 1st edition, 2005.
http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=office.
[8] Tim Bray, Dave Hollander, Andrew Layman, and Richard Tobin. Namespaces in XML
1.0. W3C, 2nd edition, 2006. http://www.w3.org/TR/REC-xml-names/.
[9] Tim Bray, Jean Paoli, C. M. Sperberg-McQueen, Eve Maler, and François Yergeau.
Extensible Markup Language (XML) 1.0. W3C, 4th edition, 2006.
http://www.w3.org/TR/REC-xml/.
[10] CampSmalltalk. SUnit. 2006. http://sunit.sourceforge.net/.
[11] Don Chamberlin, Daniela Florescu, and Jonathan Robie. XQuery Update Facility. W3C,
2006. http://www.w3.org/TR/xqupdate/.
[12] James Clark. XSL Transformations (XSLT) Version 1.0. W3C, 1999.
http://www.w3.org/TR/xslt.
[13] James Clark and Steve DeRose. XML Path Language (XPath) Version 1.0. W3C, 1999.
http://www.w3.org/TR/xpath.
[14] Steven DeRose, Ron Daniel Jr., Paul Grosso, Eve Maler, Jonathan Marsh, and Norman
Walsh. XML Pointer Language (XPointer). W3C, 2002. http://www.w3.org/TR/xptr/.
[15] Steven DeRose, Eve Maler, and David Orchard. XML Linking Language (XLink)
Version 1.0. W3C, 2001. http://www.w3.org/TR/xlink/.
[16] Mary Fernandez, Ashok Malhotra, Jonathan Marsh, Marton Nagy, and Norman Walsh.
XQuery 1.0 and XPath 2.0 Data Model (XDM). W3C, 2006.
http://www.w3.org/TR/xpath-datamodel/.
54
KAPITOLA 7. SEZNAM LITERATURY
[17] Jon Ferraiolo, Fujisawa Jun, and Dean Jackson. Scalable Vector Graphics (SVG) 1.1
Specification. W3C, 2003. http://www.w3.org/TR/SVG11/.
[18] Martin Gudgin, March Hadley, Noah Mendelsohn, Jean-Jacques Moreau, and
Henrik Frystyk Nielsen. SOAP Version 1.2 Part 1: Messaging Framework. W3C, 2003.
http://www.w3.org/TR/soap12-part1/.
[19] The Refactory Inc. SmaCC. 2006. http://www.refactory.com/Software/SmaCC/.
[20] Lehrgebiet Informationssysteme. XML Transaction Coordinator. 2006.
http://wwwdvs.informatik.uni-kl.de/xtc/.
[21] Patrick Ion and Robert Miner. Mathematical Markup Language (MathML) 1.01
Specification. W3C, 1999. http://www.w3.org/TR/REC-MathML/.
[22] Edward J. Klimas, Suzanne Skublics, and David A. Thomas. Smalltalk with Style.
Prentice Hall, 1996.
[23] Jiřı́ Kosek. XML pro každého. Grada Publishing, 1st edition, 2000.
[24] Andreas Laux and Lars Martin. XML:DB Initiative: XUpdate Working Draft. XML:DB,
2000. http://xmldb-org.sourceforge.net/xupdate/xupdate-wd.html.
[25] Hakon Wium Lie and Bert Bos. Cascading Style Sheets, level 1. W3C, 1999.
http://www.w3.org/TR/CSS1.
[26] Ashok Malhotra, Jim Melton, and Norman Walsh. XQuery 1.0 and XPath 2.0 Functions
and Operators. W3C, 2006. http://www.w3.org/TR/xquery-operators/.
[27] Jim Melton and Subramanian Muralidhar. XML Syntax for XQuery 1.0 (XQueryX).
W3C, 2006. http://www.w3.org/TR/xqueryx/.
[28] Irena Mlýnková, Jaroslav Pokorný, Karel Richta, Kamil Toman, and Vojtěch Toman.
Technologie XML. Karolinum, 1st edition, 2006.
[29] Denise Draper nad Peter Fankhauser nad Mary Fernandez, Ashok Malhotra, Kristoffer
Rose, Michael Rys, Jerome Simeon, and Philip Wadler. XQuery 1.0 and XPath 2.0
Formal Semantics. W3C, 2006. http://www.w3.org/TR/xquery-semantics/.
[30] Steven Pemberton. XHTML 1.0 The Extensible HyperText Markup Language. W3C, 2nd
edition, 2002. http://www.w3.org/TR/xhtml1/.
[31] Karel Přı́hoda. Cache manager a recovery modul nativnı́ XML databáze. Bakalářská
práce FEL ČVUT, 2006.
[32] Dave Raggett, Arnaud Le Hors, and Ian Jacobs. HTML 4.01 Specification. W3C, 1999.
http://www.w3.org/TR/html401/.
[33] Michael Rorke, Karuna Muthiah, and Joanne Tong. XML Query Test Suite. W3C, 2006.
http://www.w3.org/XML/Query/test-suite/.
[34] C. M. Sperberg-McQueen and Henry Thompson. XML Schema 1.1. W3C, 2006.
http://www.w3.org/XML/Schema.
[35] Pavel Strnad. Transakčnı́ manažer pro XML dokumenty. Bakalářská práce FEL ČVUT,
2005.
KAPITOLA 7. SEZNAM LITERATURY
55
[36] Kamil Toman and Irena Mlýnková. Xml data - the current state of affairs. In Processings
of XML Prague 2006, pages 87–100, 2006.
[37] Norman Walsh. The DocBook Document Type, Committee Draft 4.3. OASIS, 2004.
http://www.oasis-open.org/docbook/specs/cd-docbook-docbook-4.3.html.
56
KAPITOLA 7. SEZNAM LITERATURY
PŘÍLOHA A. GRAMATIKA XQUERY
57
A Gramatika XQuery
[1] Module ::= VersionDecl? (LibraryModule | MainModule)
[2] VersionDecl ::= "xquery" "version" StringLiteral
("encoding" StringLiteral)? Separator
[3] MainModule ::= Prolog QueryBody
[4] LibraryModule ::= ModuleDecl Prolog
[5] ModuleDecl ::= "module" "namespace" NCName "=" URILiteral Separator
[6] Prolog ::= ((DefaultNamespaceDecl | Setter | NamespaceDecl | Import)
Separator)* ((VarDecl | FunctionDecl | OptionDecl) Separator)*
[7] Setter ::= BoundarySpaceDecl | DefaultCollationDecl | BaseURIDecl
| ConstructionDecl | OrderingModeDecl | EmptyOrderDecl
| CopyNamespacesDecl
[8] Import ::= SchemaImport | ModuleImport
[9] Separator ::= ";"
[10] NamespaceDecl ::= "declare" "namespace" NCName "=" URILiteral
[11] BoundarySpaceDecl ::= "declare" "boundary-space" ("preserve" | "strip")
[12] DefaultNamespaceDecl ::= "declare" "default" ("element" | "function")
"namespace" URILiteral
[13] OptionDecl ::= "declare" "option" QName StringLiteral
[14] OrderingModeDecl ::= "declare" "ordering" ("ordered" | "unordered")
[15] EmptyOrderDecl ::= "declare" "default" "order" "empty"
("greatest" | "least")
[16] CopyNamespacesDecl ::= "declare" "copy-namespaces"
PreserveMode "," InheritMode
[17] PreserveMode ::= "preserve" | "no-preserve"
[18] InheritMode ::= "inherit" | "no-inherit"
[19] DefaultCollationDecl ::= "declare" "default" "collation" URILiteral
[20] BaseURIDecl ::= "declare" "base-uri" URILiteral
[21] SchemaImport ::= "import" "schema" SchemaPrefix? URILiteral
("at" URILiteral ("," URILiteral)*)?
[22] SchemaPrefix ::= ("namespace" NCName "=")
| ("default" "element" "namespace")
[23] ModuleImport ::= "import" "module" ("namespace" NCName "=")? URILiteral
("at" URILiteral ("," URILiteral)*)?
[24] VarDecl ::= "declare" "variable" "$" QName TypeDeclaration?
((":=" ExprSingle) | "external")
[25] ConstructionDecl ::= "declare" "construction" ("strip" | "preserve")
[26] FunctionDecl ::= "declare" "function" QName "(" ParamList? ")"
("as" SequenceType)? (EnclosedExpr | "external")
[27] ParamList ::= Param ("," Param)*
[28] Param ::= "$" QName TypeDeclaration?
[29] EnclosedExpr ::= "{" Expr "}"
[30] QueryBody ::= Expr
[31] Expr ::= ExprSingle ("," ExprSingle)*
[32] ExprSingle ::= FLWORExpr | QuantifiedExpr | TypeswitchExpr
| IfExpr | OrExpr
[33] FLWORExpr ::= (ForClause | LetClause)+ WhereClause? OrderByClause?
"return" ExprSingle
58
PŘÍLOHA A. GRAMATIKA XQUERY
[34] ForClause ::= "for" "$" VarName TypeDeclaration? PositionalVar?
"in" ExprSingle ("," "$" VarName TypeDeclaration?
PositionalVar? "in" ExprSingle)*
[35] PositionalVar ::= "at" "$" VarName
[36] LetClause ::= "let" "$" VarName TypeDeclaration? ":=" ExprSingle
("," "$" VarName TypeDeclaration? ":=" ExprSingle)*
[37] WhereClause ::= "where" ExprSingle
[38] OrderByClause ::= (("order" "by") | ("stable" "order" "by"))
OrderSpecList
[39] OrderSpecList ::= OrderSpec ("," OrderSpec)*
[40] OrderSpec ::= ExprSingle OrderModifier
[41] OrderModifier ::= ("ascending" | "descending")?
("empty" ("greatest" | "least"))?
("collation" URILiteral)?
[42] QuantifiedExpr ::= ("some" | "every") "$" VarName TypeDeclaration?
"in" ExprSingle ("," "$" VarName TypeDeclaration?
"in" ExprSingle)* "satisfies" ExprSingle
[43] TypeswitchExpr ::= "typeswitch" "(" Expr ")" CaseClause+
"default" ("$" VarName)? "return" ExprSingle
[44] CaseClause ::= "case" ("$" VarName "as")? SequenceType
"return" ExprSingle
[45] IfExpr ::= "if" "(" Expr ")" "then" ExprSingle "else" ExprSingle
[46] OrExpr ::= AndExpr ( "or" AndExpr )*
[47] AndExpr ::= ComparisonExpr ( "and" ComparisonExpr )*
[48] ComparisonExpr ::= RangeExpr ( (ValueComp | GeneralComp
| NodeComp) RangeExpr )?
[49] RangeExpr ::= AdditiveExpr ( "to" AdditiveExpr )?
[50] AdditiveExpr ::= MultiplicativeExpr ( ("+" | "-") MultiplicativeExpr )*
[51] MultiplicativeExpr ::= UnionExpr ( ("*" | "div" | "idiv"
| "mod") UnionExpr )*
[52] UnionExpr ::= IntersectExceptExpr ( ("union"
| "|") IntersectExceptExpr )*
[53] IntersectExceptExpr ::= InstanceofExpr ( ("intersect"
| "except") InstanceofExpr )*
[54] InstanceofExpr ::= TreatExpr ( "instance" "of" SequenceType )?
[55] TreatExpr ::= CastableExpr ( "treat" "as" SequenceType )?
[56] CastableExpr ::= CastExpr ( "castable" "as" SingleType )?
[57] CastExpr ::= UnaryExpr ( "cast" "as" SingleType )?
[58] UnaryExpr ::= ("-" | "+")* ValueExpr
[59] ValueExpr ::= ValidateExpr | PathExpr | ExtensionExpr
[60] GeneralComp ::= "=" | "!=" | "<" | "<=" | ">" | ">="
[61] ValueComp ::= "eq" | "ne" | "lt" | "le" | "gt" | "ge"
[62] NodeComp ::= "is" | "<<" | ">>"
[63] ValidateExpr ::= "validate" ValidationMode? "{" Expr "}"
[64] ValidationMode ::= "lax" | "strict"
[65] ExtensionExpr ::= Pragma+ "{" Expr? "}"
[66] Pragma ::= "(#" S? QName (S PragmaContents)? "#)"
[67] PragmaContents ::= (Char* - (Char* ’#)’ Char*))
[68] PathExpr ::= ("/" RelativePathExpr?) | ("//" RelativePathExpr)
| RelativePathExpr
PŘÍLOHA A. GRAMATIKA XQUERY
[69]
[70]
[71]
[72]
[73]
59
RelativePathExpr ::= StepExpr (("/" | "//") StepExpr)*
StepExpr ::= FilterExpr | AxisStep
AxisStep ::= (ReverseStep | ForwardStep) PredicateList
ForwardStep ::= (ForwardAxis NodeTest) | AbbrevForwardStep
ForwardAxis ::= ("child" "::") | ("descendant" "::") | ("attribute" "::")
| ("self" "::") | ("descendant-or-self" "::")
| ("following-sibling" "::") | ("following" "::")
[74] AbbrevForwardStep ::= "@"? NodeTest
[75] ReverseStep ::= (ReverseAxis NodeTest) | AbbrevReverseStep
[76] ReverseAxis ::= ("parent" "::") | ("ancestor" "::")
| ("preceding-sibling" "::") | ("preceding" "::")
| ("ancestor-or-self" "::")
[77] AbbrevReverseStep ::= ".."
[78] NodeTest ::= KindTest | NameTest
[79] NameTest ::= QName | Wildcard
[80] Wildcard ::= "*" | (NCName ":" "*") | ("*" ":" NCName)
[81] FilterExpr ::= PrimaryExpr PredicateList
[82] PredicateList ::= Predicate*
[83] Predicate ::= "[" Expr "]"
[84] PrimaryExpr ::= Literal | VarRef | ParenthesizedExpr | ContextItemExpr
| FunctionCall | OrderedExpr | UnorderedExpr
| Constructor
[85] Literal ::= NumericLiteral | StringLiteral
[86] NumericLiteral ::= IntegerLiteral | DecimalLiteral | DoubleLiteral
[87] VarRef ::= "$" VarName
[88] VarName ::= QName
[89] ParenthesizedExpr ::= "(" Expr? ")"
[90] ContextItemExpr ::= "."
[91] OrderedExpr ::= "ordered" "{" Expr "}"
[92] UnorderedExpr ::= "unordered" "{" Expr "}"
[93] FunctionCall ::= QName "(" (ExprSingle ("," ExprSingle)*)? ")"
[94] Constructor ::= DirectConstructor | ComputedConstructor
[95] DirectConstructor ::= DirElemConstructor | DirCommentConstructor
| DirPIConstructor
[96] DirElemConstructor ::= "<" QName DirAttributeList ("/>" | (">"
DirElemContent* "</" QName S? ">"))
[97] DirAttributeList ::= (S (QName S? "=" S? DirAttributeValue)?)*
[98] DirAttributeValue ::= (’"’ (EscapeQuot | QuotAttrValueContent)* ’"’)
| ("’" (EscapeApos | AposAttrValueContent)* "’")
[99] QuotAttrValueContent ::= QuotAttrContentChar | CommonContent
[100] AposAttrValueContent ::= AposAttrContentChar | CommonContent
[101] DirElemContent ::= DirectConstructor | CDataSection | CommonContent
| ElementContentChar
[102] CommonContent ::= PredefinedEntityRef | CharRef | "{{" | "}}"
| EnclosedExpr
[103] DirCommentConstructor ::= "<!--" DirCommentContents "-->"
[104] DirCommentContents ::= ((Char - ’-’) | (’-’ (Char - ’-’)))*
[105] DirPIConstructor ::= "<?" PITarget (S DirPIContents)? "?>"
[106] DirPIContents ::= (Char* - (Char* ’?>’ Char*))
[107] CDataSection ::= "<![CDATA[" CDataSectionContents "]]>"
60
PŘÍLOHA A. GRAMATIKA XQUERY
[108] CDataSectionContents ::= (Char* - (Char* ’]]>’ Char*))
[109] ComputedConstructor ::= CompDocConstructor | CompElemConstructor
| CompAttrConstructor | CompTextConstructor
| CompCommentConstructor | CompPIConstructor
[110] CompDocConstructor ::= "document" "{" Expr "}"
[111] CompElemConstructor ::= "element" (QName | ("{" Expr "}"))
"{" ContentExpr? "}"
[112] ContentExpr ::= Expr
[113] CompAttrConstructor ::= "attribute" (QName | ("{" Expr "}"))
"{" Expr? "}"
[114] CompTextConstructor ::= "text" "{" Expr "}"
[115] CompCommentConstructor ::= "comment" "{" Expr "}"
[116] CompPIConstructor ::= "processing-instruction" (NCName | ("{" Expr "}"))
"{" Expr? "}"
[117] SingleType ::= AtomicType "?"?
[118] TypeDeclaration ::= "as" SequenceType
[119] SequenceType ::= ("empty-sequence" "(" ")")
| (ItemType OccurrenceIndicator?)
[120] OccurrenceIndicator ::= "?" | "*" | "+"
[121] ItemType ::= KindTest | ("item" "(" ")") | AtomicType
[122] AtomicType ::= QName
[123] KindTest ::= DocumentTest | ElementTest | AttributeTest
| SchemaElementTest | SchemaAttributeTest | PITest
| CommentTest | TextTest | AnyKindTest
[124] AnyKindTest ::= "node" "(" ")"
[125] DocumentTest ::= "document-node" "(" (ElementTest
| SchemaElementTest)? ")"
[126] TextTest ::= "text" "(" ")"
[127] CommentTest ::= "comment" "(" ")"
[128] PITest ::= "processing-instruction" "(" (NCName | StringLiteral)? ")"
[129] AttributeTest ::= "attribute" "(" (AttribNameOrWildcard
("," TypeName)?)? ")"
[130] AttribNameOrWildcard ::= AttributeName | "*"
[131] SchemaAttributeTest ::= "schema-attribute" "(" AttributeDeclaration ")"
[132] AttributeDeclaration ::= AttributeName
[133] ElementTest ::= "element" "(" (ElementNameOrWildcard
("," TypeName "?"?)?)? ")"
[134] ElementNameOrWildcard ::= ElementName | "*"
[135] SchemaElementTest ::= "schema-element" "(" ElementDeclaration ")"
[136] ElementDeclaration ::= ElementName
[137] AttributeName ::= QName
[138] ElementName ::= QName
[139] TypeName ::= QName
[140] URILiteral ::= StringLiteral
[141] IntegerLiteral ::= Digits
[142] DecimalLiteral ::= ("." Digits) | (Digits "." [0-9]*)
[143] DoubleLiteral ::= (("." Digits) | (Digits ("." [0-9]*)?))
[eE] [+-]? Digits
PŘÍLOHA A. GRAMATIKA XQUERY
61
[144] StringLiteral ::= (’"’ (PredefinedEntityRef | CharRef
| EscapeQuot | [^"&])* ’"’)
| ("’" (PredefinedEntityRef | CharRef
| EscapeApos | [^’&])* "’")
[145] PredefinedEntityRef ::= "&" ("lt" | "gt" | "amp" | "quot" | "apos") ";"
[146] EscapeQuot ::= ’""’
[147] EscapeApos ::= "’’"
[148] ElementContentChar ::= Char - [{}<&]
[149] QuotAttrContentChar ::= Char - ["{}<&]
[150] AposAttrContentChar ::= Char - [’{}<&]
[151] Comment ::= "(:" (CommentContents | Comment)* ":)"
[152] PITarget ::= [http://www.w3.org/TR/REC-xml#NT-PITarget]XML
[153] CharRef ::= [http://www.w3.org/TR/REC-xml#NT-CharRef]XML
[154] QName ::= [http://www.w3.org/TR/REC-xml-names/#NT-QName]Names
[155] NCName ::= [http://www.w3.org/TR/REC-xml-names/#NT-NCName]Names
[156] S ::= [http://www.w3.org/TR/REC-xml#NT-S]XML
[157] Char ::= [http://www.w3.org/TR/REC-xml#NT-Char]XML
[158] Digits ::= [0-9]+
[159] CommentContents ::= (Char+ - (Char* (’(:’ | ’:)’) Char*))
62
PŘÍLOHA A. GRAMATIKA XQUERY
PŘÍLOHA B. IMPLEMENTOVANÁ ČÁST GRAMATIKY XQUERY
63
B Implementovaná část gramatiky XQuery
Sloupec # odkazuje na čı́slo pravidla gramatiky XQuery podle normy W3C, W3C rule name
pak uvádı́ název tohoto pravidla podle stejné normy. Sloupec SmaCC rule name obsahuje
název pravidla podle implementace a sloupec AST class name určuje název třı́dy SmaCC,
kterou pravidlo produkuje do stromu abstraktnı́ syntaxe.
#
29
30
31
32
33
34
35
36
37
38
39
40
41
42
45
46
47
48
49
50
51
52
53
58
59
60
61
62
W3C rule name
EnclosedExpr
QueryBody
Expr
ExprSingle
FLWORExpr
ForClause
PositionalVar
LetClause
WhereClause
OrderByClause
OrderSpecList
OrderSpecList
OrderModifier
QuantifiedExpr
IfExpr
OrExpr
AndExpr
ComparisonExpr
RangeExpr
AdditiveExpr
MultiplicativeExpr
UnionExpr
IntersectExceptExpr
UnaryExpr
ValueExpr
GeneralComp
ValueComp
NodeComp
SmaCC rule name
EnclosedExpr
QueryBody
Expr
ExprSingle
FLWORExpr
FLWORExpr ForLet
ForClause
ForClause Impl
PositionalVar
LetClause
LetClause Impl
WhereClause
OrderByClause
OrderSpecList
OrderSpec
OrderModifier
OrderModifierAscDesc
OrderModifierGreatestLeast
QuantifiedExpr
QuantifiedExpr Impl
IfExpr
OrExpr
AndExpr
ComparisonExpr
RangeExpr
AdditiveExpr
MultiplicativeExpr
UnionExpr
IntersectExceptExpr
UnaryExpr
ValueExpr
GeneralComp
ValueComp
NodeComp
AST class name
AstEnclosedExpr
AstExpr
AstFLWORExpr
AstFLWORExpr ForLet
AstForClause
AstLetClause
AstWhereClause
AstOrderByClause
AstOrderSpecList
AstOrderSpec
AstOrderModifier
konstanty
konstanty
AstQuantifiedExpr
AstQuantifiedExpr Impl
AstIfExpr
AstOrExpr
AstAndExpr
AstComparisonExpr
AstRangeExpr
AstAdditiveExpr
AstMultiplicativeExpr
AstUnionExpr
AstIntersectExceptExpr
AstUnaryExpr
konstanty
konstanty
konstanty
Tabulka B.1: Přehled implementovaných pravidel gramatiky XQuery - 1. část
64
PŘÍLOHA B. IMPLEMENTOVANÁ ČÁST GRAMATIKY XQUERY
#
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
101
102
109
110
111
112
113
114
123
124
125
126
W3C rule name
PathExpr
RelativePathExpr
StepExpr
AxisStep
ForwardStep
ForwardAxis
AbbrevForwardStep
ReverseStep
ReverseAxis
AbbrevReverseStep
NodeTest
NameTest
Wildcard
FilterExpr
PredicateList
Predicate
PrimaryExpr
Literal
NumericLiteral
VarRef
VarName
ParenthesizedExpr
ContextItemExpr
OrderedExpr
UnorderedExpr
FunctionCall
Constructor
DirectConstructor
DirElemConstructor
DirAttributeList
DirAttributeValue
DirElemContent
CommonContent
ComputedConstructor
CompDocConstructor
CompElemConstructor
ContentExpr
CompAttrConstructor
CompTextConstructor
KindTest
AnyKindTest
DocumentTest
TextTest
SmaCC rule name
PathExpr
RelativePathExpr
StepExpr
AxisStep
ForwardStep
ForwardAxis
AbbrevForwardStep
ReverseStep
ReverseAxis
AbbrevReverseStep
NodeTest
NameTest
Wildcard
FilterExpr
PredicateList
Predicate
PrimaryExpr
Literal
NumericLiteral
VarRef
VarName
ParenthesizedExpr
ContextItemExpr
OrderedExpr
UnorderedExpr
FunctionCall
FunctionParametersList
Constructor
DirectConstructor
DirElemConstructor
DirAttributeList
DirAttributeValue
DirElemContent
CommonContent
ComputedConstructor
CompDocConstructor
CompElemConstructor
ContentExpr
CompAttrConstructor
CompTextConstructor
KindTest
AnyKindTest
DocumentTest
TextTest
AST class name
AstPathExpr
AstRelativePathExpr
AstAxisStep
AstForwardStep
konstanty
AstAbbrevForwardStep
AstReverseStep
konstanty
konstanty
AstNameTest
AstWildcard
AstFilterExpr
AstPredicateList
AstPredicate
AstVarRef
AstParenthesizedExpr
AstContextItemExpr
AstOrderedUnorderedExpr
AstOrderedUnorderedExpr
AstFunctionCall
AstFunctionParametersList
AstDirElemConstructor
AstDirAttributeList
AstDirElemContent
AstCompDocConstructor
AstCompElemConstructor
AstCompAttrConstructor
AstCompTextConstructor
AstAnyKindTest
AstDocumentTest
AstTextTest
Tabulka B.2: Přehled implementovaných pravidel gramatiky XQuery - 2. část
PŘÍLOHA B. IMPLEMENTOVANÁ ČÁST GRAMATIKY XQUERY
#
129
130
133
134
137
138
145
154
155
144
141
142
143
W3C rule name
AttributeTest
AttribNameOrWildcard
ElementTest
ElementNameOrWildcard
AttributeName
ElementName
PredefinedEntityRef
QName
NCName
StringLiteral
IntegerLiteral
DecimalLiteral
DoubleLiteral
SmaCC rule name
AttributeTest
AttribNameOrWildcard
ElementTest
ElementNameOrWildcard
AttributeName
ElementName
PredefinedEntityRef
QName
NCName
StringLiteral
IntegerLiteral
DecimalLiteral
DoubleLiteral
AST class name
AstAttributeTest
AstAttribNameOrWildcard
AstElementTest
AstElementNameOrWildcard
AstPredefinedEntityRef
AstQName
AstNCName
AstStringLiteral
AstIntegerLiteral
AstDecimalLiteral
AstDoubleLiteral
Tabulka B.3: Přehled implementovaných pravidel gramatiky XQuery - 3. část
-
65
66
PŘÍLOHA B. IMPLEMENTOVANÁ ČÁST GRAMATIKY XQUERY
PŘÍLOHA C. PŘEHLED IMPLEMENTOVANÝCH FUNKCÍ
C Přehled implementovaných funkcı́
Jméno funkce
fn:count
fn:avg
fn:max
fn:min
fn:sum
fn:zero-or-one
fn:one-or-more
fn:exactly-one
fn:boolean
fn:empty
fn:exists
fn:insert-before
fn:remove
fn:reverse
fn:subsequence
fn:abs
fn:ceiling
fn:floor
fn:round
fn:position
fn:last
fn:not
fn:true
fn:false
fn:doc
fn:distinct-values
Deklarace funkce podle normy XQuery
fn:count($arg as item()*) as xs:integer
fn:avg($arg as xs:anyAtomicType*) as xs:anyAtomicType?
fn:max($arg as xs:anyAtomicType*) as xs:anyAtomicType?
fn:min($arg as xs:anyAtomicType*) as xs:anyAtomicType?
fn:sum($arg as xs:anyAtomicType*,
$zero as xs:anyAtomicType?) as xs:anyAtomicType?
fn:zero-or-one($arg as item()*) as item()?
fn:one-or-more($arg as item()*) as item()+
fn:exactly-one($arg as item()*) as item()
fn:boolean($arg as item()*) as xs:boolean
fn:empty($arg as item()*) as xs:boolean
fn:exists($arg as item()*) as xs:boolean
fn:insert-before($target as item()*, $position as xs:integer,
$inserts as item()*) as item()*
fn:remove($target as item()*, $position as xs:integer) as item()*
fn:reverse($arg as item()*) as item()*
fn:subsequence($sourceSeq as item()*,
$startingLoc as xs:double) as item()*
fn:subsequence($sourceSeq as item()*,
$startingLoc as xs:double, $length as xs:double) as item()*
fn:abs($arg as numeric?) as numeric?
fn:ceiling($arg as numeric?) as numeric?
fn:floor($arg as numeric?) as numeric?
fn:round($arg as numeric?) as numeric?
fn:position() as xs:integer
fn:last() as xs:integer
fn:not($arg as item()*) as xs:boolean
fn:true() as xs:boolean
fn:false() as xs:boolean
fn:doc($uri as xs:string?) as document-node()?
fn:distinct-values($arg as xs:anyAtomicType*)
as xs:anyAtomicType*
Tabulka C.1: Přehled implementovaných funkcı́ XQuery
67
68
PŘÍLOHA C. PŘEHLED IMPLEMENTOVANÝCH FUNKCÍ
PŘÍLOHA D. UML DIAGRAMY
D UML diagramy
Obrázek D.1: UML - XQuery executor
69
70
PŘÍLOHA D. UML DIAGRAMY
Obrázek D.2: UML - Databáze CellStore
PŘÍLOHA D. UML DIAGRAMY
Obrázek D.3: UML - Repository
71
72
PŘÍLOHA D. UML DIAGRAMY
Obrázek D.4: UML - Transaction manager
Obrázek D.5: UML - Cache manager
PŘÍLOHA E. UŽIVATELSKÁ / INSTALAČNÍ PŘÍRUČKA
73
E Uživatelská / instalačnı́ přı́ručka
Pro použı́vánı́ implementace XQuery v rámci databáze CellStore je třeba zprovoznit vývojové
a běhové prostředı́ Smalltalk/X a natáhnout do smalltalkovské image (obraz objektové paměti)
potřebné třı́dy. Mezi potřebné třı́dy je kromě třı́d samotné implementace XQuery třeba
započı́tat samozřejmě i třı́dy databáze CellStore, podpůrných nástrojů SmaCC a SUnit a dalšı́ch
potřebných knihoven (např. projekt XML Suite).
Dobrým výchozı́m bodem pro jejich zı́skánı́ je adresa http://cellstore.felk.cvut.cz, tedy
WWW stránka projektu CellStore. Na nı́ jsou dostupné bližšı́ informace, vztahujı́cı́ se k projektu a jeho aktuálnı́mu stavu. Také jsou na nı́ ke staženı́ připraveny jak přizpůsobená verze
prostředı́ Smalltalk/X, tak aktuálnı́ stav zdrojových souborů projektu CellStore jako tarball.
K dispozici je také přı́stup k aktuálnı́mu stavu CVS přes webové rozhranı́.
Na CD, přiloženém k textu diplomové práce, je kromě fileoutu (exportu třı́d v podobě textového souboru) třı́d implementace XQuery k dispozici i soubor smalltalkovské image. Ten je
nejjednoduššı́m způsobem, jak spustit funkčnı́ stav implementace XQuery v rámci databáze
CellStore v takové podobě, v jaké byl v době odevzdánı́ tohoto textu. Spuštěnı́ Smalltalk/X
s určenı́m konkrétnı́ image je možné zadánı́m přı́kazu stx -i <soubor> na přı́kazové řádce
operačnı́ho systému. Parametr <soubor> určuje jméno souboru s image včetně cesty.
Po spuštěnı́ image je možné zobrazit předváděcı́ grafického uživatelského rozhranı́ XQuery.
Jednou z cest je otevřenı́ okna SystemBrowser, které zobrazuje přehled třı́d v rámci image.
Po nalezenı́ třı́dy XQueryExecutorUI je předváděcı́ GUI implementace možné spustit dvojitým poklepánı́m na název třı́dy. Druhou cestou je otevřenı́ okna Workspace, zadánı́ výrazu
XQuery::XQueryExecutorUI open a jeho provedenı́.
Ukázkové GUI se skládá z jediného okna s dvěma plochami a tlačı́tkem Execute. V hornı́
části okna uživatel zadává dotaz a tlačı́tkem Execute spouštı́ jeho vyhodnocenı́. Výsledek
vyhodnocenı́ dotazu se objevı́ v dolnı́ části okna.
V přı́padě zájmu o spuštěnı́ testů je vhodné v třı́dách jednotkových testů upravit cestu k testovacı́m XML dokumentům.
74
PŘÍLOHA E. UŽIVATELSKÁ / INSTALAČNÍ PŘÍRUČKA
PŘÍLOHA F. OBSAH PŘILOŽENÉHO CD
75
F Obsah přiloženého CD
V této přı́loze je uveden obsah elektronické přı́lohy diplomové práce - CD. Jedná se jednak
o samotný text diplomové práce, jednak vlastnı́ vypracovánı́ této práce v prostředı́ Smalltalk/X.
image
- adresář obsahuje image jazyka Smalltalk/X, která zahrnuje implementaci XQuery, databázi
CellStore a nástroje SmaCC a SUnit
source/classes
- adresář obsahuje třı́dy implementace XQuery, exportované do samostatných souborů v textovém formátu
source/fileout
- adresář obsahuje třı́dy implementace XQuery, exportované do jediného souboru v textovém
formátu
test
- adresář obsahuje soubory, použitelné při testovánı́ implementace XQuery
text/pdf
- adresář obsahuje text diplomové práce ve formátu PDF
text/tex
- adresář obsahuje text diplomové práce ve formě zdrojových souborů TEXu a dalšı́ch souborů,
potřebných pro sazbu

Podobné dokumenty

Implementace jazyka Ruby pro virtuální stroj Smalltalk/X

Implementace jazyka Ruby pro virtuální stroj Smalltalk/X Cílem této diplomové práce je implementovat jazyk Ruby pro virtuální stroj Smalltalk/X. Implementace bude umoº¬ovat na£íst a zkompilovat zdrojové kódy jazyku Ruby a takto p°eloºený kód vykovat. For...

Více

Diplomová práce Ukládání geodat do XML nativních databází

Diplomová práce Ukládání geodat do XML nativních databází geographical data. After the brief acquaintance with the basics of XML (XML, Xpath, Xquery, XSLT, ...), native XML databases (kinds, basic charackteristics, ...) and XML formats (GML, cGML, ...) of...

Více

Prezentace aplikace PowerPoint

Prezentace aplikace PowerPoint computer scientist mathematician cryptographer

Více

STRUKTUROVA Ý ŽIVOTOPIS OSOB Í ÚDAJE Jméno a příjmení Bc

STRUKTUROVA Ý ŽIVOTOPIS OSOB Í ÚDAJE Jméno a příjmení Bc C, C++, C++/CLI, C# (.NET), VB .NET, Pascal, PHP, Bash, JavaScript Funkcionálních jazyků Haskell, F#, Lisp / Scheme, Ocaml, XQuery Neprocedurálních jazyků Prolog Prostředí Visual Studio, Delphi, C+...

Více

MicroStrategy Mobile

MicroStrategy Mobile MicroStrategy mobile Suite 25 uživatelských licencí s mobilním přístupem MicroStrategy Intelligence Server, MicroStrategy Mobile, MicroStrategy Report Services, MicroStrategy Transaction Services ...

Více

XXIVth conference Hotel Sněžník Dolní Morava 16. 5

XXIVth conference Hotel Sněžník Dolní Morava 16. 5 V říjnu 2003 bylo definitivně schváleno Java Portlet API ve verzi 1.0 jako standard. To umožňuje vývojářům jednou napsat portlet a provozovat jej v různých portálech podoporujících toto API. Měsíc ...

Více