Potřebujete pomoci s XSL-FO?
Nabízím školení, konzultace, vývoj tiskových šablon 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.

Kapitola 6. Ukázky

6.1. Katalog výrobků
6.2. Citáty
6.3. Faktura
6.4. SVG a grafy
6.5. Čárové kódy

6.1 Katalog výrobků

Příklad demonstruje:

  • využití základních formátovacích objektů;

  • číslování stran;

  • řízení stránkového zlomu;

  • použití plovoucích objektů;

  • vkládání obrázků;

  • vytváření seznamů;

  • podmíněný výběr předlohy stránky.

Příklad 6.1. Katalog výrobků – katalog.xml

<?xml version="1.0" encoding="utf-8"?>
<katalog>
  <info>
    <firma>Sony</firma>
    <adresa>Nedůležitá, NěkdeTown</adresa>
    <obdobi>zima 2001</obdobi>
  </info>
  
  <polozka kod="mxd-d4">
    <nazev>MiniDisc kombinovaný s CD přehrávačem</nazev>
    <kategorie>MiniDisc</kategorie>
    <cena>14990</cena>
    <popis>Kombinace MD a CD pro pohodlné nahrávání z CD<br/>
      přepis <b>vysokou rychlostí</b> z CD<br/>
      nahrávání v LP režimu (4x)<br/>
      20 bitový A/D převodník<br/>funkce Time Machine Recording<br/>
      funkce sf Edit<br/>
      nízká spotřeba v pohotovostním režimu</popis>
  </polozka>
  
  <polozka kod="mds-ja555es_n">
    <nazev>MiniDisc rekordér řady ES</nazev>
    <kategorie>MiniDisc</kategorie>
    <cena>34990</cena>
    <popis>plné editační možnosti<br/>
      zásuvková mechanika pro vkládání
      MD<br/>
      Pitch Control<br/>
      proudový pulsní D/A převodník<br/>
      24bitový A/D převodník<br/>
      digitální filtr s proměnným
      koeficientem<br/>
      dvojitý transformátor s kruhovým jádrem
      (R-Core)<br/>
      systém DSP ATRAC typu R<br/>
      digitální ovládání záznamové úrovně<br/>
      dva optické digitální výstupy + koaxiální
      digitální vstup<br/>
      ovládání A1 (Control A1)<br/>
      provedení <b>ve zlaté
        barvě</b></popis>
    <foto href="MDSJA555ES_N.jpg"/>
  </polozka>
  
  <polozka kod="str-de135">
    <nazev>Stereo receiver a zesilovač</nazev>
    <kategorie>Receiver</kategorie>
    <cena>5990</cena>
    <popis>2 x 60W (DIN 4 Ohm)<br/>
      3 audiovstupy<br/>tuner RDS/EON<br/>30 předvoleb, korekce tónu a
      vyvážení<br/>digitální zpracování signálu - DSP<br/>
      systémový dálkový ovladač </popis>
    <foto href="STRDE135.jpg"/>
  </polozka>
  
  <polozka kod="mz-r90">
    <nazev>MD Walkman</nazev>
    <kategorie>MiniDisc</kategorie>
    <cena>12990</cena>
    <popis>MD Walkman s možností záznamu<br/>
      <b>nejmenší na světě</b><br/>
      tělo přístroje z magnézia - výjimečně nízká hmotnost<br/>
      Pop Up Eject mechanismus<br/>až 14,5 hodin záznamu / 
      29 hodin reprodukce (Ni-MH + AA
      baterie)<br/>
      40 sec. ESP, Mega Bass<br/>
      dálkové ovládání s podsvětleným LCD displejem (9 znaků) s editovacími
      funkcemi<br/>možnost pojmenování skladeb a disku během záznamu<br/>
      možnost monofonního záznamu v LP režimu
      (až 160 min.)<br/>
      LCD displej na přístroji<br/>
      paměť pro často užívaná slova
      (cca 40 výrazů po 10 znacích)<br/>možnost kopírování 
      CD textu<br/>linkový
      vstup / výstup, optický vstup, vstup pro mikrofon<br/>zásuvka pro
      napájení ze sítě, AC adaptér, dobíjecí Ni-MH baterie</popis>
    <foto href="MZR90.jpg"/>
  </polozka>
  
  <polozka kod="ss-mb215">
    <nazev>3pásmové reproduktory</nazev>
    <kategorie>Reproduktory</kategorie>
    <cena>3990</cena>
    <popis>párové, regálové, 3pásmové<br/>
      max. zatížitelnost 120W<br/>impedance 8 Ohm<br/>
      bassreflex<br/>magneticky stíněné<br/>
      odnímatelné mřížky<br/>
      rozměry: 220 x 518 x 230 mm</popis>
  </polozka>
  
  <polozka kod="ss-cr490">
    <nazev>Sada AV reproduktorů</nazev>
    <kategorie>Reproduktory</kategorie>
    <cena>5990</cena>
    <popis>2 x zadní, 1 x centrální, 2 pásmové<br/>
      maximální zatížitelnost zadní: 120 W, centrální: 150 W<br/>
      impedance 8 Ohm</popis>
  </polozka>
  
</katalog>

Příklad 6.2. Styl pro základní formátování katalogu – katalog.xsl

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

<xsl:template match="/">
  <fo:root>
    <!-- Definice layoutu stránky -->
    <fo:layout-master-set>
      <!-- Rozměry stránky a její okraje -->
      <fo:simple-page-master master-name="my-page"
        page-height="297mm" page-width="210mm" margin="1in">
  
        <!-- Tiskové zrcadlo - oblast pro samotný obsah stránky -->
        <fo:region-body margin-bottom="15mm" margin-top="15mm"/>        
        
        <!-- Oblast pro záhlaví stránky -->
        <fo:region-before extent="10mm"/>
        
        <!-- Oblast pro zápatí stránky -->
        <fo:region-after extent="10mm"/>
      </fo:simple-page-master>
    </fo:layout-master-set>
    
    <!-- Definice obsahu stránky -->
    <fo:page-sequence master-reference="my-page">
      <!-- Společný obsah všech stránek v zápatí stránky -->
      <fo:static-content flow-name="xsl-region-after">
        <fo:block>
          <xsl:text>Strana </xsl:text>
          <fo:page-number/>
          <xsl:text> z </xsl:text>
          <fo:page-number-citation ref-id="last_page"/>
        </fo:block>
      </fo:static-content>

      <!-- Společný obsah všech stránek v záhlaví stránky -->
      <fo:static-content flow-name="xsl-region-before">
        <fo:block text-align-last="justify">
          Katalog <xsl:value-of select="/katalog/info/firma"/>
          <fo:leader leader-pattern="space"/>
          Období: <xsl:value-of select="/katalog/info/obdobi"/>
        </fo:block>
      </fo:static-content>

      <!-- Samotný text dokumentu -->
      <fo:flow flow-name="xsl-region-body" 
               font-family="Arial,Helvetica,sans-serif"
               font-size="12pt">

        <!-- Zpracování všech elementů zdrojového dokumentu -->
        <xsl:apply-templates/>

        <!-- Prázdný blok pro zjištění čísla poslední strany -->
        <fo:block id="last_page"/>

      </fo:flow>
    </fo:page-sequence>
  </fo:root>
</xsl:template>

<xsl:template match="info">
  <fo:block font-size="24pt" text-align="center"
            space-after="18pt" color="navy">
    <xsl:value-of select="firma"/>
  </fo:block>
</xsl:template>

<xsl:template match="polozka">
  <!-- Celá položka bude vždy na jené stejné straně -->
  <fo:block keep-together.within-column="always">
    <xsl:apply-templates select="nazev"/>
    <fo:block text-align-last="justify" font-size="6pt" 
              space-after="1.5pt">
      Kategorie: <fo:inline color="red"><xsl:value-of 
                     select="kategorie"/></fo:inline>
      <fo:leader leader-pattern="space"/>
      Cena: <xsl:value-of select="cena"/></fo:block>
    <xsl:if test="foto[@href]">
      <fo:float float="end">
        <fo:block>
          <fo:external-graphic src="url({foto/@href})" content-width="5cm" 
                               width="40%" text-align="center"/>
        </fo:block>
      </fo:float>
    </xsl:if>
    <xsl:apply-templates select="popis"/>
      
  </fo:block>
  <!-- Mezi položkami bude čára -->
  <xsl:if test="following-sibling::polozka">
    <fo:block text-align-last="justify" space-after="0pt" 
              keep-with-next="always" clear="both">
      <fo:leader leader-pattern="rule"/>
    </fo:block>
  </xsl:if>
