Potřebujete pomoci s XSLT?
Nabízím školení, konzultace, vývoj XSLT kódu na zakázku. Nevájte a kontaktujte mne.

Podpořte provoz stránek
Platba probíhá pomocí služby PayPal a je možné platit kartou nebo převodem z vašeho PayPal účtu.

11.6 Zpracování dokumentů používajících jmenné prostory

Častým dotazem bývá, jak zpracovávat dokumenty, jejichž elementy patří do nějakého jmenného prostoru. Zpracování je zcela stejné, jako u elementu bez jmenných prostorů, ale musíme si uvědomit, že v XPath dotazech se musí používat plně kvalifikovaná jména (prefix jmenného prostoru společně s lokálním názvem elementu). Prefix jmenného prostoru přitom musí být definován ve stylu, protože v něm používáme XPath dotazy. Prefixy musíme ve stylu používat i v případě, že vstupní dokument používá implicitní jmenný prostor. Je to logické, protože XSLT transformace se dostane až k abstraktní stromové reprezentaci dokumentu, která od podobných věcí do jisté míry abstrahuje.

Ukažme si to například na XHTML dokumentu. Všechny elementy XHTML patří do jmenného prostoru http://www.w3.org/1999/xhtml, stránka proto začíná zápisem:

<html lang="cs" xml:lang="cs" xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Nadpis</title>
  </head>
  <body>
    ...
  </body>
</html>

Abychom mohli s tímto dokumentem ve stylu pracovat, musíme si pro jeho jmenný prostor ve stylu definovat prefix, například html:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:html="http://www.w3.org/1999/xhtml"
                version="1.0">

Pro zjištění nadpisu stránky pak můžeme použít například následující XPath dotaz:

html:html/html:head/html:title

Vše si ukážeme na příkladě, který je schopný do libovolné XHTML stránky doplnit menu s jejím obsahem.

Příklad 11.10. Ukázková XHTML stránka – stranka.html

