Processamento de Documentos Estruturados usando StyleSheets (XSL | CSS | DSSSL)

XSL (elementos)

 

xsl:stylesheet

<xsl:stylesheet

  id = id

  version = number

  <!-- Conteúdo: (xsl:import*,elementos-top) -->

</xsl:stylesheet>

 

<xsl:transform

  id = id

  version = number

  <!-- Conteúdo: (xsl:import*,elementos-top) -->

</xsl:transform>


Elementos de topo (filhos de xsl:stylesheet)

·      xsl:import

·      xsl:include

·      xsl:strip-space

·      xsl:preserve-space

·      xsl:output

·      xsl:key

·      xsl:decimal-format

·      xsl:namespace-alias

·      xsl:attribute-set

·      xsl:variable

·      xsl:param

·      xsl:template

Estrutura de uma stylesheet

<xsl:stylesheet version="1.0"

                xmlns:xsl="http:…">

 

  <xsl:import href="…"/>

 

  <xsl:include href="…"/>

 

  <xsl:strip-space elements="…"/>

 

  <xsl:preserve-space elements="…"/>

 

  <xsl:output encoding="…"/>

 

  <xsl:key name="…" match="…" use="…"/>

 

  <xsl:decimal-format name="…"/>

 

  <xsl:namespace-alias stylesheet-prefix="…"

                       result-prefix="…"/>

 

  <xsl:attribute-set name="…">

   

  </xsl:attribute-set>

 

  <xsl:variable name="…">…</xsl:variable>

 

  <xsl:param name="…">…</xsl:param>

 

  <xsl:template match="…">

   

  </xsl:template>

 

  <xsl:template name="…">

   

  </xsl:template>

 

</xsl:stylesheet>

xsl:include (combinação de stylesheets)

<!-- Categoria: elemento de topo -->

<xsl:include

  href = uri-ref />

 

As instruções incluídas têm a mesma prioridade dos filhos de xsl:stylesheet.

xsl:import (combinação de stylesheets)

<!-- Categoria: elemento de topo -->

<xsl:import

  href = uri-ref />

 

Perante uma árvore de importações a prioridade segue uma travessia post-order dessa árvore.

xsl:strip-space

<!-- Categoria: elemento de topo -->

<xsl:strip-space

  elements = "el-id1 el-id2 …" />

 

Remoção de nodos texto com o conteúdo composto por caracteres brancos.

xsl:preserve-space

<!-- Categoria: elemento de topo -->

<xsl:preserve-space

  elements = "el-id1 el-id2 …" />

 

Preservação de nodos texto com o conteúdo composto por caracteres brancos.

xsl:template

<!-- Categoria: elemento de topo -->

<xsl:template

  match = pattern

  name = nomeq

  priority = number

  mode = nomeq>

  <!-- Conteúdo: (xsl:param*,template)

</xsl:template>

Esta regra serve para especificar um template. O atributo match identifica os nodos aos quais o template deverá ser aplicado.

O conteúdo do atributo match é um padrão (pattern) escrito numa linguagem de padrões que se especifica a seguir.

O atributo name serve para associar um nome à template de modo a que esta possa ser invocada como uma sub-rotina.

O atributo priority serve para hierarquizar a aplicação das templates.


Gramática para a linguagem de "Patterns"

Pattern

-->

LocationPathPattern

 

  |

Pattern '|' LocationPathPattern

 

 

 

LocationPathPattern

-->

'/' RelativePathPattern?

 

  |

IdKeyPattern ('/' RelativePathPattern)?

 

  |

IdKeyPattern ('//' RelativePathPattern)?

 

  |

('//')? RelativePathPattern

 

 

 

IdKeyPattern

-->

'id' '(' Literal ')'

 

  |

'key' '('Literal','Literal')'

 

 

 

RelativePathPattern

-->

StepPattern

 

  |

RelativePathPattern '/' StepPattern

 

  |

RelativePathPattern '//' StepPattern

 

 

 

StepPattern

-->

ChildOrAttributeAxisSpecifier NodeTest Predicate*

 

 

 

ChildOrAttributeAxisSpecifier

-->

AbbreviatedAxisSpecifier

 

  |

'child' '::'

 

  |

'attribute' '::'

 


Alguns exemplos

·      p

·      *

·      data | sumario

·      lista/p

·      aula//p

·      /

·      text() - qq nodo texto

·      processing-instruction()

·      node() - qq nodo excepto o nodo raíz e os nodos atributo

·      id("i23") - o elemento com um atributo do tipo ID de valor i23

·      para[1] - qq elemento para que seja o primeiro filho do seu pai

·      *[position() = 1 and self::para] - o mesmo da anterior

·      para[last()=1] - qq para que seja filho único

·      lista/item[position()>1] - qq item filho de lista que não seja o primeiro filho

·      item[position() mod 2 =1] - qq item numa posição ímpar numa lista de filhos

