Základy XQuery a věci z toho pro nás plynoucí
Základním stavebním kamenem XQuery je Expression, které mohou být konstruovány z klíčových slov, symbolů a operandů. Každý operand je opět Expression. XQuery je funkcionální jazyk se silnou typovou kontrolou.
Hodnota Expression v XQuery je vždy Sequence což je setříděná kolekce 0 nebo více Items. Každá Item je buď Atomic value nebo Node. Každý Node má jednoznačnou identitu ( z toho pro nás plyne to, že každému uzlu XML databáze musíme přiřadit nějakým způsobem id, přičemž uzlem může být element, atribut, poznámka nebo text ).
XQuery procesor (XQP)
XQuery procesor vyhodnocuje jednotlivé Expressions v dotazu. Tím dostává Sequences Itemů. Nechť E je nějaký Expression, který vyhodnocuje v rámci daného dotazu. Potřebuje vyhodnotit všechny Expessiony, které se vyskytují v E jako operandy. Tím dostává Sequences Itemů jako podvýsledky. Tyto Sequences poté zpracuje podle daných klíčových slov a symbolů v E a vytvoří nový Sequence S jako výsledek. Při tomto zpracování potřebuje přistupovat k obsahu Itemů ze Sequences z podvýsledků. Jediné co má jsou id těchto Itemů. Potřebuje-li tedy procesor získat nějakou Item J z Itemu I, musí mít možnost získat I z dokumentu, nad kterým je dotaz prováděn.
Pro vyhodnocení Experession musí mít vrstvu XML Document Index Structures (XDIS Layer). Pomocí indexů v XDIS získá Sequence id Itemů ležících na dané cestě. Pokud potřebuje přistoupit k nějakým datům Itemu I, potřebuje k tomu vrstvu XML Document Data Model (XDDM Layer). Zavolá metodu Item getItem(id_t id), která vrací Item identifikované id z argumentu metody. Nechť I je výsledek tohoto volání. I je možné přetypovat na nějaký konkrétní subtyp typu Node, buď ho explicitně známe, nebo můžeme jeho typ zjistit z runtime vlastností. Objekt I daného typu potom poskytuje metody pro přístup k potomkům, atributům, jménu, ... .
Příklad vyhodnocení dotazu
<bib>
{
for $b in document("http://www.bn.com/bib.xml")/bib/book
where $b/publisher = "Addison-Wesley" and $b/@year > 1991
return
<book year="{ $b/@year }">
{ $b/title }
</book>
}
</bib>
- Do XDIS vyšle požadavek na všechna id Itemů odpovídající cestě document("http://www.bn.com/bib.xml")/bib/book
- Iteruje přes výslednou Sequence S, pro každé id Itemu I ze Sequence S:
- Sváže Item I s proměnnou $b tím, že proměnné $b přiřadí (Element)XDDM.getItem(id)
- Vyhodnotí predikát $b/publisher = "Addison-Wesley" and $b/@year > 1991 pro hodnotu $b. Příslušné hodnoty získává metodami objektu $b
- Pokud podmínka není splněna, pokračuje dalším krokem iterace
- Podmínka je splněna, zkonstruuje výsledný element specifikovaný ve složce return
Příklad vyhodnocení dotazu
<results>
{
for $a in distinct-values(document("http://www.bn.com/bib.xml")//author)
return
<result>
{ $a }
{
for $b in document("http://www.bn.com/bib.xml")/bib/book
where some $ba in $b/author satisfies deep-equal($ba,$a)
return $b/title
}
</result>
}
</results>
- Do XDIS vyšle požadavek na všechna id Itemů odpovídající cestě document("http://www.bn.com/bib.xml")//author
- Pro výslednou Sequence S volá metodu XQP.distinct-values(S), výsledkem je Sequence SS
- Iteruje přes SS, pro každé id Itemu I z SS:
- Sváže Item I s proměnnou $a tím, že jí přiřadí (Element)XDDM.getItem(id)
- Konstruuje výsledný element specifikovaný ve složce return. K tomu potřebuje vyhodnotit poddotaz:
- Do XDIS vyšle požadavek na všechna id Itemů odpovídající cestě document("http://www.bn.com/bib.xml")/bib/book.
- Iteruje přes výslednou Sequence S, pro každé id Itemu I ze Sequence S:
- Sváže Item I s proměnnou $b tím, že proměnné $b přiřadí (Element)XDDM.getItem(id)
- Vyhodnotí predikát some $ba in $b/author satisfies deep-equal($ba,$a) pro hodnotu $b.
Příslušné hodnoty získává metodami objektu $b či $a
- Pokud podmínka není splněna, pokračuje dalším krokem iterace
- Podmínka je splněna, zkonstruuje výsledný element specifikovaný ve složce return
XML Document Data Model (XDDM Layer)
Jde o indexy, které mapují čísla id do jejich Nodes. Metoda XDDM.getItem(id) toto umožňuje a vrací objekt N(instanci třídy Node), který je možno přetypovat podle skutečného typu uzlu příslušejícího tomuto id. Objekt N nabízí metody pro přístup různým vlastnostem příslušného Node z XML dokumentu. Je třeba řešit, jak bude skutečně ten Node uložený. Vrstvám komunikujícím s touto vrstvou ze zhora (XQP) je to jedno, těm je nabízeno interface reprezentované objektem vráceným metodou XDDM.getItem(id). Možná by to šlo takhle:
-
Atomická hodnota - nemá svoje id.
Pak je uložen přímo v paměti u objektu, který tuto atomickou hodnotu obsahuje nebo (pokud je to moc dlouhej string např.) je na tu hodnotu nějak vhodně ukázáno a I/O vrstva pro práci s diskem umožní přístup k téhle hodnotě podle toho zadaného ukazatele (měli bychom asi nějak rozumně omezit s jak velkými stringy se může v paměti pracovat (je to podporováno i DOMem, pokud chceme získat třeba hodnotu textovýho uzlu, tak pokud je ta hodnota moc dlouhá, je vyhozena vyjímka a je potřeba k této hodnotě přistupovat pomocí metody subString)).
-
Node - má své id, obsahuje další Nodes.
Může být namapován do paměti nebo uložen na disku (je třeba navrhnout logiku toho, jaké Nodes budou namapovány a jaké uloženy na disku a jak bude docházet k jejich výměně, LRU, NRU, ... ). V případě, že je namapován v paměti, má namapovány i své atomické hodnoty či odkazy na ně tak, aby mu je I/O layer mohla poskytnout. Pokud obsahuje nějaký Node, má uložen v paměti buď ukazatel na objekt tohoto Node, pokud je tento Node také namapován v pamětia náš Node o tom ví. Pokud o tom neví, nebo Node není namapován, je uloženo jeho id. Pokud chceme přistoupit přes náš uzel k tomuto uzlu, jdeme buď přímo přes ukazatel nebo se podíváme do tabulky, kde jsou dvojice id-ukazatel pro všechny namapované Nody. Pokud tu je hledaný, máme ukazatel. Pokud tu není, musíme ho namapovat a přidat záznam do paměti. Pokud není místo na namapování musíme někoho odmapovat, ale ne ty které zrovna používáme :-).
Vyřešit: Jak budeme namapovávat Nody, které nejsou v paměti a jak budou uložený. Pro každý Node potřebuju uložit idčka všech Nodů, které jsou obsažený v tomto Nodu (pro element např. idčka atributů, elementů, commentů, textnodů, ...) a jeho atomické hodnoty (pro textnode např. jeho obsah, pro element např jeho jméno, pro atribut jeho jméno a hodnotu, ...). Jak budu žádat o namapování nějakýho Nodu? (přes jeho id, nějaká index struktura, která mi řekne, kde se Node fyzicky nachází podle jeho id?).