<?xml version="1.0" encoding="utf-8"?>
<!--
Odkaz na DTD je odstraněn, protože vyžaduje přístup k Internetu
nebo funkční katalogové soubory.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-->
<html lang="cs" xml:lang="cs" xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Slohová práce</title>
  </head>
  <body>
    <h1>Slohová práce</h1>

    <h2 id="uvod">Úvod</h2>
    <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
      Vivamus at lectus eget erat fermentum nonummy. Pellentesque a
      diam. Pellentesque quis lorem vitae lorem ornare egestas. Mauris
      risus turpis, faucibus sit amet, venenatis nec, tempus at,
      purus. Fusce at tellus vel neque tincidunt dictum. Integer felis
      justo, tempor nec, fringilla vel, tempus id, risus. Sed sapien
      ipsum, rutrum vel, auctor ut, tincidunt eget, ante. Donec diam
      tellus, elementum at, tincidunt ac, consequat vitae, purus.
      Fusce rhoncus sem mollis velit. Aliquam tempor ipsum sit amet
      magna. Sed facilisis leo a justo. Praesent fermentum, magna
      vestibulum rhoncus mattis, lectus tortor tincidunt sem, vitae
      ultricies urna ipsum sit amet lectus. Proin iaculis ligula eget
      lorem.</p>

    <h2 id="stat">Stať</h2>
    <p>Aliquam erat volutpat. Duis id felis. Suspendisse dictum
      hendrerit dolor. Sed eleifend. Sed eget arcu. Proin ultrices,
      leo ut pharetra eleifend, mi felis elementum arcu, ac bibendum
      nulla tellus eget odio. Curabitur vitae ipsum id felis accumsan
      fringilla. Class aptent taciti sociosqu ad litora torquent per
      conubia nostra, per inceptos hymenaeos. Morbi a erat ac nunc
      vestibulum semper. In ultricies nisl et tortor. Donec faucibus.
      Quisque dui arcu, vulputate at, vulputate sit amet, luctus at,
      orci.</p>

    <h3>Podstatná stať</h3>
    <p>Curabitur metus lorem, ultricies nec, pulvinar et, aliquam
      dignissim, lectus. Nulla interdum vestibulum enim. Proin in nisl
      eget nibh laoreet blandit. Maecenas congue, odio quis imperdiet
      porta, ante neque aliquam quam, eu eleifend turpis eros sed
      lorem. Suspendisse potenti. Duis dapibus nonummy augue. Praesent
      massa magna, luctus non, tincidunt non, lacinia a, tellus. Fusce
      sapien purus, ullamcorper et, laoreet et, adipiscing id, mi.
      Donec in nulla eu ligula fermentum ornare. Nunc nunc diam,
      mollis et, porttitor sed, pharetra at, magna. Donec cursus
      porttitor libero. Aenean in odio vitae elit mollis feugiat.
      Nulla elementum. Aliquam erat volutpat. Mauris eros nisl,
      placerat vitae, posuere vitae, luctus vel, nisl. Nam sit amet
      lorem. Aliquam erat volutpat.</p>

    <p>Fusce eleifend nunc sollicitudin mauris. Nunc dictum.
      Pellentesque habitant morbi tristique senectus et netus et
      malesuada fames ac turpis egestas. Curabitur vehicula vestibulum
      libero. Duis ut arcu. Fusce dictum, lacus vitae pharetra
      vestibulum, urna arcu placerat augue, sit amet dapibus mauris
      mauris nec nibh. Mauris tempor bibendum leo. Ut rhoncus massa et
      diam. Nulla dapibus. Donec nunc nunc, fermentum quis, varius a,
      scelerisque eget, purus. Etiam ut erat.</p>

    <h2>Podstatnější stať</h2>
    <p>Ut sit amet magna. Etiam risus sapien, ultrices vel, tristique
      eu, pellentesque sed, eros. In aliquet hendrerit nunc. Ut luctus
      sollicitudin orci. Maecenas ut mi adipiscing diam sagittis
      pretium. Donec condimentum facilisis mauris. Nulla placerat,
      pede at ultrices lobortis, felis sem fermentum mi, ut venenatis
      mauris massa eu wisi. In scelerisque lacinia risus. Ut
      tincidunt, tellus ut vulputate pharetra, neque ligula fringilla
      enim, vel tempus eros tellus non sem. Pellentesque habitant
      morbi tristique senectus et netus et malesuada fames ac turpis
      egestas. In hac habitasse platea dictumst. Sed eu orci. Praesent
      commodo elementum magna. Aenean in augue ut nibh ullamcorper
      convallis. Integer vel nunc at ante commodo auctor. Sed rhoncus
      mi et diam. Pellentesque elit. Mauris id felis.</p>

    <p>Donec sapien mauris, elementum quis, ornare id, rhoncus at,
      nunc. Proin ac nibh in augue bibendum consectetuer. Nullam
      porta. Integer nisl massa, gravida et, luctus a, nonummy in,
      nulla. Proin placerat sapien sed nibh. Nulla wisi nibh, euismod
      et, auctor vel, ultrices id, lorem. Phasellus nec lorem id arcu
      rhoncus ultricies. Curabitur urna. Sed augue massa, auctor
      vitae, laoreet ut, sagittis id, sem. Proin sapien dolor, tempus
      ac, euismod id, pretium at, velit. Praesent eget dui at neque
      sollicitudin hendrerit. Sed et dolor non turpis tincidunt
      interdum. Aenean gravida ante ac lacus. Morbi pellentesque,
      metus eget congue cursus, enim ligula congue velit, feugiat
      lobortis ante dui accumsan orci. Sed commodo consequat urna.
      Cras ultricies justo sit amet pede. Aliquam laoreet volutpat
      odio.</p>

    <h3>Nepostatná nestať</h3>
    <p>Vivamus vulputate libero vel dolor. Donec ac nulla sed erat
      consequat semper. Mauris pretium magna semper orci. Phasellus
      gravida, lacus nec fringilla gravida, dolor metus ultricies
      nibh, fringilla iaculis elit erat ut dui. Integer lacinia varius
      arcu. Nulla sagittis sem eu dolor. Integer augue. Fusce pretium.
      Ut vehicula mattis lacus. Sed sit amet leo. Class aptent taciti
      sociosqu ad litora torquent per conubia nostra, per inceptos
      hymenaeos. Aenean vestibulum nisl in mi. Mauris pretium
      malesuada lorem. Curabitur eget orci ut metus suscipit rutrum.
      Nullam non pede in sem iaculis iaculis. Maecenas nec velit non
      mi cursus placerat. Fusce tempor aliquam libero. Suspendisse
      fringilla nisl eget ante.</p>

    <p>Proin est. Nam eget nunc in mi lobortis pulvinar. Cras diam.
      Cras malesuada, purus at condimentum eleifend, nunc lacus
      condimentum metus, non auctor est magna in nulla. Quisque
      aliquet augue. Fusce vestibulum. Ut commodo scelerisque arcu.
      Sed a nisl et elit accumsan sagittis. Vivamus ante orci,
      ullamcorper sed, interdum nec, pulvinar eu, quam. Nulla
      consequat turpis sed purus. In hac habitasse platea dictumst.
      Nam ultricies pede quis massa luctus tincidunt. Etiam porta
      pellentesque metus. Etiam aliquam, ipsum non posuere volutpat,
      nulla justo posuere ipsum, quis dictum orci leo ut ipsum. Morbi
      varius dui eu risus. Sed id odio. Proin a diam et ante gravida
      elementum.</p>

    <h2>Sťal</h2>
    <p>Cum sociis natoque penatibus et magnis dis parturient montes,
      nascetur ridiculus mus. Duis tempor. Fusce magna dui, euismod
      dignissim, posuere vel, mollis ut, massa. Aenean bibendum. Morbi
      id diam. Nam bibendum. Nunc scelerisque tempus tortor. Aenean id
      libero sit amet arcu lacinia vulputate. Cras lobortis dui
      consectetuer neque. Donec accumsan ipsum dignissim nisl. Cum
      sociis natoque penatibus et magnis dis parturient montes,
      nascetur ridiculus mus. Nulla consequat dictum leo.</p>

    <p>Sed tincidunt magna eu purus. Duis lobortis mollis est. Nullam
      turpis diam, condimentum a, volutpat vel, pharetra a, pede. Cras
      elit ligula, venenatis non, tempus ut, feugiat vel, nulla. Etiam
      viverra velit nec nibh. Integer nec lectus. Etiam dapibus
      egestas augue. Mauris at sapien. In hac habitasse platea
      dictumst. Proin risus.</p>

    <h2 id="zaver">Závěr</h2>
    <p>Vivamus lobortis vestibulum velit. Proin id leo. Nullam sit
      amet wisi vel orci vestibulum dignissim. Cras sapien orci,
      scelerisque a, malesuada vitae, gravida non, quam. Proin sit
      amet elit eu dui auctor iaculis. Curabitur sagittis, odio sit
      amet hendrerit eleifend, tortor tortor convallis mi, at euismod
      enim risus ut mauris. Proin a sapien. Vivamus sed ipsum.
      Pellentesque fringilla elementum turpis. Praesent vel nunc. Duis
      lobortis lacinia enim. Donec vitae neque in lectus sodales
      egestas. Mauris vel lorem ac neque dictum dapibus. Cum sociis
      natoque penatibus et magnis dis parturient montes, nascetur
      ridiculus mus.</p>

  </body>