·      aula[@tipo="T"]//p - qq p na descendência de um elemento aula que tenha um atributo tipo com valor "T"

·      @tipo - qq atributo tipo

·      @* - qq atributo

Algumas utilizações do xsl:template

Exemplo1: normal

<xsl:template match="data">

  <h2>

  <xsl:apply-templates/>

  </h2>

</xsl:template>

 

Exemplo2: filtragem

<xsl:template match="aula[@tipo='T']">

  <p>

  <xsl:apply-templates select="sumario"/>

  </p>

</xsl:template>

 

Exemplo 3: extracção de várias partes

<xsl:template match="aula">

  <h2>Aulas Teóricas</h2>

  <ol>

  <xsl:apply-templates select=".[@tipo='T']/sumario"/>

  </ol>

 

  <h2>Aulas Teórico-Práticas</h2>

  <ol>

  <xsl:apply-templates select=".[@tipo='TP']/sumario"/>

  </ol>

</xsl:template>

 


Exemplo 4: Múltiplos processamentos (mode)

<xsl:template match="/">

  <h2>Índice Cronológico</h2>

  <ul>

    <xsl:apply-templates mode="data"/>

  </ul>

  <h2>Sumários de PED</h2>

  <xsl:apply-templates select="sumario"/>

</xsl:template>

 

<xsl:template match="aula" mode="data">

  <li>

    <xsl:value-of select="data"/>

  </li>

</xsl:template>

 

  Templates por omissão

Para nodos elemento e nodo raíz

<xsl:template match="*|/">

  <xsl:apply-templates/>

</xsl:template>

 

Para um determinado modo m

<xsl:template match="*|/" mode="m">

  <xsl:apply-templates mode="m"/>

</xsl:template>

 


Para nodos texto e atributo

<xsl:template match="text()|@*">

  <xsl:value-of select="."/>

</xsl:template>

 

xsl:call-template (invocação directa dum template)

<!-- Categoria: instrução -->

<xsl:call-template

  name = "template-name" >

  <!-- Conteúdo: xsl:with-param* -->

</xsl:call-template>


xsl:element (criar elementos)

<!-- Categoria: instrução -->

<xsl:element

  name = "nome-do-novo-elemento"

  namespace = "uri-ref"

  use-attribute-sets = attribute-set-name*>

  <!-- Conteúdo: template -->

</xsl:element>

Exemplo: transformação da estrutura

<?xml version="1.0"?>

<greeting>Hello world.</greeting>

 

<xsl:template match="/">

  <xsl:element name="ola">

    <xsl:value-of select="."/>

  </xsl:element>

</xsl:template>

 

<ola>Hello world.</ola>

 


xsl:attribute (criar atributos)

<!-- Categoria: instrução -->

<xsl:attribute

  name = "nome-do-novo-atributo"

  namespace = "uri-ref">

  <!-- Conteúdo: template -->

</xsl:attribute>

Exemplo: transformação da estrutura c/ atributos

<?xml version="1.0"?>

<greeting>Hello world.</greeting>

 

<xsl:template match="/">

  <xsl:element name="ola">

    <xsl:attribute name="mensagem">

      simples

    </xsl:attribute>

    <xsl:value-of select="."/>

  </xsl:element>

</xsl:template>

 

<ola mensagem="simples">Hello world.</ola>

 


xsl:attribute-set (criar atributos modularmente)

<!-- Categoria: elemento de topo -->

<xsl:attribute-set

  name = "nome-do-conjunto-atributos"

  use-attribute-sets = attribute-set-name*>

  <!-- Conteúdo: template -->

</xsl:attribute>

Exemplo: transformação da estrutura c/ atributos

<?xml version="1.0"?>

<greeting>Hello world.</greeting>

 

<xsl:attribute-set name="base">

    <xsl:attribute name="mensagem">

      simples

    </xsl:attribute>

    <xsl:attribute name="tipo">

      String

    </xsl:attribute>

</xsl:attribute-set>

<xsl:template match="/">

  <xsl:element name="ola"

               use-attribute-sets="base">

    <xsl:value-of select="."/>

  </xsl:element>

</xsl:template>

 

<ola mensagem="simples" tipo="String">Hello world.</ola>

 


xsl:text (criar nodos do tipo text())

<!-- Categoria: instrução -->

<xsl:text

  disable-output-escaping = "yes" | "no">

  <!-- Conteúdo: #PCDATA -->

</xsl:attribute>

Exemplo: Criar nodos do tipo text()

<xsl:template match="/">

  <xsl:text>Isto é apenas um teste!!!</xsl:text>

</xsl:template>

Esta stylesheet aplicada a qualquer documento XML dá como resultado:

Isto é apenas um teste!!!


xsl:processing-instruction

<!-- Categoria: instrução -->

<xsl:processing-instruction

  name = "nome-processador-externo">

  <!-- Conteúdo: template -->

</xsl:processing-instruction>

