XQuery: dotazy nad XML a JSON

XQuery je dotazovací jazyk pro XML a od verze 3.1 také pro mapy, pole a JSON. Sdílí s XPath datový model a mnoho výrazů, přidává FLWOR, konstrukci uzlů a moduly.

Autor: Aktualizováno

První dotaz FLWOR

Vstup
<objednavka><polozka nazev="Hrnek" cena="199"/><polozka nazev="Podtácek" cena="49"/></objednavka>
XQuery 3.1
for $p in /objednavka/polozka
let $cena := xs:decimal($p/@cena)
where $cena >= 100
order by $cena descending
return <polozka cena="{$cena}">{string($p/@nazev)}</polozka>

Výsledkem je element položky s cenou 199 a textem Hrnek. for prochází položky, let váže hodnotu, where filtruje, order by řadí a return vytváří výsledek. Cena se převádí na decimal, takže se neřadí jako text.

Sekvence a funkce

Výsledek: 121 a 242
declare function local:s-dph($cena as xs:decimal) as xs:decimal {
  $cena * 1.21
};
for $cena in (100, 200)
return local:s-dph($cena)

Základní výsledek je sekvence položek. Prázdná sekvence () není null. Funkce může mít deklarované typy a zdroj lze rozdělit do modulů s vlastním jmenným prostorem. Proměnné vážou hodnotu, nejsou běžnými měnitelnými buňkami.

Jmenné prostory

Dotaz pro XML ve jmenném prostoru
declare namespace o = "urn:objednavky";
for $p in /o:objednavka/o:polozka
return string($p/@nazev)

Prefix dotazu musí odpovídat URI, nemusí být stejný jako prefix dokumentu. Výchozí prostor elementů dotazu lze nastavit pomocí declare default element namespace; běžné neprefixované atributy tím prostor nezískají.

JSON v XQuery 3.1

Součet: 248
let $data := parse-json('{"polozky":[{"cena":199},{"cena":49}]}')
return sum($data?polozky?*?cena)

JSON objekty se převádějí na mapy, pole na XPath pole a null při parse-json na prázdnou sekvenci. Počet členů pole tím nezmizí. Operátor ? zpřístupňuje hodnoty mapy či členy pole. Na serveru lze výsledek serializovat metodou JSON; nepřeváděj mapu ručně spojováním řetězců.

XML databáze a kompatibilita

BaseX a eXist-db nabízejí XQuery nad XML databází a další vlastní funkce. doc() a collection() závisí na prostředí. Prohlížečový tester nepředstavuje celý databázový server a automaticky nestahuje libovolné dokumenty.

XQuery 3.1 je doporučení W3C z roku 2017. Návrhy 4.0 u QT4CG jsou k 1. 10. 2026 stále ve vývoji. XQuery Update je samostatné rozšíření; ukázaný čistý dotaz původní data nemění.

Časté chyby

  • Prázdný výsledek bývá způsoben jiným jmenným prostorem.
  • Pořadí textových cen se liší od číselného; proveď typovou konverzi.
  • Chyba převodu na decimal znamená neplatnou hodnotu, ne nutně neplatnou syntaxi XML.
  • U nedůvěryhodných dotazů omez přístup k souborům, síti a funkcím prostředí.

Samostatný XQuery 3.1 dotaz nad JSON

Celý XQuery program; nepotřebuje kontextový XML dokument
xquery version "3.1";
let $data := parse-json('{"knihy":[{"nazev":"XML","cena":199},{"nazev":"XPath","cena":49}]}')
return serialize(
  array {
    for $k in $data?knihy?*
    where $k?cena ge 100
    return map {"nazev": $k?nazev, "cena": $k?cena}
  },
  map {"method": "json"}
)
Očekávaný JSON výstup
[{"nazev":"XML","cena":199}]

parse-json vytváří mapu a pole v modelu XDM. ?knihy je lookup do mapy a ?* rozbalí členy pole. array zachová výsledky jako JSON pole, i když vyjde jen jedna kniha. Serialize určí metodu json; bez explicitního pole by jedna hodnota mohla mít jinou očekávanou reprezentaci.

XQuery 3.1 spojuje dotazování XML s mapami a poli, nevyžaduje převést každý JSON do XML elementů. Procesor musí podporovat příslušnou verzi a funkce. Příklad spusť například v XQuery 3.1 prostředí BaseX; náš tester použij pro podporované dotazy a ověř konkrétní omezení jeho implementace.

Funkce, namespace a XML databáze

Kompletní program s pojmenovanou funkcí
xquery version "3.1";
declare namespace k = "urn:knihy";
declare namespace local = "urn:xmlcz:funkce";
declare function local:nazev($k as element(k:kniha)) as xs:string {
  normalize-space(string($k/k:nazev))
};
let $doc := <k:katalog><k:kniha><k:nazev> XML </k:nazev></k:kniha></k:katalog>
return <vysledek>{for $k in $doc/k:kniha return <nazev>{local:nazev($k)}</nazev>}</vysledek>

Výstup je element vysledek s názvem XML bez krajních mezer. Funkce deklaruje vstup i návratový typ. XML konstruktor vytváří elementy; obsah v složených závorkách je výraz, ne doslovný text. Prefixy dotazového programu určují QName použité v cestách i typových deklaracích.

XML databáze může zpřístupnit kolekce, indexy a uložené dokumenty, ale konkrétní collection(), konfigurace a aktualizace závisí na systému. XQuery Update je samostatná specifikace; standardní return nevykonává automaticky změnu uloženého XML. Pro začátek pracuj s pevnými daty, poté přidej řízený přístup k dokumentům a parametry. Specifikace: XQuery 3.1.