</html>

Příklad 11.11. Přidání obsahu do XHTML stránky – addmenu.xsl

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:html="http://www.w3.org/1999/xhtml"
                version="1.0">

<!-- Výstupem je XHTML Strict -->
<xsl:output method="xml" encoding="utf-8" 
            doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
            doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"/>

<!-- Standardně se všechny uzly kopírují -->
<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

<!-- Vložení stylu do záhlaví -->
<xsl:template match="html:head">
  <!-- Zkopírování atributů -->
  <xsl:copy>
    <xsl:apply-templates select="@*"/>
    <!-- Informace o kódování -->
    <xsl:element name="meta" namespace="http://www.w3.org/1999/xhtml">
      <xsl:attribute name="http-equiv">Content-Type</xsl:attribute>
      <xsl:attribute name="content">text/html;charset=utf-8</xsl:attribute>
    </xsl:element>
    <!-- Zkopírování původního obsahu elementu head -->
    <xsl:apply-templates select="node()"/>
    <!-- Vložení stylu -->
    <xsl:element name="style" namespace="http://www.w3.org/1999/xhtml">
      <xsl:attribute name="type">text/css</xsl:attribute>
      .menu { position: fixed;
              left: 10px;
              width: 182px;
              border: 2px blue solid;
              padding: 2px;
	      overflow: auto;
              height: 90%;

              /* IE hack */
              position: expression("absolute");
              top: expression(document.body.scrollTop+this.offsetHeight-this.offsetHeight);
            }
      .content { margin-left: 200px }
    </xsl:element>
  </xsl:copy>
