Implementace cásti jazyka XQuery v rámci projektu CellStore JanˇZák
Transkript
Č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ř. <). 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
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...
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...
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+...
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 ...
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 ...