</xsl:template>

<xsl:template match="nazev">
  <fo:block font-size="14pt" font-weight="bold">
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<!-- Popis je uložen tak, že jej nejde snadno zpracovat pomocí XSLT šablon.
     Elegantnější řešení nabídne XSLT 2.0 -->
<xsl:template match="popis">
  <fo:list-block provisional-distance-between-starts="1em"
                 font-size="10pt">
    <xsl:for-each-group select="node()" group-starting-with="br">
      <fo:list-item>
        <fo:list-item-label start-indent="0.5em" end-indent="label-end()">
          <fo:block>&#x2022;</fo:block>
        </fo:list-item-label>
        <fo:list-item-body start-indent="body-start()">
          <fo:block>
            <xsl:apply-templates select="current-group()"/>
          </fo:block>
        </fo:list-item-body>
      </fo:list-item>
    </xsl:for-each-group>
  </fo:list-block>
</xsl:template>

<xsl:template match="b">
  <fo:inline font-weight="bold">
    <xsl:apply-templates/>
  </fo:inline>
</xsl:template>

</xsl:stylesheet>

Příklad 6.3. Katalog s odlišnou titulní stranou – katalog-titulni-strana.xsl

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

<!-- Import stávajícího stylu -->
<xsl:import href="katalog.xsl"/>

<!-- Předefinování zpracování -->
<xsl:template match="/">
  <fo:root>

    <!-- Definice layoutu stránky -->
    <fo:layout-master-set>
      <!-- Rozměry stránky a její okraje -->
      <fo:simple-page-master master-name="normalni"
        page-height="297mm" page-width="210mm" margin="1in">
  
        <!-- Tiskové zrcadlo - oblast pro samotný obsah stránky -->
        <fo:region-body margin-bottom="15mm" margin-top="15mm"/>        
        
        <!-- Oblast pro záhlaví stránky -->
        <fo:region-before extent="10mm"/>
        
        <!-- Oblast pro zápatí stránky -->
        <fo:region-after extent="10mm"/>
      </fo:simple-page-master>

      <!-- Definice layoutu první stránky bez záhlaví -->
      <fo:simple-page-master master-name="prvni"
        page-height="297mm" page-width="210mm" margin="1in">
  
        <!-- Tiskové zrcadlo - oblast pro samotný obsah stránky -->
        <fo:region-body margin-bottom="15mm"/>        
        
        <!-- Oblast pro zápatí stránky -->
        <fo:region-after extent="10mm"/>
      </fo:simple-page-master>

      <!-- Sekvence stránek, kde první nemá záhlaví -->
      <fo:page-sequence-master master-name="katalog">
        <fo:repeatable-page-master-alternatives>
          <fo:conditional-page-master-reference master-reference="prvni"
            page-position="first"/>
          <fo:conditional-page-master-reference master-reference="normalni"
            page-position="any"/>
        </fo:repeatable-page-master-alternatives>
      </fo:page-sequence-master>
      
    </fo:layout-master-set>
    
    <!-- Definice obsahu stránky -->
    <fo:page-sequence master-reference="katalog">
      <!-- Společný obsah všech stránek v zápatí stránky -->
      <fo:static-content flow-name="xsl-region-after">
        <fo:block>
          <xsl:text>Strana </xsl:text>
          <fo:page-number/>
          <xsl:text> z </xsl:text>
          <fo:page-number-citation ref-id="last_page"/>
        </fo:block>
      </fo:static-content>

      <!-- Společný obsah všech stránek v záhlaví stránky -->
      <fo:static-content flow-name="xsl-region-before">
        <fo:block text-align-last="justify">
          Katalog <xsl:value-of select="/katalog/info/firma"/>
          <fo:leader leader-pattern="space"/>
          Období: <xsl:value-of select="/katalog/info/obdobi"/>
        </fo:block>
      </fo:static-content>

      <!-- Samotný text dokumentu -->
      <fo:flow flow-name="xsl-region-body" 
               font-family="Arial,Helvetica,sans-serif"
               font-size="12pt">

        <!-- Zpracování všech elementů zdrojového dokumentu -->
        <xsl:apply-templates/>

        <!-- Prázdný blok pro zjištění čísla poslední strany -->
        <fo:block id="last_page"/>

      </fo:flow>
    </fo:page-sequence>
  </fo:root>
</xsl:template>

</xsl:stylesheet>

Příklad 6.4. Katalog s odlišnými patičkami na sudé a liché stránce – katalog-sude-liche.xsl

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

<!-- Import stávajícího stylu -->
<xsl:import href="katalog.xsl"/>

<!-- Předefinování zpracování -->
<xsl:template match="/">
  <fo:root>

    <!-- Definice layoutu stránky -->
    <fo:layout-master-set>
      <!-- Rozměry stránky a její okraje -->
      <fo:simple-page-master master-name="suda"
        page-height="297mm" page-width="210mm" margin="1in">
  
        <!-- Tiskové zrcadlo - oblast pro samotný obsah stránky -->
        <fo:region-body margin-bottom="15mm" margin-top="15mm"/>        
        
        <!-- Oblast pro záhlaví stránky -->
        <fo:region-before extent="10mm"/>
        
        <!-- Oblast pro zápatí stránky -->
        <fo:region-after extent="10mm" region-name="suda-paticka-region"/>
      </fo:simple-page-master>

      <!-- Definice layoutu první stránky bez záhlaví -->
      <fo:simple-page-master master-name="licha"
        page-height="297mm" page-width="210mm" margin="1in">
  
        <!-- Tiskové zrcadlo - oblast pro samotný obsah stránky -->
        <fo:region-body margin-bottom="15mm" margin-top="15mm"/>        
        
        <!-- Oblast pro záhlaví stránky -->
        <fo:region-before extent="10mm"/>
        
        <!-- Oblast pro zápatí stránky -->
        <fo:region-after extent="10mm" region-name="licha-paticka-region"/>
      </fo:simple-page-master>

      <!-- Sekvence stránek, kde první nemá záhlaví -->
      <fo:page-sequence-master master-name="katalog">
        <fo:repeatable-page-master-alternatives>
          <fo:conditional-page-master-reference master-reference="suda"
            odd-or-even="even"/>
          <fo:conditional-page-master-reference master-reference="licha"
            odd-or-even="odd"/>
        </fo:repeatable-page-master-alternatives>
      </fo:page-sequence-master>
      
    </fo:layout-master-set>
    
    <!-- Definice obsahu stránky -->
    <fo:page-sequence master-reference="katalog" id="doc">
      <!-- Obsah sudých stránek v zápatí -->
      <fo:static-content flow-name="suda-paticka-region">
        <fo:block text-align="left">
          <fo:page-number/>
          <xsl:text>/</xsl:text>
          <fo:page-number-citation-last ref-id="doc"/>
        </fo:block>
      </fo:static-content>

      <!-- Obsah lichých stránek v zápatí -->
      <fo:static-content flow-name="licha-paticka-region">
        <fo:block text-align="right">
          <fo:page-number/>
          <xsl:text>/</xsl:text>
          <fo:page-number-citation-last ref-id="doc"/>
        </fo:block>
      </fo:static-content>
      
      <!-- Společný obsah všech stránek v záhlaví stránky -->
      <fo:static-content flow-name="xsl-region-before">
        <fo:block text-align-last="justify">
          Katalog <xsl:value-of select="/katalog/info/firma"/>
          <fo:leader leader-pattern="space"/>
          Období: <xsl:value-of select="/katalog/info/obdobi"/>
        </fo:block>
      </fo:static-content>

      <!-- Samotný text dokumentu -->
      <fo:flow flow-name="xsl-region-body" 
               font-family="Arial,Helvetica,sans-serif"
               font-size="12pt">

        <!-- Zpracování všech elementů zdrojového dokumentu -->
        <xsl:apply-templates/>

      </fo:flow>
    </fo:page-sequence>
  </fo:root>
</xsl:template>

</xsl:stylesheet>

6.2 Citáty

Příklad demonstruje:

  • využití základních formátovacích objektů;

  • číslování stran;

  • podmíněný výběr předlohy stránky;

  • vytváření obsahu;

  • vytváření křížových odkazů;

  • vytvoření záložek pro PDF;

  • sazbu do více sloupců;

  • živá záhlaví;

  • generování rejstříku;

  • vložení vodoznaku;

  • vytváření poznámek pod čarou.

Příklad 6.5. Citáty – citaty.xml

<?xml version="1.0" encoding="windows-1250"?>
<citaty>

