Hlavní navigace

Úskalí XML (3)

Petr Cimprich

XML Path Language má svůj půvab, pokud lze o něčem takovém mluvit u jazyka pro lokalizaci uzlů v dokumentu XML. Je kompaktní, přitom intuitivní a dobře čitelný. Jeho autoři, zdá se, měli šťastnou ruku. Přesto i XPath má svá drobná úskalí vedoucí k často opakovaným chybám uživatelů.

XPath 1.0

XPath není samostatný jazyk. Abychom mohli vyhodnotit výraz XPath, musíme k tomu znát aktuální kontext, který je typicky definován hostitelským jazykem (XSLT, XQuery). Obliba jazyka XPath sice vedla ke vzniku celé řady samostatných implementací, ty však musí poskytovat funkce API umožňující nastavení kontextu z aplikace. Kontext nezbytný pro vyhodnocení dotazů XPath zahrnuje tyto informace:

  • aktuální uzel a sada uzlů – Kvůli vyhodnocení relativních cest je samozřejmě třeba znát aktuální uzel. To však nestačí; vždy musí být definována i aktuální sada uzlů, její velikost (počet uzlů) a pozice aktuálního uzlu v této sadě. Bez této informace by nebylo možné vyhodnotit funkce last() a position().
  • seznam deklarovaných prefixů – Vyhodnocení kvalifikovaných jmen se neobejde bez znalosti jmenných prostorů, k nimž jsou vázány prefixy použité v dotazu.
  • seznam definovaných proměnných – Pokud dotaz obsahuje proměnné, je třeba znát jejich hodnoty.

Následující příklad ilustruje často opakovanou chybu začátečníků v XSLT; její příčinou je špatně odhadnutá aktuální sada uzlů.

<?xml version="1.0"?>
<!-- data -->
<root>
  <node/>
  <node/>

  <node/>
</root>

<?xml version="1.0"?>
<!-- stylesheet -->
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="/root">
    <xsl:apply-templates/>

  </xsl:template>

  <xsl:template match="node">
    <xsl:value-of select="position()"/>
  </xsl:template>

</xsl:stylesheet>

Výsledkem transformace není 123, jak by snad někdo mohl očekávat, ale 246. Výraz position() je vyhodnocován nad sadou všech dětí elementu root, jimiž jsou po řadě textový uzel obsahující pouze mezery a konec řádku (whitespaces), první element node, další „prázdný“ textový uzel, druhý node a tak dále. Abychom dostali očekávaný výsledek, je třeba explicitně vybrat požadovanou sadu uzlů, <xsl:apply-templates select=„node“/>, nebo zvolit některý ze způsobů, jimiž lze v XSLT ze vstupních dat odstranit „prázdné“ textové uzly (whitespace-stripping, xml:space).

Ke kontextu je ještě dobré připomenout, že každý výraz v predikátu je vyhodnocován ve svém vlastním interním kontextu, nikoli v kontextu hlavního výrazu.

<xsl:template match="node1">
  <xsl:value-of select="node2[position() = 1]">
  <xsl:value-of select="node2/node3[. = 'foo']">
  <xsl:value-of select="node2/node3[@name = current()/@name]">
</xsl:template>

Pozice v prvním výrazu se proto týká sady elementů node2, nikoli výchozí sady elementů node1. Stejně tak . (tečka) ve druhém výrazu zastupuje aktuální uzel node3. Kdybychom chtěli referovat výchozí node1, je třeba použít funkci current(), jak ukazuje třetí příklad.

Při použití jmenných prostorů ve výrazech XPath v XSLT platí jedna roztomilá výjimka – defaultní jmenný prostor se nebere do úvahy. Nekvalifikovaná jména prvků a atributů ve výrazech tedy nepatří do defaultního jmenného prostoru (je-li deklarován), ale zůstávají nezařazena. Vstupní data následující ukázky obsahují dva uzly node; první z nich patří do jmenného prostoru, druhý nikoliv. V šabloně XSLT je onen jmenný prostor deklarován jako standardní:

<?xml version="1.0"?>
<!-- data -->
<root>
  <node xmlns="http://gingerall.org/ns">A</node>
  <node>B</node>

</root>

<?xml version="1.0"?>
<!-- stylesheet -->
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns="http://gingerall.org/ns">

  <xsl:template match="/root">
    <xsl:value-of select="node"/>
  </xsl:template>

</xsl:stylesheet>

