kb.erickguedes.com
XSLT: Transformação de Documentos

Parâmetros e Variáveis em XSLT

Aula 3 de 5

xsl:variable

Variáveis são imutáveis em XSLT — seu valor não pode ser alterado após definido.

<!-- Variável com valor simples -->
<xsl:variable name="titulo" select="'Relatório de Vendas'"/>
<xsl:variable name="moeda" select="'R$'"/>
<xsl:variable name="limite" select="1000"/>

<!-- Variável com conteúdo (RTF - Result Tree Fragment) -->
<xsl:variable name="estilos">
  <style>
    <cor-fundo>#f0f0f0</cor-fundo>
    <fonte>Arial</fonte>
  </style>
</xsl:variable>

xsl:param e xsl:with-param

Parâmetros permitem passar valores para templates, tornando as transformações reutilizáveis.

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

  <!-- Parâmetro global com valor default -->
  <xsl:param name="preco-maximo" select="9999.99"/>
  <xsl:param name="formato-saida" select="'html'"/>

  <xsl:template match="/">
    <xsl:call-template name="lista-produtos">
      <xsl:with-param name="categoria" select="'Eletrônicos'"/>
      <xsl:with-param name="minimo" select="100"/>
    </xsl:call-template>
  </xsl:template>

  <xsl:template name="lista-produtos">
    <xsl:param name="categoria"/>
    <xsl:param name="minimo" select="0"/>

    <h2>Produtos: <xsl:value-of select="$categoria"/></h2>
    <xsl:for-each select="//produto[categoria=$categoria
                          and number(preco) >= $minimo]">
      <p><xsl:value-of select="nome"/> - <xsl:value-of select="preco"/></p>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

Escopo de Variáveis e Parâmetros

<xsl:template match="/">
  <!-- Escopo global (todo o template) -->
  <xsl:variable name="data" select="'2024-01-01'"/>

  <xsl:for-each select="//livro">
    <!-- Escopo local (apenas dentro do for-each) -->
    <xsl:variable name="desconto">
      <xsl:choose>
        <xsl:when test="number(preco) > 100">10</xsl:when>
        <xsl:otherwise>5</xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <p>
      <xsl:value-of select="titulo"/>
      Preço c/ desconto:
      <xsl:value-of select="format-number(preco * (100 - $desconto) div 100, '#.00')"/>
      (<xsl:value-of select="$desconto"/>% off)
    </p>
  </xsl:for-each>
</xsl:template>

Import e Include

Reutilização de folhas XSLT entre projetos.

<!-- include: copia o conteúdo no mesmo escopo -->
<xsl:include href="templates-comuns.xsl"/>
<xsl:include href="formatacao.xsl"/>

<!-- import: prioridade menor (pode ser sobrescrito) -->
<xsl:import href="base.xsl"/>

Lab: Transformação Parametrizada

# 1. Documento XML
cat << 'EOF' > vendas.xml
<?xml version="1.0"?>
<vendas mes="janeiro" ano="2024">
  <produto cat="ELETRO">
    <nome>Notebook</nome>
    <preco>3500.00</preco>
    <quantidade>5</quantidade>
  </produto>
  <produto cat="LIVRO">
    <nome>XSLT Avançado</nome>
    <preco>120.00</preco>
    <quantidade>10</quantidade>
  </produto>
  <produto cat="ELETRO">
    <nome>Mouse</nome>
    <preco>50.00</preco>
    <quantidade>20</quantidade>
  </produto>
</vendas>
EOF

# 2. Folha XSLT com parâmetros
cat << 'EOF' > relatorio.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:param name="categoria" select="'TODAS'"/>
  <xsl:param name="preco-min" select="0"/>
  <xsl:param name="mostrar-total" select="'sim'"/>

  <xsl:template match="/">
    <html>
    <head><title>Relatório de Vendas</title></head>
    <body>
      <h1>Vendas - <xsl:value-of select="//vendas/@mes"/>
                 / <xsl:value-of select="//vendas/@ano"/></h1>
      <p>Filtro: categoria = <xsl:value-of select="$categoria"/>,
         preço mínimo = R$ <xsl:value-of select="$preco-min"/></p>

      <table border="1">
        <tr><th>Produto</th><th>Preço</th><th>Qtd</th><th>Total</th></tr>

        <xsl:for-each select="//produto[
          ($categoria = 'TODAS' or categoria = $categoria)
          and number(preco) >= $preco-min]">

          <xsl:variable name="total-linha" select="number(preco) * number(quantidade)"/>
          <tr>
            <td><xsl:value-of select="nome"/></td>
            <td><xsl:value-of select="format-number(preco, '#.00')"/></td>
            <td><xsl:value-of select="quantidade"/></td>
            <td><xsl:value-of select="format-number($total-linha, '#.00')"/></td>
          </tr>
        </xsl:for-each>
      </table>

      <xsl:if test="$mostrar-total = 'sim'">
        <p><strong>Total geral: R$
          <xsl:value-of select="format-number(
            sum(//produto[
              ($categoria = 'TODAS' or categoria = $categoria)
              and number(preco) >= $preco-min
            ]/preco * ../quantidade),
          '#.00')"/></strong></p>
      </xsl:if>
    </body>
    </html>
  </xsl:template>
</xsl:stylesheet>
EOF

# 3. Executar com parâmetros
echo "=== Relatório completo ==="
xsltproc --stringparam categoria "TODAS" \
         --stringparam preco-min "0" \
         relatorio.xsl vendas.xml

echo ""
echo "=== Apenas ELETRO, preco > 100 ==="
xsltproc --stringparam categoria "ELETRO" \
         --stringparam preco-min "100" \
         relatorio.xsl vendas.xml

echo ""
echo "=== Sem total geral ==="
xsltproc --stringparam categoria "TODAS" \
         --stringparam preco-min "0" \
         --stringparam mostrar-total "nao" \
         relatorio.xsl vendas.xml

Parâmetros transformam XSLT estático em um motor de templates dinâmico e reutilizável.