<citat>
  <text>Absolutní hodnota člověka je v mozku. Skutečná cena v charakteru.</text>
  <autor>FONTANA, I.</autor>
</citat>

<citat>
  <text>Adam - jediný šťastlivec, který neměl tchýni.</text>
  <autor>ŠOLOM, ALEJCHEM</autor>
</citat>

<citat>
  <text>Agitátor přemlouvá jenom hloupějšího člověka než je sám.</text>
  <autor>VYMAZAL, FRANTIŠEK</autor>
</citat>

<citat>
  <text>Alkohol je náš úhlavní nepřítel, nemáme však milovat své nepřátele jako své bližní?</text>
  <autor>N. N.</autor>
</citat>

...

</citaty>

Příklad 6.6. Formátování citátů – citaty.xsl

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

<!-- Často používané formátovací vlastnosti -->
<xsl:attribute-set name="zakladni.format">
  <xsl:attribute name="font-family">Arial,Helvetica,sans-serif</xsl:attribute>
  <xsl:attribute name="font-size">9pt</xsl:attribute>
  <xsl:attribute name="line-height">11pt</xsl:attribute>
</xsl:attribute-set>

<!-- Základní šablona -->
<xsl:template match="/">
  <fo:root>
    <!-- Definice layoutu stránky -->
    <fo:layout-master-set>
      <!-- Rozměry stránky a její okraje -->

      <!-- Předloha stránky pro citáty -->
      <fo:simple-page-master master-name="my-page"
        page-height="297mm" page-width="210mm" 
        margin-left="1in" margin-right="1in"
        margin-bottom="1in - 15mm" margin-top="1in - 15mm">
  
        <!-- Tiskové zrcadlo - oblast pro samotný obsah stránky -->
        <fo:region-body margin-bottom="15mm" margin-top="15mm" 
                        column-count="2" column-gap="24pt"/>        
        
        <!-- Oblast pro záhlaví stránky -->
        <fo:region-before extent="10mm"/>
        
        <!-- Oblast pro zápatí stránky -->
        <fo:region-after extent="10mm"/>
      </fo:simple-page-master>

      <!-- Předloha stránky pro obsah -->
      <fo:simple-page-master master-name="obsah"
        page-height="297mm" page-width="210mm" 
        margin-left="1in" margin-right="1in"
        margin-bottom="1in" margin-top="1in">
  
        <!-- Tiskové zrcadlo - oblast pro samotný obsah stránky -->
        <fo:region-body column-count="2" column-gap="24pt"/>        
      </fo:simple-page-master>

    </fo:layout-master-set>

    <!-- Vygenerování záložek -->
    <xsl:call-template name="zalozky"/>

    <!-- Vygenerování obsahu -->
    <xsl:call-template name="obsah"/>

    <!-- Zpracování samotných citátů -->
    <xsl:call-template name="zpracuj.citaty"/>
    
  </fo:root>
</xsl:template>

<xsl:template name="obsah">
  <!-- Obsah je samostatná sekvence stránek -->
  <fo:page-sequence master-reference="obsah" force-page-count="no-force">

    <fo:flow flow-name="xsl-region-body" 
             xsl:use-attribute-sets="zakladni.format">

      <!-- Nadpis dokumentu -->
      <fo:block font-size="200%" text-align="center" 
                space-before="0pt" space-after="24pt"
                span="all" id="obsah">
        Sbírka citátů
      </fo:block>

      <!-- Seskupení a seřazení včech citátů -->
      <xsl:for-each-group select="//citat" group-by="autor">
        <xsl:sort select="autor"/>
        <fo:block text-align-last="justify">
          <fo:basic-link internal-destination="{generate-id(.)}">
            <xsl:value-of select="autor"/>
            <fo:leader leader-pattern="dots"/>
            <fo:page-number-citation ref-id="{generate-id(.)}"/>
          </fo:basic-link>
        </fo:block>
      </xsl:for-each-group>

      <!-- Trik pro vybalancování vícesloupcové sazby -->
      <fo:block span="all"/>

    </fo:flow>
  </fo:page-sequence>
</xsl:template>

<!-- Zpracování citátů -->
<xsl:template name="zpracuj.citaty">
  <!-- Definice obsahu stránky -->
  <fo:page-sequence master-reference="my-page" 
                    initial-page-number="1">
    <!-- Společný obsah všech stránek v zápatí stránky -->
    <fo:static-content flow-name="xsl-region-after" 
                       xsl:use-attribute-sets="zakladni.format">
      <fo:block text-align-last="center">
        <xsl:text>&#x2013; </xsl:text>
        <fo:page-number/>
        <xsl:text> &#x2013;</xsl:text>
      </fo:block>
    </fo:static-content>
    
    <!-- Společný obsah všech stránek v záhlaví stránky -->
    <fo:static-content flow-name="xsl-region-before" 
                       xsl:use-attribute-sets="zakladni.format">
      <fo:block text-align-last="justify">
        <fo:retrieve-marker retrieve-class-name="autor" 
          retrieve-position="first-including-carryover"/>
        <fo:leader leader-pattern="space"/>
        <fo:retrieve-marker retrieve-class-name="autor" 
          retrieve-position="last-starting-within-page"/>
      </fo:block>
    </fo:static-content>
    
    <!-- Samotný text dokumentu -->
    <fo:flow flow-name="xsl-region-body" 
             xsl:use-attribute-sets="zakladni.format"
             font-size="10pt" line-height="12pt">
      
      <!-- Seskupení a seřazení včech citátů -->
      <xsl:for-each-group select="//citat" group-by="autor">
        <xsl:sort select="autor"/>
        <fo:block>
          <fo:marker marker-class-name="autor"><xsl:value-of 
                                                 select="autor"/></fo:marker>
          <fo:block font-weight="bold" text-align="center" 
                    space-before="12pt" keep-with-next="always"
                    id="{generate-id()}">
            <xsl:value-of select="autor"/>
          </fo:block>
          <!-- Zpracování všech citátů jednoho autora -->
          <xsl:for-each select="current-group()">
            <xsl:sort select="text"/>
            <fo:block language="cs" hyphenate="true"
                      text-align="justify" text-align-last="center"
                      space-before="6pt" space-after="6pt"
                      id="{generate-id(text)}">
              <xsl:value-of select="text"/>
            </fo:block>
          </xsl:for-each>
        </fo:block>
      </xsl:for-each-group>
    </fo:flow>
  </fo:page-sequence>
</xsl:template>

<!-- Vygenerování záložek -->
<xsl:template name="zalozky">
  <fo:bookmark-tree>
    <fo:bookmark internal-destination="obsah">
      <fo:bookmark-title>Obsah</fo:bookmark-title>
    </fo:bookmark>
    <xsl:for-each-group select="//citat" group-by="autor">
      <xsl:sort select="autor"/>
      <fo:bookmark internal-destination="{generate-id()}" starting-state="hide">
        <fo:bookmark-title>
          <xsl:value-of select="autor"/>
        </fo:bookmark-title>
        <xsl:for-each select="current-group()">
          <xsl:sort select="text"/>
          <fo:bookmark internal-destination="{generate-id(text)}">
            <fo:bookmark-title>
              <xsl:value-of select="text"/>
            </fo:bookmark-title>
          </fo:bookmark>
        </xsl:for-each>
      </fo:bookmark>
    </xsl:for-each-group>    
  </fo:bookmark-tree>
</xsl:template>

</xsl:stylesheet>

Příklad 6.7. Formátování citátů a vytvoření rejstříku – citaty-tabulka.xsl

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
		            xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:fo="http://www.w3.org/1999/XSL/Format">
  
<!-- Mohou se používat nové objekty pro lepší tvorbu rejstříků z XSL-FO 1.1? -->
<xsl:param name="xsl11" select="true()"/>

