XPath Avançado em XSLT
Aula 2 de 5
Eixos Avançados
Eixos definem a direção da navegação na árvore XML dentro de templates XSLT.
<xsl:template match="produto">
<!-- Eixos de navegação -->
<xsl:value-of select="preceding-sibling::produto[1]/nome"/>
<xsl:value-of select="following-sibling::produto[1]/nome"/>
<xsl:value-of select="ancestor::catalogo/@id"/>
<xsl:value-of select="descendant::*/preco"/>
<!-- Atalhos -->
<xsl:value-of select="../produto"/> <!-- parent:: -->
<xsl:value-of select=".//preco"/> <!-- self::descendant:: -->
</xsl:template>
Funções Especiais do XSLT
current()
Retorna o nó atual (diferente do nó de contexto).
<xsl:for-each select="//categoria">
<!-- current() é o nó da iteração, . é o contexto -->
<xsl:value-of select="//produto[categoria = current()/nome]"/>
</xsl:for-each>
document()
Acessa documentos XML externos.
<xsl:template match="/">
<xsl:for-each select="document('precos.xml')//produto">
<p><xsl:value-of select="nome"/> - R$ <xsl:value-of select="preco"/></p>
</xsl:for-each>
</xsl:template>
generate-id()
Gera identificadores únicos para nós.
<xsl:template match="livro">
<a name="{generate-id()}">
<xsl:value-of select="titulo"/>
</a>
</xsl:template>
Seleção Condicional com XPath
<!-- Usando predicados para seleção condicional -->
<xsl:template match="/">
<h2>Livros caros</h2>
<xsl:apply-templates select="//livro[preco > 50]"/>
<h2>Autores de ficção</h2>
<xsl:apply-templates select="//livro[genero='ficcao']/autor"/>
<h2>Primeiros 3 livros</h2>
<xsl:apply-templates select="//livro[position() <= 3]"/>
</xsl:template>
Concatenação e Formatação
<xsl:template match="livro">
<!-- Concatenação -->
<p><xsl:value-of select="concat(titulo, ' - ', autor, ' (', ano, ')')"/></p>
<!-- Formatação de strings -->
<p><xsl:value-of select="concat('R$ ', format-number(preco, '#.00'))"/></p>
<!-- Substring e normalização -->
<p><xsl:value-of select="substring(normalize-space(descricao), 1, 100)"/>...</p>
</xsl:template>
Lab: Transformação com XPath Avançado
# 1. Documento XML
cat << 'EOF' > catalogo.xml
<?xml version="1.0"?>
<catalogo>
<categoria id="ELETRO">Eletrônicos</categoria>
<categoria id="LIVRO">Livros</categoria>
<produto id="P001" cat="ELETRO">
<nome>Notebook Pro</nome>
<preco>4999.00</preco>
<estoque>15</estoque>
</produto>
<produto id="P002" cat="LIVRO">
<nome>XML na Prática</nome>
<preco>89.90</preco>
<estoque>30</estoque>
</produto>
<produto id="P003" cat="ELETRO">
<nome>Mouse Wireless</nome>
<preco>129.90</preco>
<estoque>42</estoque>
</produto>
</catalogo>
EOF
# 2. Folha XSLT com XPath avançado
cat << 'EOF' > catalogo.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/">
<html>
<head><title>Catálogo Avançado</title></head>
<body>
<h1>Catálogo de Produtos</h1>
<!-- Agrupamento por categoria usando XPath -->
<xsl:for-each select="//categoria">
<h2>Categoria: <xsl:value-of select="."/></h2>
<ul>
<xsl:for-each select="//produto[@cat = current()/@id]">
<li>
<xsl:value-of select="concat(nome, ' - R$ ', preco)"/>
<xsl:if test="number(estoque) < 20">
<strong> (ESTOQUE BAIXO: <xsl:value-of select="estoque"/> un.)</strong>
</xsl:if>
</li>
</xsl:for-each>
</ul>
</xsl:for-each>
<hr/>
<p>Total de produtos:
<xsl:value-of select="count(//produto)"/>
</p>
<p>Produtos com estoque baixo:
<xsl:value-of select="count(//produto[number(estoque) < 20])"/>
</p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
EOF
# 3. Executar
xsltproc catalogo.xsl catalogo.xml > catalogo.html
type catalogo.html
Domine XPath e você dominará XSLT — toda seleção e condição começa com uma expressão precisa.