Výsledkem bude B. Kdybychom ale xmlns=„http://…“ změnili na xmlns:pre=„ht­tp://…“ a select=„node“ na select=„pre:node“, dostanemeA. Ignorování defaultního jmenného prostoru může být někdy výhodné, jindy naopak. Spolehlivým způsobem, jak se nezamotat do jmenných prostorů, je používat vždy prefixy, a to pokud možno stále stejné pro tytéž jmenné prostory. XSLT 2.0 navrhuje elegantní řešení problému s defaultním jmenným prostorem ve výrazech XPath. Atributem default-xpath-namespace si jej každý může nastavit podle potřeby.

XPath 2.0

K pohledu do budoucnosti jazyka XPath nepotřebujeme křišťálovou kouli. W3C už přibližně dva roky připravuje verzi 2.0 a pracovní verze specifikací jsou dostupné.

Přestože podoba druhé verze zatím není definitivní, některá nová úskalí se už rýsují. Tím zásadním asi bude propojení s datovými typy jazyka W3C XML Schema. Pokud dokument nebude mít k dispozici také své schéma, výrazy pracující s datovými typy budou nevyhodnotitelné. To je dalším krokem v kontroverzní snaze učinit ze schématu povinnou součát dokumentu.

Celkově je zřejmé, že XPath 2.0 bude o dost komplexnější než jeho předchůdce. Správné a logické změny zůstávají poněkud ve stínu nových funkcí a konceptů, kouzlo jednoduchosti bude z velké části pryč. Jedno je jisté – o temná místa v XPath 2.0 určitě nebude nouze.

Našli jste v článku chybu?

24. 1. 2003 11:11

pp (neregistrovaný)

XPath (1.0) si muzete osahat pomoci programu
XSH (http://xsh.sourceforge.net), ktery vyvijim. Nabizi interaktivni shell pro praci s XML dokumenty i davkove zpracovani. Vetsina prikazu pracuje prave na zaklade XPath. XSH umoznuje delat s dokumenty rychle upravy, napr. kopirovat ci presouvat uzly v ramci jednoho ci mezi ruznymi dokumenty, mazat a vytvaret nove uzly. Cele to je trochu pojate a la filesystem, takze funguji prikazy typu cd <xpath>, pwd, ale i foreach apod. XSH je napsan v Perl…

DigiZone.cz: Recenze Westworld: zavraždit a...

Recenze Westworld: zavraždit a...

Lupa.cz: Propustili je z Avastu, už po nich sahá ESET

Propustili je z Avastu, už po nich sahá ESET

DigiZone.cz: Placené VoD a obsah zdarma

Placené VoD a obsah zdarma

DigiZone.cz: Dreambox DM900 Ultra HD přichází

Dreambox DM900 Ultra HD přichází

Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

120na80.cz: Pánové, pečujte o svoje přirození a prostatu

Pánové, pečujte o svoje přirození a prostatu

Podnikatel.cz: EET: Totálně nezvládli metodologii projektu

EET: Totálně nezvládli metodologii projektu

Měšec.cz: Air Bank zruší TOP3 garanci a zdražuje kurzy

Air Bank zruší TOP3 garanci a zdražuje kurzy

Lupa.cz: Co se dá měřit přes Internet věcí

Co se dá měřit přes Internet věcí

Vitalia.cz: „Připluly“ z Německa a možná obsahují jed

„Připluly“ z Německa a možná obsahují jed

Vitalia.cz: Jmenuje se Janina a žije bez cukru

Jmenuje se Janina a žije bez cukru

Root.cz: Certifikáty zadarmo jsou horší než za peníze?

Certifikáty zadarmo jsou horší než za peníze?

Lupa.cz: Proč firmy málo chrání data? Chovají se logicky

Proč firmy málo chrání data? Chovají se logicky

Lupa.cz: Teletext je „internetem hipsterů“

Teletext je „internetem hipsterů“

Podnikatel.cz: Zavře krám u #EET Malá pokladna a Teeta?

Zavře krám u #EET Malá pokladna a Teeta?

Vitalia.cz: Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Lupa.cz: Insolvenční řízení kvůli cookies? Vítejte v ČR

Insolvenční řízení kvůli cookies? Vítejte v ČR

Měšec.cz: mBank cenzuruje, zrušila mFórum

mBank cenzuruje, zrušila mFórum

Měšec.cz: Zdravotní a sociální pojištění 2017: Připlatíte

Zdravotní a sociální pojištění 2017: Připlatíte

Vitalia.cz: Paštiky plné masa ho zatím neuživí

Paštiky plné masa ho zatím neuživí