<!-- Základní šablona -->
<xsl:template match="/">
  <fo:root>
    <!-- Definice layoutu stránky -->
    <fo:layout-master-set>
      <!-- Rozměry stránky a její okraje -->

      <!-- Předloha stránky pro citáty -->
      <fo:simple-page-master master-name="my-page"
        page-height="297mm" page-width="210mm" 
        margin="1in" margin-bottom="1in - 10mm">
  
        <fo:region-body margin-bottom="10mm"/>        
        <fo:region-after extent="10mm"/>
      </fo:simple-page-master>

      <!-- Předloha stránky pro rejstřík -->
      <fo:simple-page-master master-name="rejstrik"
        page-height="297mm" page-width="210mm" 
        margin-left="1in" margin-right="1in"
        margin-bottom="1in" margin-top="1in">
  
        <fo:region-body column-count="2" column-gap="24pt"/>        
      </fo:simple-page-master>

    </fo:layout-master-set>

    <fo:page-sequence master-reference="my-page">

      <fo:static-content flow-name="xsl-region-after">
        <fo:block text-align-last="center">
          <xsl:text>&#x2013; </xsl:text>
          <fo:page-number/>
          <xsl:text> &#x2013;</xsl:text>
        </fo:block>
      </fo:static-content>
      
      <fo:flow flow-name="xsl-region-body">
        
        <fo:table border="solid 1pt" border-after-width.conditionality="retain">
          <fo:table-column column-width="30%"/>
          <fo:table-column column-width="70%"/>
          <fo:table-header>
            <fo:table-row font-weight="bold">
              <fo:table-cell padding="3pt" border-style="solid" 
                             border-width="1pt 1pt 1pt 0pt">
                <fo:block>
                  Autor
                </fo:block>
              </fo:table-cell>
              <fo:table-cell padding="3pt" border-style="solid" 
                             border-width="1pt 0pt 1pt 0pt">
                <fo:block>
                  Text
                </fo:block>
              </fo:table-cell>
            </fo:table-row>
          </fo:table-header>
          <fo:table-body>
            <xsl:for-each select="citaty/citat">
              <fo:table-row>
                <fo:table-cell padding="3pt" border-style="solid" 
                               border-width="0pt 1pt 0pt 0pt">
                  <fo:block id="{generate-id()}">
                    <xsl:if test="$xsl11">
                      <xsl:attribute name="index-key" select="autor"/>
                    </xsl:if>
                    <xsl:value-of select="autor"/>
                  </fo:block>
                </fo:table-cell>
                <fo:table-cell padding="3pt">
                  <fo:block>
                    <xsl:value-of select="text"/>
                  </fo:block>
                </fo:table-cell>
              </fo:table-row>
            </xsl:for-each>
          </fo:table-body>
        </fo:table>
        
      </fo:flow>
    </fo:page-sequence>

    <fo:page-sequence master-reference="rejstrik">

      <fo:static-content flow-name="xsl-region-after">
        <fo:block text-align-last="center">
          <xsl:text>&#x2013; </xsl:text>
          <fo:page-number/>
          <xsl:text> &#x2013;</xsl:text>
        </fo:block>
      </fo:static-content>
      
      <fo:flow flow-name="xsl-region-body">

        <fo:block font-size="200%" space-after="12pt">
          Rejstřík
        </fo:block>

        <!-- Seskupení citátů podle prvního písmene jejich autora -->
        <xsl:for-each-group select="citaty/citat" group-by="substring(autor, 1, 1)">
          <xsl:sort select="current-grouping-key()" lang="cs"/>
          
          <!-- Nové písmeno -->
          <fo:block space-before="12pt" space-after="6pt" 
                   keep-with-next="always" font-weight="bold">
           &#x2013;
           <xsl:value-of select="current-grouping-key()"/>
           &#x2013;
          </fo:block>
          
          <!-- Seskupení citátů s autorem na dané písmeno podle autora -->
          <xsl:for-each-group select="current-group()" group-by="autor">
            <xsl:sort select="current-grouping-key()" lang="cs"/>
            <fo:block text-align="left" start-indent="1em" 
                      text-indent="-1em">
              <!-- Vypsání jména autora -->
              <xsl:value-of select="current-grouping-key()"/>,
              <xsl:choose>                
                <xsl:when test="$xsl11">
                  <fo:index-page-citation-list merge-sequential-page-numbers="merge">
                    <fo:index-key-reference ref-index-key="{current-grouping-key()}"
                                            page-number-treatment="link"/>
                  </fo:index-page-citation-list>                  
                </xsl:when>
                <xsl:otherwise>
                  <!-- Výběr všech citátů od daného autora -->
                  <xsl:for-each select="current-group()">
                    <fo:basic-link internal-destination="{generate-id()}">
                      <fo:page-number-citation ref-id="{generate-id()}"/>
                    </fo:basic-link>
                    <xsl:if test="position() != last()">
                      <xsl:text>, </xsl:text>
                    </xsl:if>
                  </xsl:for-each>
                </xsl:otherwise>
              </xsl:choose>
            </fo:block>
          </xsl:for-each-group>

        </xsl:for-each-group>

      </fo:flow>
    </fo:page-sequence>

  </fo:root>
</xsl:template>

</xsl:stylesheet>

Příklad 6.8. Formátování citátů a vytvoření rejstříku podle českých zvyklostí – citaty-tabulka-cesky.xsl

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
		            xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:fo="http://www.w3.org/1999/XSL/Format"
                xmlns:i="urn:cz-kosek:functions:index"
                xmlns:l="urn:cz-kosek:data:index"
                xmlns:xs="http://www.w3.org/2001/XMLSchema">
  
<!-- Mohou se používat nové objekty pro lepší tvorbu rejstříků z XSL-FO 1.1? -->
<xsl:param name="xsl11" select="true()"/>
  
<!-- Atribut i odpovídá pořadí v rejstříku. Písmena se stejným pořadím 
     se řadí do stejné skupiny v rejstříku -->
<l:letters>
  <l i="0">Symboly</l>
  <l i="1">A</l>
  <l i="1">a</l>
  <l i="1">Á</l>
  <l i="1">á</l>
  <l i="2">B</l>
  <l i="2">b</l>
  <l i="3">C</l>
  <l i="3">c</l>
  <l i="4">Č</l>
  <l i="4">č</l>
  <l i="5">D</l>
  <l i="5">d</l>
  <l i="5">Ď</l>
  <l i="5">ď</l>
  <l i="7">E</l>
  <l i="7">e</l>
  <l i="7">É</l>
  <l i="7">é</l>
  <l i="7">Ě</l>
  <l i="7">ě</l>
  <l i="7">Ë</l>
  <l i="7">ë</l>
  <l i="8">F</l>
  <l i="8">f</l>
  <l i="9">G</l>
  <l i="9">g</l>
  <l i="10">H</l>
  <l i="10">h</l>
  <l i="11">Ch</l>
  <l i="11">ch</l>
  <l i="11">cH</l>
  <l i="11">CH</l>
  <l i="12">I</l>
  <l i="12">i</l>
  <l i="12">Í</l>
  <l i="12">í</l>
  <l i="13">J</l>
  <l i="13">j</l>
  <l i="14">K</l>
  <l i="14">k</l>
  <l i="15">L</l>
  <l i="15">l</l>
  <l i="16">M</l>
  <l i="16">m</l>
  <l i="17">N</l>
  <l i="17">n</l>
  <l i="17">Ň</l>
  <l i="17">ň</l>
  <l i="19">O</l>
  <l i="19">o</l>
  <l i="19">Ó</l>
  <l i="19">ó</l>
  <l i="19">Ö</l>
  <l i="19">ö</l>
  <l i="20">P</l>
  <l i="20">p</l>
  <l i="21">Q</l>
  <l i="21">q</l>
  <l i="22">R</l>
  <l i="22">r</l>
  <l i="23">Ř</l>
  <l i="23">ř</l>
  <l i="24">S</l>
  <l i="24">s</l>
  <l i="25">Š</l>
  <l i="25">š</l>
  <l i="26">T</l>
  <l i="26">t</l>
  <l i="26">Ť</l>
  <l i="26">ť</l>
  <l i="28">U</l>
  <l i="28">u</l>
  <l i="28">Ú</l>
  <l i="28">ú</l>
  <l i="28">Ů</l>
  <l i="28">ů</l>
  <l i="28">Ü</l>
  <l i="28">ü</l>
  <l i="29">V</l>
  <l i="29">v</l>
  <l i="30">W</l>
  <l i="30">w</l>
  <l i="31">X</l>
  <l i="31">x</l>
  <l i="32">Y</l>
  <l i="32">y</l>
  <l i="32">Ý</l>
  <l i="32">ý</l>
  <l i="33">Z</l>
  <l i="33">z</l>
  <l i="34">Ž</l>
  <l i="34">ž</l>
</l:letters>