</xsl:template>

<!-- Odstranění původní informace o kódování -->
<xsl:template match="html:meta[translate(@http-equiv,'CONTEYP','conteyp')='content-type']"/>

<!-- Hned za HTML se vloží menu -->
<xsl:template match="html:body">
  <!-- Kopie elementu body -->
  <xsl:copy>
    <!-- Zkopírování všech atributů -->
    <xsl:apply-templates select="@*"/>
    <!-- Vytvoření menu -->
    <xsl:element name="div" namespace="http://www.w3.org/1999/xhtml">
      <xsl:attribute name="class">menu</xsl:attribute>
      <xsl:apply-templates mode="toc"/>
    </xsl:element>
    <!-- Původní obsah stránky -->
    <xsl:element name="div" namespace="http://www.w3.org/1999/xhtml">
      <xsl:attribute name="class">content</xsl:attribute>
      <xsl:apply-templates select="node()"/>
    </xsl:element>
  </xsl:copy>
</xsl:template>

<!-- Položka obsahu z nadpisu h1 --> 
<xsl:template match="html:h1" mode="toc">
  <xsl:variable name="id">
    <xsl:call-template name="getid"/>
  </xsl:variable>
  <xsl:element name="a" namespace="http://www.w3.org/1999/xhtml">
    <xsl:attribute name="href">#<xsl:value-of select="$id"/></xsl:attribute>
    <xsl:value-of select="."/>
  </xsl:element>
  <xsl:element name="br" namespace="http://www.w3.org/1999/xhtml"/>
</xsl:template>

<!-- Položka obsahu z nadpisu h2 -->
<xsl:template match="html:h2" mode="toc">
  <xsl:variable name="id">
    <xsl:call-template name="getid"/>
  </xsl:variable>
  - 
  <xsl:element name="a" namespace="http://www.w3.org/1999/xhtml">
    <xsl:attribute name="href">#<xsl:value-of select="$id"/></xsl:attribute>
    <xsl:value-of select="."/>
  </xsl:element>
  <xsl:element name="br" namespace="http://www.w3.org/1999/xhtml"/>
</xsl:template>

<!-- Položka obsahu z nadpisu h3 -->
<xsl:template match="html:h3" mode="toc">
  <xsl:variable name="id">
    <xsl:call-template name="getid"/>
  </xsl:variable>
  --
  <xsl:element name="a" namespace="http://www.w3.org/1999/xhtml">
    <xsl:attribute name="href">#<xsl:value-of select="$id"/></xsl:attribute>
    <xsl:value-of select="."/>
  </xsl:element>
  <xsl:element name="br" namespace="http://www.w3.org/1999/xhtml"/>
</xsl:template>

<!-- V režimu tvorby obsahu nás zajímají jen nadpisy, ostatní text ignorujeme -->
<xsl:template match="text()" mode="toc"/>

<!-- Doplnění identifikátorů pro odkazy -->
<xsl:template match="html:h1[not(@id)] | html:h2[not(@id)] | html:h3[not(@id)]">
  <xsl:copy>
    <!-- Zkopírování všech atributů -->
    <xsl:apply-templates select="@*"/>
    <!-- Doplnění ID -->
    <xsl:attribute name="id"><xsl:value-of select="generate-id()"/></xsl:attribute>
    <!-- Zkopírování původního obsahu elementu -->
    <xsl:apply-templates select="node()"/>
  </xsl:copy>
</xsl:template>

<!-- Vrátí bud skutečné nebo automaticky vygenerované ID 
     pro aktuální element -->
<xsl:template name="getid">
  <xsl:choose>
    <xsl:when test="@id">
      <xsl:value-of select="@id"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="generate-id()"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

</xsl:stylesheet>

Na příkladě si ještě všimněte, že i elementy, které generujeme musí patřit do jmenného prostoru XHTML. Používáme přitom konstrukci xsl:element místo prostého html:název, aby se elementy zařadily do implicitního jmenného prostoru. Druhou možností je použití zápisu využívajícího implicitní jmenný prostor:

<název xmlns="http://www.w3.org/1999/xhtml">

Následující příklad ukazuje alternativní metodu pro vygenerování menu.