Exemplo: criar instruções de processamento

<xsl:processing-instruction name="xml-stylesheet">

  href="sumarios.xsl" type="text/xsl"

</xsl:processing-instruction>

O que produziria a seguinte saída:

<?xml-stylesheet

    href="sumarios.xsl" type="text/xsl"?>

xsl:comment

<!-- Categoria: instrução -->

<xsl:comment>

  <!-- Conteúdo: template -->

</xsl:comment>

Exemplo: criar comentários

<xsl:comment>Este documento foi gerado

  automaticamente. Não o edite! </xsl:comment>

Produziria a seguinte saída:

<!--Este documento foi gerado automaticamente. Não o edite! -->

xsl:copy

<!-- Categoria: instrução -->

<xsl:copy

  use-attribute-sets = attribute-set-name*>

  <!-- Conteúdo: template -->

</xsl:copy>

Exemplo: a transformação identidade

<xsl:template match="@*|node()">

  <xsl:copy>

    <xsl:apply-templates select="@*|node()"/>

  </xsl:copy>

</xsl:template>

 

<!-- o match pode ter: /, node(), ou * -->

   <xsl:template match="/">

     <xsl:copy-of select="."/>

   </xsl:template>


xsl:copy-of (“copiando subárvores inteiras”)

<!-- Categoria: instrução -->

<xsl:copy-of

  select = expression/>

xsl:value-of ("querying for text")

<!-- Categoria: instrução -->

<xsl:value-of

  select = string-expression

  disable-output-escaping = "yes"|"no" />

Exemplo: O índice cronológico de sumários

<xsl:template match="/">

  <h2>Índice Cronológico</h2>

  <ul>

    <xsl:apply-templates mode="data"/>

  </ul>

  <h2>Sumários de PED</h2>

  <xsl:apply-templates select="sumario"/>

</xsl:template>

 

<xsl:template match="aula" mode="data">

  <li>

    <xsl:value-of select="data"/>

  </li>

</xsl:template>

 


Mais exemplos (2001)

Exemplo: strip-space e nodos do tipo text()

<xsl:strip-space elements="*"/>

   <xsl:template match="text()">

     <result>

         <xsl:copy-of select="."/>

     </result>

   </xsl:template>

 

Instruções cíclicas

xsl:for-each

<!-- Categoria: instrução -->

<xsl:for-each

  select = node-set-expression/>

Exemplo: geração dum índice de contextos

<xsl:strip-space elements="*"/>

  

   <xsl:template match="/">

     <indice>

     <xsl:for-each select="//text()">

       <tnode>

 

         <valor>

           <xsl:value-of select="."/>

         </valor>

    

         <contexto>

           <xsl:for-each select="ancestor::*">

              <xsl:value-of select="name()"/>

              <xsl:text>==</xsl:text>

           </xsl:for-each>

         </contexto>

      

       </tnode>

     </xsl:for-each>

     </indice>

   </xsl:template>

 

Instruções condicionais

xsl:if

<!-- Categoria: instrução -->

<xsl:if

  test = boolean-expression>

</xsl:if>

Exemplo: É o último?

<xsl:template match=”lista/item”>

  <xsl:apply-templates/>

  <xsl:if test=”not([last()])”>

    ,

  </xsl:if>

</xsl:template>

 

xsl:choose

<!-- Categoria: instrução -->

<xsl:choose>

  <xsl:when test = boolean-expression>

   

  </xsl:when>

  ...

  <xsl:otherwise>

 

  </xsl:otherwise>

</xsl:choose>

 

xsl:sort

<!-- Categoria: instrução -->

<xsl:sort

  select = expression

  [data-type = “text|number”]

  [lang = “langcode”]

  [order = “ascending|descending”]

  [case-order = “upper-first|lower-first”]/>

Exemplo: ordenação de nomes

<xsl:template match="/">

     <alunos>

     <xsl:for-each select="//aluno1|//aluno2|//aluno3">

       <xsl:sort select="nome1|nome2|nome3" order="ascending"/>

       <aluno>

 

         <nome>

           <xsl:value-of select="nome1|nome2|nome3"/>

         </nome>

    

         <numero>

           <xsl:value-of select="numero1|numero2|numero3"/>

         </numero>

      

       </aluno>

     </xsl:for-each>

     </alunos>

   </xsl:template>

 

Exemplo: ordenação de números

<xsl:template match="/">

     <alunos>

     <xsl:for-each select="//aluno1|//aluno2|//aluno3">

       <xsl:sort select="numero1|numero2|numero3"

                 data-type="number" order="ascending"/>

       <aluno>

 

         <nome>

           <xsl:value-of select="nome1|nome2|nome3"/>

         </nome>

    

         <numero>

           <xsl:value-of select="numero1|numero2|numero3"/>

         </numero>

      

       </aluno>

     </xsl:for-each>

     </alunos>

   </xsl:template>