<!-- Funkce vrací číselný kód prvního písmena z předaného parametru -->
<xsl:function name="i:group-index" as="xs:integer">
  <xsl:param name="term"/>
  <xsl:variable name="long-letter-index" select="document('')/*/l:letters/l[. = substring($term,1,2)]/@i" as="xs:integer?"/>
  <xsl:variable name="short-letter-index" select="document('')/*/l:letters/l[. = substring($term,1,1)]/@i" as="xs:integer?"/>
  <xsl:variable name="letter-index">
    <xsl:choose>
      <xsl:when test="$long-letter-index">
        <xsl:sequence select="$long-letter-index"/>
      </xsl:when>
      <xsl:when test="$short-letter-index">
        <xsl:sequence select="$short-letter-index"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:message>
          No match for: <xsl:value-of select="$term"/>
        </xsl:message>
        <xsl:sequence select="0"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  <xsl:sequence select="xs:integer($letter-index)"/>
</xsl:function>

<!-- Vrací písmenko odpovídající kódu -->
<xsl:function name="i:group-letter">
  <xsl:param name="index"/>
  <xsl:value-of select="document('')/*/l:letters/l[@i=$index][1]"/>
</xsl:function>

<!-- Základní šablona -->
<xsl:template match="/">
  <fo:root font-family="sans-serif">
    <!-- Definice layoutu stránky -->
    <fo:layout-master-set>
      <!-- Rozměry stránky a její okraje -->

      <!-- Předloha stránky pro citáty -->
      <fo:simple-page-master master-name="my-page"
        page-height="297mm" page-width="210mm" 
        margin="1in" margin-bottom="1in - 10mm">
  
        <fo:region-body margin-bottom="10mm"/>        
        <fo:region-after extent="10mm"/>
      </fo:simple-page-master>

      <!-- Předloha stránky pro rejstřík -->
      <fo:simple-page-master master-name="rejstrik"
        page-height="297mm" page-width="210mm" 
        margin-left="1in" margin-right="1in"
        margin-bottom="1in" margin-top="1in">
  
        <fo:region-body column-count="2" column-gap="24pt"/>        
      </fo:simple-page-master>

    </fo:layout-master-set>

    <fo:page-sequence master-reference="my-page">

      <fo:static-content flow-name="xsl-region-after">
        <fo:block text-align-last="center">
          <xsl:text>&#x2013; </xsl:text>
          <fo:page-number/>
          <xsl:text> &#x2013;</xsl:text>
        </fo:block>
      </fo:static-content>
      
      <fo:flow flow-name="xsl-region-body">
        
        <fo:table border="solid 1pt" border-after-width.conditionality="retain">
          <fo:table-column column-width="30%"/>
          <fo:table-column column-width="70%"/>
          <fo:table-header>
            <fo:table-row font-weight="bold">
              <fo:table-cell padding="3pt" border-style="solid" 
                             border-width="1pt 1pt 1pt 0pt">
                <fo:block>
                  Autor
                </fo:block>
              </fo:table-cell>
              <fo:table-cell padding="3pt" border-style="solid" 
                             border-width="1pt 0pt 1pt 0pt">
                <fo:block>
                  Text
                </fo:block>
              </fo:table-cell>
            </fo:table-row>
          </fo:table-header>
          <fo:table-body>
            <xsl:for-each select="citaty/citat">
              <fo:table-row>
                <fo:table-cell padding="3pt" border-style="solid" 
                               border-width="0pt 1pt 0pt 0pt">
                  <fo:block id="{generate-id()}">
                    <xsl:if test="$xsl11">
                      <xsl:attribute name="index-key" select="autor"/>
                    </xsl:if>
                    <xsl:value-of select="autor"/>
                  </fo:block>
                </fo:table-cell>
                <fo:table-cell padding="3pt">
                  <fo:block>
                    <xsl:value-of select="text"/>
                  </fo:block>
                </fo:table-cell>
              </fo:table-row>
            </xsl:for-each>
          </fo:table-body>
        </fo:table>
        
      </fo:flow>
    </fo:page-sequence>

    <fo:page-sequence master-reference="rejstrik">

      <fo:static-content flow-name="xsl-region-after">
        <fo:block text-align-last="center">
          <xsl:text>&#x2013; </xsl:text>
          <fo:page-number/>
          <xsl:text> &#x2013;</xsl:text>
        </fo:block>
      </fo:static-content>
      
      <fo:flow flow-name="xsl-region-body">

        <fo:block font-size="200%" space-after="12pt">
          Rejstřík
        </fo:block>

        <!-- Výběr všech písmen, na které začíná nějaké heslo -->
        <xsl:for-each-group select="//citat" group-by="i:group-index(autor)">
         <xsl:sort select="current-grouping-key()"/>
         
         <!-- Nové písmeno -->
         <fo:block space-before="12pt" space-after="6pt" 
                   keep-with-next="always" font-weight="bold">
           &#x2013;
           <xsl:value-of select="i:group-letter(current-grouping-key())"/>
           &#x2013;
         </fo:block>
         
         <!-- Výběr všech unikátních autorů, kteří začínají na dané písmeno -->
         <xsl:for-each-group select="current-group()" group-by="autor">
           <xsl:sort select="current-grouping-key()" lang="cs"/>
            <fo:block text-align="left" start-indent="1em" 
                      text-indent="-1em">
              <xsl:value-of select="current-grouping-key()"/>,

              <xsl:choose>
                <xsl:when test="$xsl11">
                  <fo:index-page-citation-list merge-sequential-page-numbers="merge">
                    <fo:index-key-reference ref-index-key="{current-grouping-key()}"/>
                  </fo:index-page-citation-list>                  
                </xsl:when>
                <xsl:otherwise>
                  <!-- Výběr všech citátů od daného autora -->
                  <xsl:for-each select="current-group()">
                    <fo:basic-link internal-destination="{generate-id()}">
                      <fo:page-number-citation ref-id="{generate-id()}"/>
                    </fo:basic-link>
                    <xsl:if test="position() != last()">
                      <xsl:text>, </xsl:text>
                    </xsl:if>
                  </xsl:for-each>
                </xsl:otherwise>
              </xsl:choose>

            </fo:block>
          </xsl:for-each-group>

        </xsl:for-each-group>

      </fo:flow>
    </fo:page-sequence>

  </fo:root>
</xsl:template>

</xsl:stylesheet>

Příklad 6.9. Vytváření poznámek pod čarou – citaty-poznamky.xsl

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
            		xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:fo="http://www.w3.org/1999/XSL/Format">
  
<!-- Základní šablona -->
<xsl:template match="/">
  <fo:root>
    <!-- Definice layoutu stránky -->
    <fo:layout-master-set>
      <!-- Rozměry stránky a její okraje -->

      <!-- Předloha stránky pro citáty -->
      <fo:simple-page-master master-name="my-page"
        page-height="297mm" page-width="210mm" 
        margin="1in" margin-bottom="1in - 10mm">
  
        <!-- Vložení vodoznaku jako obrázku na pozadí -->
        <fo:region-body margin-bottom="10mm"
                        background-image="url(vodoznak.pdf)"
                        background-position-horizontal="center"
                        background-position-vertical="center"
                        background-repeat="no-repeat"
                        background-attachment="fixed"/>
        
        <fo:region-after extent="10mm"/>
      </fo:simple-page-master>

    </fo:layout-master-set>

    <fo:page-sequence master-reference="my-page">

      <fo:static-content flow-name="xsl-region-after">
        <fo:block text-align-last="center">
          <xsl:text>&#x2013; </xsl:text>
          <fo:page-number/>
          <xsl:text> &#x2013;</xsl:text>
        </fo:block>
      </fo:static-content>

      <!-- Vzhled oddělovače poznámek pod čarou -->
      <fo:static-content flow-name="xsl-footnote-separator">
        <fo:block>
          <fo:leader leader-length="42%" rule-style="solid" leader-pattern="rule"/>
        </fo:block>
      </fo:static-content>
      
      <fo:flow flow-name="xsl-region-body">

        <xsl:for-each select="citaty/citat">
          <fo:block space-after="6pt">
            <xsl:value-of select="text"/>
            <fo:footnote>
              <fo:inline font-size="70%" 
                         baseline-shift="super"><xsl:number/></fo:inline>
              <fo:footnote-body>
                <fo:block>
                  <fo:inline font-size="70%" 
                             baseline-shift="super"><xsl:number/></fo:inline>
                  <xsl:value-of select="autor"/>
                </fo:block>
              </fo:footnote-body>
            </fo:footnote>
          </fo:block>
        </xsl:for-each>

      </fo:flow>
    </fo:page-sequence>

  </fo:root>
</xsl:template>

</xsl:stylesheet>

6.3 Faktura

Příklad demonstruje:

  • využití základních formátovacích objektů;

  • formátování tabulek;

  • využití značek v tabulkách pro dynamické záhlaví/zápatí tabulky.

Příklad 6.10. Faktura v XML – faktura.xml