Příklad 11.12. Přidání obsahu do XHTML stránky trochu jinak – addmenu2.xsl

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:html="http://www.w3.org/1999/xhtml"
                xmlns="http://www.w3.org/1999/xhtml"
                exclude-result-prefixes="html"
                version="1.0">

<!-- Výstupem je XHTML Strict -->
<xsl:output method="xml" encoding="utf-8" 
            doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
            doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"/>

<!-- Standardně se všechny uzly kopírují -->
<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

<!-- Vložení stylu do záhlaví -->
<xsl:template match="html:head">
  <!-- Zkopírování atributů -->
  <xsl:copy>
    <xsl:apply-templates select="@*"/>
    <!-- Informace o kódování -->
    <meta 
          http-equiv="Content-Type"
          content="text/html;charset=utf-8"/>
    <!-- Zkopírování původního obsahu elementu head -->
    <xsl:apply-templates select="node()"/>
    <!-- Vložení stylu -->
    <style type="text/css">
      .menu { position: fixed;
              left: 10px;
              width: 182px;
              border: 2px blue solid;
              padding: 2px;
	      overflow: auto;
              height: 90%;

              /* IE hack */
              position: expression("absolute");
              top: expression(document.body.scrollTop+this.offsetHeight-this.offsetHeight);
            }
      .content { margin-left: 200px }
    </style>
  </xsl:copy>
</xsl:template>

<!-- Odstranění původní informace o kódování -->
<xsl:template match="html:meta[translate(@http-equiv,'CONTEYP','conteyp')='content-type']"/>

<!-- Hned za HTML se vloží menu -->
<xsl:template match="html:body">
  <!-- Kopie elementu body -->
  <xsl:copy>
    <!-- Zkopírování všech atributů -->
    <xsl:apply-templates select="@*"/>
    <!-- Vytvoření menu -->
    <div class="menu">
      <xsl:apply-templates mode="toc"/>
    </div>
    <!-- Původní obsah stránky -->
    <div class="content">
      <xsl:apply-templates select="node()"/>
    </div>
  </xsl:copy>
</xsl:template>

<!-- Položka obsahu z nadpisu h1 --> 
<xsl:template match="html:h1" mode="toc">
  <xsl:variable name="id">
    <xsl:call-template name="getid"/>
  </xsl:variable>
  <a href="#{$id}">
    <xsl:value-of select="."/>
  </a>
  <br/>
</xsl:template>

<!-- Položka obsahu z nadpisu h2 -->
<xsl:template match="html:h2" mode="toc">
  <xsl:variable name="id">
    <xsl:call-template name="getid"/>
  </xsl:variable>
  - 
  <a href="#{$id}">
    <xsl:value-of select="."/>
  </a>
  <br/>
</xsl:template>

<!-- Položka obsahu z nadpisu h3 -->
<xsl:template match="html:h3" mode="toc">
  <xsl:variable name="id">
    <xsl:call-template name="getid"/>
  </xsl:variable>
  --
  <a href="#{$id}">
    <xsl:value-of select="."/>
  </a>
  <br/>
</xsl:template>

<!-- V režimu tvorby obsahu nás zajímají jen nadpisy, ostatní text ignorujeme -->
<xsl:template match="text()" mode="toc"/>

<!-- Doplnění identifikátorů pro odkazy -->
<xsl:template match="html:h1[not(@id)] | html:h2[not(@id)] | html:h3[not(@id)]">
  <xsl:copy>
    <!-- Zkopírování všech atributů -->
    <xsl:apply-templates select="@*"/>
    <!-- Doplnění ID -->
    <xsl:attribute name="id"><xsl:value-of select="generate-id()"/></xsl:attribute>
    <!-- Zkopírování původního obsahu elementu -->
    <xsl:apply-templates select="node()"/>
  </xsl:copy>
</xsl:template>

<!-- Vrátí bud skutečné nebo automaticky vygenerované ID 
     pro aktuální element -->
<xsl:template name="getid">
  <xsl:choose>
    <xsl:when test="@id">
      <xsl:value-of select="@id"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="generate-id()"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

</xsl:stylesheet>

© Jiří Kosek 2014

Tento dokument je určen výhradně pro osobní potřebu seznámení s jazykem XSLT. Jakékoliv jiné použití, včetně dalšího šíření, pořizování kopií, použití při školeních a výuce apod. je výslovně zakázáno a bude považováno za porušení autorských práv.


Copyright © 2000-2014 Jiří Kosek