XSLT e recursividade estrutural
Helena Galhardas
DEI IST
Agenda
Recursividade estrutural XSLT
Recursividade estrutural: um paradigma diferente
Dados são vistos como conjuntos e um operador de união:
{a:3, a:{b:”one”, c:5}, b:4} =
{a:3} U {a:{b:”one”,c:5}} U {b:4}
Exemplo 1
f($T1 U $T2) = f($T1) U f($T2)f({$L: $T}) = f($T)f({}) = {}f($V) = if isInt($V) then {result: $V} else {}
f($T1 U $T2) = f($T1) U f($T2)f({$L: $T}) = f($T)f({}) = {}f($V) = if isInt($V) then {result: $V} else {}
Encontrar todos os inteiros nos dados
a a b
b c3
“one” 5
4result result result
3 5 4
Exemplo 2
O que faz?
f($T1 U $T2) = f($T1) U f($T2)f({$L: $T}) = if $L=a then {b:f($T)} else {$L:f($T)}f({}) = {}f($V) = $V
f($T1 U $T2) = f($T1) U f($T2)f({$L: $T}) = if $L=a then {b:f($T)} else {$L:f($T)}f({}) = {}f($V) = $V
Exemplo 3
Aumentar os preços dos motores de 10%
f($T1 U $T2) = f($T1) U f($T2)f({$L: $T}) = if $L= engine then {$L: g($T)} else {$L: f($T)}f({}) = {}f($V) = $V
f($T1 U $T2) = f($T1) U f($T2)f({$L: $T}) = if $L= engine then {$L: g($T)} else {$L: f($T)}f({}) = {}f($V) = $V
g($T1 U $T2) = g($T1) U g($T2)g({$L: $T}) = if $L= price then {$L:1.1*$T} else {$L: g($T)}g({}) = {}g($V) = $V
g($T1 U $T2) = g($T1) U g($T2)g({$L: $T}) = if $L= price then {$L:1.1*$T} else {$L: g($T)}g({}) = {}g($V) = $V
engine body
part price
price price
part price
100
1000
100
1000
engine body
part price
price price
part price
110
1100
100
1000
Exemplo 4
Encontrar todas as sub-árvores que se conseguem chegar por (a.b)*.a
a
b
a
f($T1 U $T2) = f($T1) U f($T2)f({$L: $T}) = if $L= a then g($T} U $T else { }f({}) = { }f($V) = { }
f($T1 U $T2) = f($T1) U f($T2)f({$L: $T}) = if $L= a then g($T} U $T else { }f({}) = { }f($V) = { }
g($T1 U $T2) = g($T1) U g($T2)g({$L: $T}) = if $L= b then f($T) else { }g({}) = { }g($V) = { }
g($T1 U $T2) = g($T1) U g($T2)g({$L: $T}) = if $L= b then f($T) else { }g({}) = { }g($V) = { }
Forma genérica de recursividade estrutural
f1($T1 U $T2) = f1($T1) U f1($T2)f1({$L: $T}) = E1($L, f1($T),...,fk($T), $T)f1({}) = { }f1($V) = { }
f1($T1 U $T2) = f1($T1) U f1($T2)f1({$L: $T}) = E1($L, f1($T),...,fk($T), $T)f1({}) = { }f1($V) = { }
fk($T1 U $T2) = fk($T1) U fk($T2)fk({$L: $T}) = Ek($L, f1($T),...,fk($T), $T)fk({}) = { }fk($V) = { }
fk($T1 U $T2) = fk($T1) U fk($T2)fk({$L: $T}) = Ek($L, f1($T),...,fk($T), $T)fk({}) = { }fk($V) = { }
. . . .
Cada E1, ..., Ek consiste só {_ : _}, U, if_then_else_
Execução da recursividade estrutural Calcula as funções recursivas começando
com f1 na raíz
Terminação é garantida
Quão eficientemente se pode executar? Não vamos detalhar
XSL XSL composto por:
Linguagem para transformar documentos XML (XSLT) Vocabulário XML para especificar semântica de formatação:
XSL-FO (formatting objects) XSLT transforma um doc XML numa árvore de
resultado: Outro doc XML Um doc HTML Um doc que contenha FO
XSL-FO em geral: Corresponde a uma ou mais áreas no écran ou página Tem props para descrever o aspecto visual da área Tem como conteúdo ou
texto Objecto externo (image, applet, etc.), ou Mais objectos de formatação
Programa XSLT
XSL program = template-rule ... template-rule
template-rule = match pattern + template
<xsl:template match = “* | /”> <xsl:apply-templates/> </xsl:template>
<xsl:template match = “/bib/*/title”> <result> <xsl:value-of select = “.” /> </result></xsl:template>
<xsl:template match = “* | /”> <xsl:apply-templates/> </xsl:template>
<xsl:template match = “/bib/*/title”> <result> <xsl:value-of select = “.” /> </result></xsl:template>
Examplo: Encontra os títulos de todos os livros
Regras XSLT (1) Regras são indicadas pelos elementos xsl:template O padrão é especificado usando uma expressão
XPath no valor do atributo match template é o conteúdo do elemento xsl:template
Ex: <xsl:template match = “book”> <xsl:apply-templates/> </xsl:template>
template corresponde aos elementos book <xsl:apply-templates/> é uma instrução que aplica
os templates a todos os filhos do elemento que fez match no template
Regras XSLT (2)
<result> e </result> são elementos resultado literais
xsl:value-of é uma instrução que produz como saída o que é seleccionado pelo .valor do atributo select O valor do atributo select é uma expressão XPath
<xsl:template match = “/bib/*/title”> <result> <xsl:value-of select = “.” /> </result></xsl:template>
<xsl:template match = “/bib/*/title”> <result> <xsl:value-of select = “.” /> </result></xsl:template>
Modelo de processamento XSLT Processador lê um doc XML e uma stylesheet XSLT O processamento começa no nó raíz do documento Cada nó é processado do seguinte modo:
Procurar a regra template com o melhor matching pattern Se encontrado, executar o conteúdo do template (a maior
parte das vezes seleccionando mais nós para processar) Se não fôr encontrado, prosseguir com a lista de nós filhos
Uma lista de nós é processada percorrendo os nós por ordem
O processo continua recursivamente até não existirem mais novos para serem seleccionados
Controlo de fluxo
<xsl:template match = “* | /”> <xsl:apply-templates/> </xsl:template>
<xsl:template match=“a”> <A><xsl:apply-templates/></A></xsl:template>
<xsl:template match=“b”> <B><xsl:apply-templates/></B></xsl:template>
<xsl:template match=“c”> <C><xsl:value-of/></C></xsl:template>
<xsl:template match = “* | /”> <xsl:apply-templates/> </xsl:template>
<xsl:template match=“a”> <A><xsl:apply-templates/></A></xsl:template>
<xsl:template match=“b”> <B><xsl:apply-templates/></B></xsl:template>
<xsl:template match=“c”> <C><xsl:value-of/></C></xsl:template>
<a> <e> <b> <c> 1 </c>
<c> 2 </c>
</b>
<a> <c> 3 </c>
</a>
</e>
<c> 4 </c>
</a>
<A> <B> <C> 1 </C>
<C> 2 </C>
</B>
<A> <C> 3 </C>
</A>
<C> 4 </C>
</A>
XSLT e recursividade estruturalEquivalente
a:f(T1 U T2) = f(T1) U f(T2)f({L: T}) = if L= c then {C: t} else L= b then {B: f(t)} else L= a then {A: f(t)} else f(t)f({}) = {}f(V) = V
f(T1 U T2) = f(T1) U f(T2)f({L: T}) = if L= c then {C: t} else L= b then {B: f(t)} else L= a then {A: f(t)} else f(t)f({}) = {}f(V) = V
<xsl:template match = “* | /”>
<xsl:template match=“c”>
<xsl:template match=“b”>
<xsl:template match=“a”>
XSLT vs recursividade estruturalXSLT: Sobre árvores Pode entrar em ciclo
infinito
Recursividade estrutural: Grafos arbitrários Termina sempre
Programa XSLT simples
Copia a entrada:<xsl:template match = “/”> <xsl:apply-templates/> </xsl:template>
<xsl:template match = “text()”> <xsl:value-of select=“.”/></xsl:template>
<xsl:template match = “*”> <xsl:element name=“name(.)”> <xsl:apply-templates/> </xsl:element></xsl:template>
<xsl:template match = “/”> <xsl:apply-templates/> </xsl:template>
<xsl:template match = “text()”> <xsl:value-of select=“.”/></xsl:template>
<xsl:template match = “*”> <xsl:element name=“name(.)”> <xsl:apply-templates/> </xsl:element></xsl:template>
Resolução de conflitos para regras de template
Se várias regras de template fazem match, escolher a que tem maior prioridade
Prioridades podem ser: Explicitas: <xsl:template match=“abc” priority=“1.41”>
implicitas: regras ad-hoc dadas pelo W3, baseadas no match
match=“abc” prioridade 0. match=“[... some namespace name... ]” prioridade -0.25. match=“node()” prioridade -0.5.
Modos em XSLT
Modo = nome para um grupo de template rules
Útil quando o mesmo nó tem que ser percorrido várias vezes
Equivalente a ter múltiplas funções recursivas
Exemplo
<xsl:template match = “/”> <xsl:apply-templates mode=“f”/> </xsl:template>
<xsl:template match=“*” mode=“f”/>
<xsl:template match=“a” mode=“f”> <result> <xsl:copy-of match=“.”/> </result> <xsl:apply-templates mode=“g”/></xsl:template>
<xsl:template match=“*” mode=“g”>
<xsl:template match=“b” mode=“g”> <xsl:apply-templates mode=“f”/></xsl:template>
<xsl:template match = “/”> <xsl:apply-templates mode=“f”/> </xsl:template>
<xsl:template match=“*” mode=“f”/>
<xsl:template match=“a” mode=“f”> <result> <xsl:copy-of match=“.”/> </result> <xsl:apply-templates mode=“g”/></xsl:template>
<xsl:template match=“*” mode=“g”>
<xsl:template match=“b” mode=“g”> <xsl:apply-templates mode=“f”/></xsl:template>
f(T1 U T2) = f(T1) U f(T2)f({a: T}) = {result:T} U g(T)f({}) = {}f(V) = V
g(T1 U T2) = g(T1) U g(T2)g({b: T}) = f(T)g({}) = {}g(V) = V
f(T1 U T2) = f(T1) U f(T2)f({a: T}) = {result:T} U g(T)f({}) = {}f(V) = V
g(T1 U T2) = g(T1) U g(T2)g({b: T}) = f(T)g({}) = {}g(V) = V
Calcular o caminho (a.b)* :
ExercícioEscreva um programa XSLT que transforme o doc XML: <teaches>
<teaches-tuple course="XML" lecturer="Peter Wood"/> <teaches-tuple course="Algorithms" lecturer="Trevor Fenner"/>
</teaches>
Noutro com o formato:<teaches>
<teaches-tuple> <course>XML</course> <lecturer>Peter Wood</lecturer>
</teaches-tuple> <teaches-tuple>
<course>Algorithms</course> <lecturer>Trevor Fenner</lecturer>
</teaches-tuple> </teaches> Assuma que teaches é o elemento raíz e que os atributos course e lecturer
são obrigatórios. O programa deve executar-se para qualquer número de ocorrências do elemento teaches-tuple.
Tópicos próximas aulas
(Prof. Pável Calado) Extracção de dados da Web Extracção de informação
Referências S. Abiteboul, P. Buneman, D. Suciu, “Data on the Web, From
Relations to Semistructured Data and XML”, Morgan Kaufmann, 2000, (caps 5 e 6)
Peter Wood, Slides on “Representing and Querying Data on the Web”, http://www.dcs.bbk.ac.uk/~ptw/teaching/data-on-the-web.html.
Dan Suciu, Slides on “The semistructured data model”, CSE 590ds: Management of XML and Semistructured Data, http://www.cs.washington.edu/education/courses/cse590ds/01sp/
www.w3.org/Style/XSL/ W3C's XSL home page
hands-on-xsl.pdf hands-on XSL: a simple exercise demonstrating the principles of XSLT (previously available from IBM developerWorks)
nwalsh.com/docs/tutorials/xsl/ an XSL tutorial by Paul Grosso and Norman Walsh
www.zvon.org/xxl/XSLTreference/Output/ an XSLT reference using examples; links to other XML tutorials
metalab.unc.edu/xml/books/bible/updates/14.html a chapter from the XML Bible on XSL Transformations (and XPath)
Top Related