<?xml version="1.0" encoding="utf-8"?>
<faktura cislo="12/2000" vystaveni="2.2.2000" splatnost="16.2.2000">
  <odberatel>
    <nazev>Poučená, a.s.</nazev>
    <adresa>Široká 21, Praha 1, 110 00</adresa>
    <ico>0987654321</ico>
    <dic>007-0987654321</dic>
  </odberatel>
  <dodavatel>
    <nazev>XMLCompany, s.r.o.</nazev>
    <adresa>Dlouhá 12, Praha 1, 110 00</adresa>
    <ico>1234567890</ico>
    <dic>007-1234567890</dic>
  </dodavatel>
  <polozka>
    <popis>Analýza nasazení XML v podnikovém IS</popis>
    <cena dph="5">50000</cena>
  </polozka>
  <polozka>
    <popis>XML Editor - 10 licencí</popis>
    <cena dph="5">128956</cena>
  </polozka>
  <polozka>
    <popis>Notebook microMini</popis>
    <cena dph="22">89500</cena>
  </polozka>
</faktura>

Příklad 6.11. Formátování faktury – faktura.xsl

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

<xsl:template match="/">
  <fo:root>
    <!-- Definice layoutu stránky -->
    <fo:layout-master-set>
      <!-- Rozměry stránky a její okraje -->
      <fo:simple-page-master master-name="my-page"
        page-height="297mm" page-width="210mm" margin="1in">
        <!-- Tiskové zrcadlo - oblast pro samotný obsah stránky -->
        <fo:region-body/>        
      </fo:simple-page-master>
    </fo:layout-master-set>
    
    <!-- Definice obsahu stránky -->
    <fo:page-sequence master-reference="my-page">
      <!-- Samotný text dokumentu -->
      <fo:flow flow-name="xsl-region-body" 
               font-family="Arial,Helvetica,sans-serif"
               font-size="12pt">

        <!-- Zpracování všech elementů zdrojového dokumentu -->
        <xsl:apply-templates/>

      </fo:flow>
    </fo:page-sequence>
  </fo:root>
</xsl:template>

<!-- Formátovací vlastnosti pro buňku tabulky -->
<xsl:attribute-set name="bunka.datum">
  <xsl:attribute name="padding">2pt</xsl:attribute>
  <xsl:attribute name="text-align">center</xsl:attribute>
  <xsl:attribute name="border-style">solid</xsl:attribute>
  <xsl:attribute name="border-width">1pt</xsl:attribute>
</xsl:attribute-set>

<!-- Šablona pro celou fakturu -->
<xsl:template match="faktura">
  <fo:table width="100%" border-width="1pt" border-after-width="0pt"
            border-collapse="collapse">
    <fo:table-column column-width="50%"/>
    <fo:table-column column-width="50%"/>
    <fo:table-body>
      <fo:table-row>
        <fo:table-cell padding="4pt" font-size="150%" 
                       font-weight="bold" display-align="after">
          <fo:block>Faktura &#x2013; daňový doklad</fo:block>
        </fo:table-cell>
        <fo:table-cell padding="4pt" text-align="right" 
                       display-align="after">
          <fo:block>
            Číslo:
            <xsl:value-of select="@cislo"/>
          </fo:block>
        </fo:table-cell>
      </fo:table-row>
      <fo:table-row>
        <fo:table-cell padding="4pt" border-style="solid" 
                       border-width="1pt">
          <xsl:apply-templates select="dodavatel"/>
        </fo:table-cell>
        <fo:table-cell padding="4pt" border-style="solid" 
                       border-width="1pt">
          <xsl:apply-templates select="odberatel"/>
        </fo:table-cell>
      </fo:table-row>
      <fo:table-row>
        <fo:table-cell border-style="solid" number-columns-spanned="2"
                       border-after-width="0pt"          
                       border-width="from-parent()">
          <fo:table width="100%" font-size="8pt">
            <fo:table-column column-width="proportional-column-width(1)"/>
            <fo:table-column column-width="proportional-column-width(1)"/>
            <fo:table-column column-width="proportional-column-width(1)"/>
            <fo:table-body>
              <fo:table-row>
                <fo:table-cell xsl:use-attribute-sets="bunka.datum">
                  <fo:block>
                    Datum vystavení: 
                    <xsl:value-of select="@vystaveni"/>
                  </fo:block>
                </fo:table-cell>
                <fo:table-cell xsl:use-attribute-sets="bunka.datum">
                  <fo:block>
                    Datum zdanitelného plnění: 
                    <xsl:value-of select="@vystaveni"/>
                  </fo:block>
                </fo:table-cell>
                <fo:table-cell xsl:use-attribute-sets="bunka.datum">
                  <fo:block>
                    Datum splatnosti: <xsl:value-of select="@splatnost"/>
                  </fo:block>
                </fo:table-cell>
              </fo:table-row>
            </fo:table-body>
          </fo:table>
        </fo:table-cell>
      </fo:table-row>
    </fo:table-body>
  </fo:table>
  
  <!-- Vypsání všech položek -->
  <fo:table width="100%" font-size="10pt" 
    border-style="solid" border-width="1pt">
    <fo:table-column column-width="proportional-column-width(3)"/>
    <fo:table-column column-width="proportional-column-width(10)"/>
    <fo:table-column column-width="proportional-column-width(2)"/>
    <fo:table-column column-width="proportional-column-width(5)"/>
    <fo:table-body>
      <fo:table-row text-align="center" font-weight="bold">
        <fo:table-cell>
          <fo:block/>
        </fo:table-cell>
        <fo:table-cell>
          <fo:block>Popis</fo:block>
        </fo:table-cell>
        <fo:table-cell>
          <fo:block>DPH</fo:block>
        </fo:table-cell>
        <fo:table-cell>
          <fo:block>Cena</fo:block>
        </fo:table-cell>
      </fo:table-row>
      <xsl:apply-templates select="polozka"/>
      <fo:table-row>
        <fo:table-cell number-columns-spanned="4">
          <fo:block><fo:leader/></fo:block>
        </fo:table-cell>
      </fo:table-row>
      <fo:table-row>
        <fo:table-cell>
          <fo:block/>
        </fo:table-cell>
        <fo:table-cell number-columns-spanned="2">
          <fo:block font-weight="bold">
            Celkem:
          </fo:block>
        </fo:table-cell>
        <fo:table-cell text-align="right" padding-right="1cm">
          <fo:block font-weight="bold">
            <xsl:value-of select="format-number(
                                    sum(for $p in polozka 
                                        return $p/cena * (1 + ($p/cena/@dph div 100))),
                                    '#,##0.00')"/></fo:block>
        </fo:table-cell>
      </fo:table-row>
    </fo:table-body>
  </fo:table>
</xsl:template>

<xsl:template match="dodavatel">
  <fo:block>
    <fo:block font-weight="bold">
      Dodavatel:
    </fo:block>
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<xsl:template match="odberatel">
  <fo:block>
    <fo:block font-weight="bold">
      Odběratel:
    </fo:block>
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<xsl:template match="nazev|adresa">
  <fo:block>
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<xsl:template match="ico">
  <fo:block>
    IČO: 
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<xsl:template match="dic">
  <fo:block>
    DIČ:
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<xsl:template match="polozka">
  <fo:table-row>
    <fo:table-cell padding-left="1cm">
      <fo:block>
        <xsl:value-of select="position()"/>.
      </fo:block>
    </fo:table-cell>
    <xsl:apply-templates select="popis"/>
    <xsl:apply-templates select="cena/@dph"/>
    <xsl:apply-templates select="cena"/>
  </fo:table-row>
</xsl:template>

<xsl:template match="popis">
  <fo:table-cell>
    <fo:block>
      <xsl:apply-templates/>
    </fo:block>
  </fo:table-cell>
</xsl:template>

<xsl:template match="@dph">
  <fo:table-cell text-align="center">
    <fo:block>
      <xsl:value-of select="."/>
      %
    </fo:block>
  </fo:table-cell>
</xsl:template>

<xsl:template match="cena">
  <fo:table-cell text-align="right" padding-right="1cm">
    <fo:block>
      <xsl:value-of select="format-number(., '#,##0.00')"/></fo:block>
  </fo:table-cell>
</xsl:template>

</xsl:stylesheet>

Příklad 6.12. Faktura s mezisoučty a živým zápatím – faktura-mezisoucty.xsl

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

