XML a databáze – základy XML-QL

20. července 2001

V předchozím článku jsem vás seznamil s jednoduchým XML dokumentem popisující klienty cestovní kanceláře a s nejjednoduším použitím dotazovacího jazyka XML-QL. Dnes vám možnosti použití jazyka rozšířím o další zajímavé příklady použití.

Konvence

V následujícím textu budu vycházet z konvence, že ukončovací tagy lze zapisovat ve zkrácené podobě, např. místo </ZAJEZD> jednoduše zapíši </>. Příklad seznamu jmen a příjmení všech brněnských klientů by vypadal takto:

where
        <KLIENT>
        <JMENO>$j</>
        <PRIJMENI>$p</>
        <ADRESA><MESTO>Brno</></>
        </> in „cestovka.xml“
construct <BRNO_KLIENT>
        <JMENO>$j</>
        <PRIJMENI>$p</>
        </>

Dokonce, je-li dvakrát za sebou </></>, lze psát zkráceně </>>.

Příklad

Pro potřebu tohoto článku vytvořím XML dokument pro popis knih v knihovně. Odpovídající DTD bude vypadat takto:

<!ELEMENT KNIHOVNA (KNIHA*)>
<!ELEMENT KNIHA (AUTOR+, TITUL, VYDAVATEL)>
<!ELEMENT AUTOR (JMENO?, PRIJMENI)>
<!ELEMENT VYDAVATEL (NAZEV, ADRESA)>
<!ELEMENT ADRESA (ULICE, CISLO, MESTO, PSC)>
<!ELEMENT TITUL (#PCDATA)>
<!ELEMENT JMENO (#PCDATA)>
<!ELEMENT PRIJMENI (#PCDATA)>
<!ELEMENT ULICE (#PCDATA)>
<!ELEMENT CISLO (#PCDATA)>
<!ELEMENT MESTO (#PCDATA)>
<!ELEMENT PSC (#PCDATA)>

Popis knihy obsahuje jednoho nebo více autorů, název a vydavatele. Autor je zapsán jako jméno a příjmení, přičemž křestní jméno nemusí být uvedeno. Vydavatel je pak evidován pod svým názvem a adresou, která se dále dělí na ulici, číslo, město a psč.

Shlukování pomocí vnořených dotazů

Přestavte si situaci, že v XML dokumentu máme následující obsah:

<KNIHOVNA>
<KNIHA>
<AUTOR><JMENO>Jan</JMENO><PRIJMENI>Novák</PRIJMENI></AUTOR>
<TITUL>Aplikace XML</TITUL>
<VYDAVATEL><NAZEV>Soleus</NAZEV><ADRESA>…</ADRESA></VYDAVATEL>
</KNIHA>
<KNIHA>
<AUTOR><JMENO>Petr</JMENO><PRIJMENI>Nový</PRIJMENI></AUTOR>
<TITUL>Aplikace XML</TITUL>
<VYDAVATEL><NAZEV>Soleus</NAZEV><ADRESA>…</ADRESA></VYDAVATEL>
</KNIHA>
</KNIHOVNA>

V XML dokumentu je uložena jedna kniha dvakrát, pokaždé s jiným jejím autorem. Položme nyní dotaz na seznam všech knih a jejich autorů. Dotaz sestrojím klasickým způsobem:

where
        <KNIHA><AUTOR><JMENO>$j</><PRIJMENI>$p</></>
        <TITUL>$t</>
        </> in „http://www.nekde.cz/knihovna.xml“
construct
        <KNIHA>
        <SPISOVATEL>$j $p</>
        <NAZEV>$t</>
        </>

Výstup bude zcela dle očekávání:

<XML>
<KNIHA><SPISOVATEL>Jan Novák</SPISOVATEL>
<NAZEV>Aplikace XML</NAZEV>
</KNIHA>
<KNIHA><SPISOVATEL>Petr Nový</SPISOVATEL>
<NAZEV>Aplikace XML</NAZEV>
</KNIHA>
</XML>

Nyní bychom ale chtěli, aby výstup byl následující:

<XML>
<KNIHA>
<NAZEV>Aplikace XML</NAZEV>
<SPISOVATEL>Jan Novák</SPISOVATEL>
<SPISOVATEL>Petr Nový</SPISOVATEL>
</KNIHA>
</XML>

Tj., aby tato kniha byla zapsána jen jednou a všichni autoři byli uvedeni u ní v  rámci jednoho záznamu. Toho docílíme následující konstrukcí dotazu:

where
        <KNIHA> $k </> in „http://www.nekde.cz/knihovna.xml“,
        <TITUL> $n </> in $k
construct
        <KNIHA>
        <NAZEV> $n </>
        where <AUTOR><JMENO>$j</><PRIJMENI>$p</></> in $k
        construct <SPISOVATEL> $j $p</>
        </>

Princip je velmi podobný vnořování dotazů v jazyce SQL. V první části where se získají všechny knihy a pro ně se naleznou všechny jejich názvy. Při konstrukci výstupu se pak vygeneruje seznam názvů všech knih a pro každou knihu (přes vazební proměnnou $k) se vygeneruje ještě podseznam všech jejích autorů.

Operátor CONTENT_AS

Uvedený dotaz lze přeformulovat pomocí operátoru content_as. Jeho použití spočívá v tom, že dotaz formulujeme klasickým jednoduchým způsobem a výsledek tohoto dotazu se „uloží“ jako kontext do vazební proměnné, na kterou se pak odkážeme v konstrukční části. Předchozí příklad lze tedy zapsat následovně:

where
        <KNIHA>
        <TITUL>$i</>
        </> content_as $k in „http://www.nekde.cz/knihovna.xml“
construct
        <KNIHA>
        <NAZEV> $n </>
        where <AUTOR><JMENO>$j</><PRIJMENI>$p</></> in $k
        construct <SPISOVATEL> $j $p</>
        </>

Příklad se zájezdy

Nyní se na chvíli vrátím k našemu příkladu z minulého článku. Kdybychom chtěli seznam všech konaných zájezdů a u každého zájezdu seznam jeho účastníků, položili bychom dotaz takto:

where
        <KLIENT>
        <ZAJEZD ID=“$i“>$z</>
        </> content_as $k in „zajezd.xml“
construct
        <AKCE>
        <NAZEV> $z </>
        where <KLIENT><JMENO>$j</>> in $k
        construct <OSOBA>$j</>
        </>

Jak sami vidíte, jazyk XML-QL je nástroj, který na vstupu má nějaký XML dokument a na výstup dává zase XML dokument. Dá se tedy říci, že XML-QL v tomto případě slouží jako „transformátor“ XML dat.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *