Python-Ref > Mimo python > XSLT > Číslování elementů v dokumentu
 
 

<-^^->
Klíčová slova
Moduly
Knihovní funkce

Číslování elementů v dokumentu

V jednoduchých případech lze pro číslování elemementů použít funkci position. Ta však vrací číselnou pozici aktuálně zpracovávaného prvku relativně k právě zpracovávané skupině prvků, nikoli vzhledem k jejich pozici v dokumentu.
Tato skutečnost je demonstrována na následujících příkladech, které dělají zdánlivě totéž, ale jiným způsobem.
Expand/Shrink
<institution>
  <department>
    <person><name>John</name></person>
    <person><name>Jerry</name></person>
    <person><name>Alice</name></person>
  </department>
  <department>
    <person><name>Henry</name></person>
  </department>
  <department>
    <person><name>Peter</name></person>
    <person><name>David</name></person>
  </department>
</institution>
Zdroj: (xslt2-1.xslt)
  1   <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  2   
  3     <xsl:output indent="yes"/>
  4   
  5     <xsl:template match="institution">
  6       <output1>
  7         <xsl:for-each select="department/person">
  8           <record>
  9             <number><xsl:value-of select="position()"/></number>
 10             <name><xsl:value-of select="name"/></name>
 11           </record>
 12         </xsl:for-each>
 13       </output1>
 14       <output2>
 15         <xsl:for-each select="department">
 16           <xsl:for-each select="person">
 17             <record>
 18               <number><xsl:value-of select="position()"/></number>
 19               <name><xsl:value-of select="name"/></name>
 20             </record>
 21           </xsl:for-each>
 22         </xsl:for-each>
 23       </output2>
 24       <output3>
 25         <xsl:for-each select="department/person">
 26           <xsl:apply-templates select="."/>
 27         </xsl:for-each>
 28       </output3>
 29     </xsl:template>
 30   
 31     <xsl:template match="person">
 32       <record>
 33         <number><xsl:value-of select="position()"/></number>
 34         <name><xsl:value-of select="name"/></name>
 35       </record>
 36     </xsl:template>
 37   
 38   </xsl:stylesheet>
stdout:
<?xml version="1.0" encoding="UTF-8"?>
<output1>
   <record>
      <number>1</number>
      <name>John</name>
   </record>
   <record>
      <number>2</number>
      <name>Jerry</name>
   </record>
   <record>
      <number>3</number>
      <name>Alice</name>
   </record>
   <record>
      <number>4</number>
      <name>Henry</name>
   </record>
   <record>
      <number>5</number>
      <name>Peter</name>
   </record>
   <record>
      <number>6</number>
      <name>David</name>
   </record>
</output1>
<output2>
   <record>
      <number>1</number>
      <name>John</name>
   </record>
   <record>
      <number>2</number>
      <name>Jerry</name>
   </record>
   <record>
      <number>3</number>
      <name>Alice</name>
   </record>
   <record>
      <number>1</number>
      <name>Henry</name>
   </record>
   <record>
      <number>1</number>
      <name>Peter</name>
   </record>
   <record>
      <number>2</number>
      <name>David</name>
   </record>
</output2>
<output3>
   <record>
      <number>1</number>
      <name>John</name>
   </record>
   <record>
      <number>1</number>
      <name>Jerry</name>
   </record>
   <record>
      <number>1</number>
      <name>Alice</name>
   </record>
   <record>
      <number>1</number>
      <name>Henry</name>
   </record>
   <record>
      <number>1</number>
      <name>Peter</name>
   </record>
   <record>
      <number>1</number>
      <name>David</name>
   </record>
</output3>
Doba běhu: 348.7 ms
Co je asi ještě horší, je fakt, že i pokud budeme konzistentně používat apply-templates, nemusíme se tohoto problému vyvarovat. Navíc se tím často chyba stane méně zřejmou.
Expand/Shrink
<institution>
  <department>
    <person><name>John</name></person>
    <person><name>Jerry</name></person>
    <person><name>Alice</name></person>
  </department>
  <department>
    <person><name>Henry</name></person>
  </department>
  <department>
    <person><name>Peter</name></person>
    <person><name>David</name></person>
  </department>
</institution>
Zdroj: (xslt2-2.xslt)
  1   <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  2   
  3     <xsl:output indent="yes"/>
  4   
  5     <xsl:template match="institution">
  6       <output1>
  7         <xsl:apply-templates select="department"/>
  8       </output1>
  9       <output2>
 10         <xsl:apply-templates select="department/person"/>
 11       </output2>
 12     </xsl:template>
 13   
 14     <xsl:template match="department">
 15       <xsl:apply-templates select="person"/>
 16     </xsl:template>
 17   
 18     <xsl:template match="person">
 19       <record>
 20         <number><xsl:value-of select="position()"/></number>
 21         <name><xsl:value-of select="name"/></name>
 22       </record>
 23     </xsl:template>
 24   
 25   </xsl:stylesheet>
stdout:
<?xml version="1.0" encoding="UTF-8"?>
<output1>
   <record>
      <number>1</number>
      <name>John</name>
   </record>
   <record>
      <number>2</number>
      <name>Jerry</name>
   </record>
   <record>
      <number>3</number>
      <name>Alice</name>
   </record>
   <record>
      <number>1</number>
      <name>Henry</name>
   </record>
   <record>
      <number>1</number>
      <name>Peter</name>
   </record>
   <record>
      <number>2</number>
      <name>David</name>
   </record>
</output1>
<output2>
   <record>
      <number>1</number>
      <name>John</name>
   </record>
   <record>
      <number>2</number>
      <name>Jerry</name>
   </record>
   <record>
      <number>3</number>
      <name>Alice</name>
   </record>
   <record>
      <number>4</number>
      <name>Henry</name>
   </record>
   <record>
      <number>5</number>
      <name>Peter</name>
   </record>
   <record>
      <number>6</number>
      <name>David</name>
   </record>
</output2>
Doba běhu: 349.4 ms
Řešení toho problému je v použití funkce count na všechny předchozí výskyty stejného elementu, namísto funkce position.
Expand/Shrink
<institution>
  <department>
    <person><name>John</name></person>
    <person><name>Jerry</name></person>
    <person><name>Alice</name></person>
  </department>
  <department>
    <person><name>Henry</name></person>
  </department>
  <department>
    <person><name>Peter</name></person>
    <person><name>David</name></person>
  </department>
</institution>
Zdroj: (xslt2-3.xslt)
  1   <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  2   
  3     <xsl:output indent="yes"/>
  4   
  5     <xsl:template match="institution">
  6       <output1>
  7         <xsl:for-each select="department/person">
  8           <record>
  9             <number><xsl:value-of select="count( preceding::person)+1"/></number>
 10             <name><xsl:value-of select="name"/></name>
 11           </record>
 12         </xsl:for-each>
 13       </output1>
 14       <output2>
 15         <xsl:for-each select="department">
 16           <xsl:for-each select="person">
 17             <record>
 18               <number><xsl:value-of select="count( preceding::person)+1"/></number>
 19               <name><xsl:value-of select="name"/></name>
 20             </record>
 21           </xsl:for-each>
 22         </xsl:for-each>
 23       </output2>
 24       <output3>
 25         <xsl:for-each select="department/person">
 26           <xsl:apply-templates select="."/>
 27         </xsl:for-each>
 28       </output3>
 29     </xsl:template>
 30   
 31     <xsl:template match="person">
 32       <record>
 33         <number><xsl:value-of select="count( preceding::person)+1"/></number>
 34         <name><xsl:value-of select="name"/></name>
 35       </record>
 36     </xsl:template>
 37   
 38   </xsl:stylesheet>
stdout:
<?xml version="1.0" encoding="UTF-8"?>
<output1>
   <record>
      <number>1</number>
      <name>John</name>
   </record>
   <record>
      <number>2</number>
      <name>Jerry</name>
   </record>
   <record>
      <number>3</number>
      <name>Alice</name>
   </record>
   <record>
      <number>4</number>
      <name>Henry</name>
   </record>
   <record>
      <number>5</number>
      <name>Peter</name>
   </record>
   <record>
      <number>6</number>
      <name>David</name>
   </record>
</output1>
<output2>
   <record>
      <number>1</number>
      <name>John</name>
   </record>
   <record>
      <number>2</number>
      <name>Jerry</name>
   </record>
   <record>
      <number>3</number>
      <name>Alice</name>
   </record>
   <record>
      <number>4</number>
      <name>Henry</name>
   </record>
   <record>
      <number>5</number>
      <name>Peter</name>
   </record>
   <record>
      <number>6</number>
      <name>David</name>
   </record>
</output2>
<output3>
   <record>
      <number>1</number>
      <name>John</name>
   </record>
   <record>
      <number>2</number>
      <name>Jerry</name>
   </record>
   <record>
      <number>3</number>
      <name>Alice</name>
   </record>
   <record>
      <number>4</number>
      <name>Henry</name>
   </record>
   <record>
      <number>5</number>
      <name>Peter</name>
   </record>
   <record>
      <number>6</number>
      <name>David</name>
   </record>
</output3>
Doba běhu: 348.8 ms