<xsl:template match="/">
  <fo:root>
    <!-- Definice layoutu stránky -->
    <fo:layout-master-set>
      <!-- Rozměry stránky a její okraje -->
      <fo:simple-page-master master-name="my-page"
        page-height="297mm" page-width="210mm" margin="1in">
        <!-- Tiskové zrcadlo - oblast pro samotný obsah stránky -->
        <fo:region-body margin-bottom="15pt"/>
        <!-- Patička pro číslování stran -->
        <fo:region-after extent="10pt"/>        
      </fo:simple-page-master>
    </fo:layout-master-set>
    
    <!-- Definice obsahu stránky -->
    <fo:page-sequence master-reference="my-page">
      <!-- Obsah patičky -->
      <fo:static-content flow-name="xsl-region-after">
        <fo:block text-align="center" font-size="8pt">
          <fo:page-number/>
          <xsl:text>/</xsl:text>
          <fo:page-number-citation-last ref-id="polozky"/>
        </fo:block>
      </fo:static-content>
      
      <!-- Samotný text dokumentu -->
      <fo:flow flow-name="xsl-region-body" 
               font-family="Arial,sans-serif"
               font-size="12pt">

        <!-- Zpracování všech elementů zdrojového dokumentu -->
        <xsl:apply-templates/>

      </fo:flow>
    </fo:page-sequence>
  </fo:root>
</xsl:template>

<!-- Formátovací vlastnosti pro buňku tabulky -->
<xsl:attribute-set name="bunka.datum">
  <xsl:attribute name="padding">2pt</xsl:attribute>
  <xsl:attribute name="text-align">center</xsl:attribute>
  <xsl:attribute name="border-style">solid</xsl:attribute>
  <xsl:attribute name="border-width">1pt</xsl:attribute>
</xsl:attribute-set>

<!-- Šablona pro celou fakturu -->
<xsl:template match="faktura">
  <fo:table width="100%" border-width="1pt" border-after-width="0pt"
            border-collapse="collapse">
    <fo:table-column column-width="50%"/>
    <fo:table-column column-width="50%"/>
    <fo:table-body>
      <fo:table-row>
        <fo:table-cell padding="4pt" font-size="150%" 
                       font-weight="bold" display-align="after">
          <fo:block>Faktura &#x2013; daňový doklad</fo:block>
        </fo:table-cell>
        <fo:table-cell padding="4pt" text-align="right" 
                       display-align="after">
          <fo:block>
            Číslo:
            <xsl:value-of select="@cislo"/>
          </fo:block>
        </fo:table-cell>
      </fo:table-row>
      <fo:table-row>
        <fo:table-cell padding="4pt" border-style="solid" 
                       border-width="1pt">
          <xsl:apply-templates select="dodavatel"/>
        </fo:table-cell>
        <fo:table-cell padding="4pt" border-style="solid" 
                       border-width="1pt">
          <xsl:apply-templates select="odberatel"/>
        </fo:table-cell>
      </fo:table-row>
      <fo:table-row>
        <fo:table-cell border-style="solid" number-columns-spanned="2"
                       border-after-width="0pt"          
                       border-width="from-parent()">
          <fo:table width="100%" font-size="8pt">
            <fo:table-column column-width="proportional-column-width(1)"/>
            <fo:table-column column-width="proportional-column-width(1)"/>
            <fo:table-column column-width="proportional-column-width(1)"/>
            <fo:table-body>
              <fo:table-row>
                <fo:table-cell xsl:use-attribute-sets="bunka.datum">
                  <fo:block>
                    Datum vystavení: 
                    <xsl:value-of select="@vystaveni"/>
                  </fo:block>
                </fo:table-cell>
                <fo:table-cell xsl:use-attribute-sets="bunka.datum">
                  <fo:block>
                    Datum zdanitelného plnění: 
                    <xsl:value-of select="@vystaveni"/>
                  </fo:block>
                </fo:table-cell>
                <fo:table-cell xsl:use-attribute-sets="bunka.datum">
                  <fo:block>
                    Datum splatnosti: <xsl:value-of select="@splatnost"/>
                  </fo:block>
                </fo:table-cell>
              </fo:table-row>
            </fo:table-body>
          </fo:table>
        </fo:table-cell>
      </fo:table-row>
    </fo:table-body>
  </fo:table>
  
  <!-- Vypsání všech položek -->
  <fo:table width="100%" font-size="10pt" 
    border-style="solid" border-width="1pt" 
    id="polozky" border-after-width.conditionality="retain">
    <fo:table-column column-width="proportional-column-width(3)"/>
    <fo:table-column column-width="proportional-column-width(10)"/>
    <fo:table-column column-width="proportional-column-width(2)"/>
    <fo:table-column column-width="proportional-column-width(5)"/>
    <!-- Hlavička se opakuje na každé stránce -->
    <fo:table-header border="solid 1pt black">
      <fo:table-row text-align="center" font-weight="bold">
        <fo:table-cell>
          <fo:block/>
        </fo:table-cell>
        <fo:table-cell>
          <fo:block>Popis</fo:block>
        </fo:table-cell>
        <fo:table-cell>
          <fo:block>DPH</fo:block>
        </fo:table-cell>
        <fo:table-cell>
          <fo:block>Cena</fo:block>
        </fo:table-cell>
      </fo:table-row>      
    </fo:table-header>
    <!-- Patička se také opakuje, obsah si bere ze značek -->
    <fo:table-footer>
      <fo:table-row border="solid 1pt black">
        <fo:table-cell><fo:block/></fo:table-cell>
        <fo:table-cell number-columns-spanned="2">
          <fo:block font-weight="bold">
            <!-- Načtení značky "Mezisoučet"/"Součet" -->
            <fo:retrieve-table-marker retrieve-class-name="mezisoucet-nadpis"
                                      retrieve-position-within-table="last-ending"/>
          </fo:block>
        </fo:table-cell>
        <fo:table-cell text-align="right" padding-right="1cm">
          <fo:block font-weight="bold">
            <!-- Načtení značky se skutečným mezisoučtem -->
            <fo:retrieve-table-marker retrieve-class-name="mezisoucet"
              retrieve-position-within-table="last-ending"/>
          </fo:block>
        </fo:table-cell>
      </fo:table-row>
      <!-- Načtení značky s informací o pokračování tabulky -->
      <fo:retrieve-table-marker retrieve-class-name="pokracovani"
        retrieve-position-within-table="last-ending"/>
    </fo:table-footer>
    <fo:table-body>
      <!-- Inicializace značek na začátku dokumentu -->
      <fo:marker marker-class-name="pokracovani">
        <fo:table-row>
          <fo:table-cell number-columns-spanned="4">
            <fo:block font-style="italic">Tabulka pokračuje na další straně...</fo:block>
          </fo:table-cell>
        </fo:table-row>
      </fo:marker>
      <fo:marker marker-class-name="mezisoucet-nadpis">Mezisoučet</fo:marker>
      
      <!-- Zpracování všech položek -->
      <xsl:apply-templates select="polozka"/>
    </fo:table-body>
  </fo:table>
</xsl:template>

<xsl:template match="dodavatel">
  <fo:block>
    <fo:block font-weight="bold">
      Dodavatel:
    </fo:block>
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<xsl:template match="odberatel">
  <fo:block>
    <fo:block font-weight="bold">
      Odběratel:
    </fo:block>
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<xsl:template match="nazev|adresa">
  <fo:block>
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<xsl:template match="ico">
  <fo:block>
    IČO: 
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<xsl:template match="dic">
  <fo:block>
    DIČ:
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<xsl:template match="polozka">
  <fo:table-row>
    <!-- Vložení značky s aktuálním mezisoučtem -->
    <fo:marker marker-class-name="mezisoucet">
      <xsl:value-of select="format-number(
                              sum(for $p in (.,preceding-sibling::polozka) 
                                  return $p/cena * (1 + ($p/cena/@dph div 100))),
                              '#,##0.00')"/>
      <xsl:text></xsl:text>
    </fo:marker>    
    <!-- Za poslední položkou se mezisoučet měni na součet a tabulka již nebude pokračovat -->
    <xsl:if test="not(following-sibling::polozka)">
      <fo:marker marker-class-name="pokracovani"/>
      <fo:marker marker-class-name="mezisoucet-nadpis">Součet</fo:marker>      
    </xsl:if>
    <fo:table-cell padding-left="1cm">
      <fo:block>
        <xsl:value-of select="position()"/>.
      </fo:block>
    </fo:table-cell>
    <xsl:apply-templates select="popis"/>
    <xsl:apply-templates select="cena/@dph"/>
    <xsl:apply-templates select="cena"/>
  </fo:table-row>
</xsl:template>

