středa 9. května 2007

XPath výrazy a XML jmenné prostory

Jmenné prostory (XML namespaces) slouží k oddělení XML elementů z různých schémat, které pak mohou být použity v jednom dokumentu. Jmenný prostor má svůj prefix, kterým jsou v dokumentu označeny "jeho" elementy (prefix předchází jménu elementu a je od jména oddělený dvojtečkou). Jeden jmenný prostor prefix mít nemusí (ani elementy potom prefixy nemají) a ten je potom výchozí.XML se dvěma jmennými prostory.

XPath výrazy, které v XML dokumentu bez jmenných prostorů fungují jako z praku, přidáním byť i jediného výchozího jmenného prostoru fungovat přestanou. Bohužel v té chvíli se ocitáme na poli, kde XPath tutoriály neorají a výrazy /root/child nebo //e:parent na uvedeném příkladě nic nevrátí.
Důležité pro pochopení je, že
  1. jmenný prostor není identifikován svým prefixem, ale svým jménem (tj. tím, co je za dvojtečkou)
  2. XPath elementy ve výchozím jmenném prostoru prostě zpracovat neumí
Cesta ven je poměrně jednoduchá: při zpracování XML obsahující jmenné prostory musíme tyto prostory vyjmenovat a všem jim přiřadit prefixy (které se můžou lišit od těch, které jsou v dokumentu použity).
V případě použití XPath procesoru Jaxen (který je součástí DOM4J, XOM a dalších) se to zařídí tak, že se vytvoří mapa prefixů a odpovídajících jmen jmenných prostorů a tuto mapu pak nastavíme jako namespace pro DocumentFactory, kterou vytváříme nebo načítáme XML soubory ke zpracování:
Map<String, String> ns = new HashMap<String, String>();
ns.put("x", "http://geek.cz");
ns.put("e", "http://geek.cz/enhanced");
DocumentFactory factory = new DocumentFactory();
factory.setXPathNamespaceURIs(ns);
Document doc = ...
doc.valueOf("//x:child"); // vrátí "ahoj"


V případě, že XPath potřebujeme použít v XSLT, tak opět vždy v šabloně musíme definovat prefix i výchozímu jmennému prostoru.

Kromě definování jmenných prostorů nám dává XPath možnost použít výrazy jako //*[local-name(.)='child'] nebo //*[name()='child'] (ten ale není doporučován), které vrací jméno elementu bez prefixu. Ty se ale dají použít jen v případě, že jmenné prostory nemají společná jména elementů a taky jejich nevýhodou je, že výrazy jsou pak méně přehledné.

Žádné komentáře:

Okomentovat