<xsl:template match="popis">
  <fo:table-cell>
    <fo:block>
      <xsl:apply-templates/>
    </fo:block>
  </fo:table-cell>
</xsl:template>

<xsl:template match="@dph">
  <fo:table-cell text-align="center">
    <fo:block>
      <xsl:value-of select="."/>
      %
    </fo:block>
  </fo:table-cell>
</xsl:template>

<xsl:template match="cena">
  <fo:table-cell text-align="right" padding-right="1cm">
    <fo:block>
      <xsl:value-of select="format-number(., '#,##0.00')"/></fo:block>
  </fo:table-cell>
</xsl:template>

</xsl:stylesheet>

6.4 SVG a grafy

Příklad demonstruje:

  • dynamické generování SVG.

Příklad 6.13. Statistika prohlížečů – prohlizece.xml

<?xml version="1.0" encoding="utf-8"?>
<prohlizece>
  <klient podil="69.5">IE6</klient>
  <klient podil="6.5">IE5</klient>
  <klient podil="2.4">Opera 7</klient>
  <klient podil="16.6">Mozilla</klient>
  <klient podil="0.2">NN3</klient>
  <klient podil="0.2">NN4</klient>
  <klient podil="1.4">NN7</klient>
</prohlizece>

Příklad 6.14. Generování koláčového grafu – kolacovy-graf.xsl

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:svg="http://www.w3.org/2000/svg"
                xmlns:math="http://exslt.org/math"
                xmlns:b="urn:x-kosek:barvy"
                extension-element-prefixes="math"
                exclude-result-prefixes="b"
                version="1.0"
                xmlns:fo="http://www.w3.org/1999/XSL/Format">

<!-- Konstanta π -->  
<xsl:variable name="pi" select="3.1415926535"/>

<!-- Kódy barev, které se postupně použijí pro jednotlivé výseče grafu -->  
<b:barvy>
  <barva>#FF7D00</barva>
  <barva>#B35800</barva>
  <barva>#FFDFBF</barva>
  <barva>#FFBE80</barva>
  <barva>#006EB0</barva>
  <barva>#004D7B</barva>
  <barva>#BFE7FF</barva>
  <barva>#80CFFF</barva>
  <barva>#320199</barva>
  <barva>#23016B</barva>
  <barva>#D4C0FF</barva>
  <barva>#A980FF</barva>
  <barva>#FFCB00</barva>
  <barva>#B38E00</barva>
  <barva>#FFF2BF</barva>
  <barva>#FFE580</barva>
</b:barvy>

<!-- Celkový počet definovaných barev -->  
<xsl:variable name="pocetBarev" select="count(document('')//b:barvy/barva)"/>

<!-- Hlavní šablona -->  
<xsl:template match="prohlizece">
  <fo:root>
    <!-- Definice layoutu stránky -->
    <fo:layout-master-set>
      <!-- Rozměry stránky a její okraje -->
      <fo:simple-page-master master-name="my-page"
        page-height="297mm" page-width="210mm" margin="1in">
        <!-- Tiskové zrcadlo - oblast pro samotný obsah stránky -->
        <fo:region-body/>        
      </fo:simple-page-master>
    </fo:layout-master-set>
    
    <!-- Definice obsahu stránky -->
    <fo:page-sequence master-reference="my-page">
      <!-- Samotný text dokumentu -->
      <fo:flow flow-name="xsl-region-body" 
        font-family="Arial,Helvetica,sans-serif"
        font-size="12pt">

        <fo:block space-after="2em" color="navy" text-align="center" font-size="200%">
          Statistika prohlížečů
        </fo:block>

        <!-- Vygenerování legendy ke grafu -->
        <fo:float float="end">
          <fo:block width="5cm" border="solid 0.4pt black" padding="1em">
            <fo:block text-align="center" font-weight="bold" space-after="1em">Legenda</fo:block>
            <xsl:for-each select="klient">
              <xsl:variable name="pos" select="position()"/>
              <xsl:variable name="fill" select="document('')//b:barvy/barva[($pos mod $pocetBarev) + 1]"/>
              <fo:block space-before="0.25em" space-after="0.25em">
                <fo:leader leader-pattern="rule" color="{$fill}" 
                           leader-length="10pt" rule-thickness="10pt" alignment-baseline="top"/>
                <fo:leader leader-length="1em"/>
                <xsl:value-of select="."/> (<xsl:value-of select="@podil"/> %)
              </fo:block>
            </xsl:for-each>
          </fo:block>
        </fo:float>
        
        <fo:block>
          <fo:instream-foreign-object>
          <!-- Začátek SVG obrázku -->
            <svg:svg viewBox="0 0 2.1 2.1" width="10cm" height="10cm">
              <svg:g transform="translate(1.05,1.05) scale(1,-1)">
                <xsl:variable name="celkem" select="sum(klient/@podil)"/>
                <xsl:variable name="pomerUhlu" select="2 * $pi div $celkem"/>
                <!-- Pro každý prohlížeč se vygeneruje jedna výseč v grafu -->
                <xsl:for-each select="klient">
                  <xsl:variable name="x1" select="format-number(math:cos(sum(preceding-sibling::klient/@podil) * $pomerUhlu), '0.####')"/>
                  <xsl:variable name="y1" select="format-number(math:sin(sum(preceding-sibling::klient/@podil) * $pomerUhlu), '0.####')"/>
                  <xsl:variable name="x2" select="format-number(math:cos((sum(preceding-sibling::klient/@podil) + @podil) * $pomerUhlu), '0.#####')"/>
                  <xsl:variable name="y2" select="format-number(math:sin((sum(preceding-sibling::klient/@podil) + @podil) * $pomerUhlu), '0.#####')"/>
                  <xsl:variable name="uhel" select="@podil * $pomerUhlu"/>
                  <xsl:variable name="large-arc">
                    <xsl:choose>
                      <xsl:when test="$uhel >= $pi">1</xsl:when>
                      <xsl:otherwise>0</xsl:otherwise>
                    </xsl:choose>
                  </xsl:variable>
                  <xsl:variable name="pos" select="position()"/>
                  <xsl:variable name="fill" select="document('')//b:barvy/barva[($pos mod $pocetBarev) + 1]"/>
                  <svg:path d="M 0,0 L {$x1},{$y1} M {$x1},{$y1} A1,1 0 {$large-arc} 1 {$x2},{$y2} L 0,0" style="stroke:black; stroke-width: 0.005; fill:{$fill}"/>
                </xsl:for-each>
              </svg:g>
            </svg:svg>
          </fo:instream-foreign-object>
        </fo:block>
        
      </fo:flow>
    </fo:page-sequence>
  </fo:root>
</xsl:template>

</xsl:stylesheet>

6.5 Čárové kódy

Příklad demonstruje:

  • využití externích knihoven pro generování čárových kódů jako SVG obrázků.

Příklad 6.15. Dokument s kódy k vysázení – kody.xml

<kody>
  <kod>502905300991</kod>
</kody>

Příklad 6.16. Generování čárových kódů – carovy-kod.xsl

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

<xsl:include href="upc-ean.xsl"/>

<xsl:output method="xml" encoding="utf-8"/>

<xsl:template match="/">
  <fo:root>
    <!-- Definice layoutu stránky -->
    <fo:layout-master-set>
      <!-- Rozměry stránky a její okraje -->
      <fo:simple-page-master master-name="my-page"
                             page-height="297mm" 
                             page-width="210mm" 
                             margin="1in">
        <!-- Tiskové zrcadlo - oblast pro samotný obsah stránky -->
        <fo:region-body/>        
      </fo:simple-page-master>
    </fo:layout-master-set>
    
    <!-- Definice obsahu stránky -->
    <fo:page-sequence master-reference="my-page">
      <!-- Samotný text dokumentu -->
      <fo:flow flow-name="xsl-region-body">
        <!-- Zpracování všech elementů zdrojového dokumentu -->
        <xsl:apply-templates/>
      </fo:flow>
    </fo:page-sequence>
  </fo:root>
</xsl:template>

<xsl:template match="kod">
  <fo:block>
    <fo:instream-foreign-object>
      <xsl:call-template name="barcode-EAN">
        <xsl:with-param name="value" select="."/>
      </xsl:call-template>
    </fo:instream-foreign-object>
  </fo:block>
</xsl:template>

</xsl:stylesheet>

© Jiří Kosek 2014

Tento dokument je určen výhradně pro osobní potřebu seznámení se s technologií XSL-FO. 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.

Dokument je zkrácenou verzí školicích materiálů používaných během školení XSL-FO.


Copyright © 2002-2015 Jiří Kosek