Análise da Semântica
Denotacional do XPath
Carlos Ramisch
Sandra Kniphoff
Soraya Hossain
Baseado no artigo de Philip Wadler
Objetivos
Breve explanação sobre XML e XPath
Apresentação parcial da sintaxe do XPath
Análise de uma semântica denotacional
Introdução ao XML
Regulamentado pelo W3C
Resolve limitações do HTML
Modularidade
Legibilidade
Flexibilidade
Troca de informações
Bases de dados XML
Exemplo de código XML
<receitas>
<receita tipo="SALGADO">
<nome>Pizza de Calabresa</nome>
<tempo>30 minutos</tempo>
<ingredientes>
<ing qtd=”30 rodelas”>linguiça
calabresa</ing>
<ing qtd=”1”>massa para pizza</ing>
<ing qtd=”100g”>queijo mussarela</ing>
<ing qtd=”1 lata”>extrato de tomate</ing>
</ingredientes>
</receita>
<receita tipo="DOCE">
<nome>Brigadeiro</nome>
<tempo>25 minutos</tempo>
<ingredientes>
<ing qtd=”1 lata”>leite condensado</ing>
<ing qtd=”1 xícara”>achocolatado em
pó</ing>
<ing qtd=”2 colheres”>manteiga</ing>
</ingredientes>
</receita>
<receita tipo="DOCE">
<nome>Bolo de Chocolate</nome>
<tempo>50 minutos</tempo>
<ingredientes>
<ing qtd=”3 xícaras”>farinha</ing>
<ing qtd=”2 xícaras”>açúcar</ing>
<ing qtd=”1 xícara”>chocolate em pó</ing>
<ing qtd=”1 xícara”>azeite</ing>
<ing qtd=”2”>ovos</ing>
<ing qtd=”1 colher”>fermento</ing>
<ing qtd=”2 xícaras”>leite</ing>
</ingredientes>
</receita>
</receitas>
Introdução ao XPath
Linguagem de consulta
Endereçar partes de documentos XML
Caminhamento em árvores
Semelhante a diretórios
Exemplos de consultas XPath
/receitas/receita – todas as receitas
/receitas/receita[ tipo= “SALGADO” ] - todas as receitas
cujo tipo é SALGADO
/child::receitas/child::receita[attribute::tipo=
“SALGADO”] - o mesmo que anterior
/receitas/receita/ingredientes/ing[ qtd= “1 xícara” ] -
todos os ingredientes de todas as receitas cuja
quantidade é 1 xícara
/child::receitas/child::node()[position() = 2 ] -
Exemplo de código XML
<receitas>
<receita tipo="SALGADO">
<nome>Pizza de Calabresa</nome>
<tempo>30 minutos</tempo>
<ingredientes>
<ing qtd=”30 rodelas”>linguiça
calabresa</ing>
<ing qtd=”1”>massa para pizza</ing>
<ing qtd=”100g”>queijo mussarela</ing>
<ing qtd=”1 lata”>extrato de tomate</ing>
</ingredientes>
</receita>
<receita tipo="DOCE">
<nome>Brigadeiro</nome>
<tempo>25 minutos</tempo>
<ingredientes>
<ing qtd=”1 lata”>leite condensado</ing>
<ing qtd=”1 xícara”>achocolatado em
pó</ing>
<ing qtd=”2 colheres”>manteiga</ing>
</ingredientes>
</receita>
<receita tipo="DOCE">
<nome>Bolo de Chocolate</nome>
<tempo>50 minutos</tempo>
<ingredientes>
<ing qtd=”3 xícaras”>farinha</ing>
<ing qtd=”2 xícaras”>açúcar</ing>
<ing qtd=”1 xícara”>chocolate em pó</ing>
<ing qtd=”1 xícara”>azeite</ing>
<ing qtd=”2”>ovos</ing>
<ing qtd=”1 colher”>fermento</ing>
<ing qtd=”2 xícaras”>leite</ing>
</ingredientes>
</receita>
</receitas>
Conjunto Completo das
Regras de Sintaxe
[1] LocationPath::= RelativeLocationPath | AbsoluteLocationPath [2] AbsoluteLocationPath::= '/' RelativeLocationPath?|
AbbreviatedAbsoluteLocationPath [3] RelativeLocationPath::= Step | RelativeLocationPath '/' Step | AbbreviatedRelativeLocationPath
[4] Step ::= AxisSpecifierNodeTestPredicate* | AbbreviatedStep
[5] AxisSpecifier ::= AxisName '::' | AbbreviatedAxisSpecifier
[6] AxisName::= 'ancestor'| 'ancestor-or-self'| 'attribute'| 'child'| 'descendant'| 'descendant-or-self'| 'following'| 'following-sibling'| 'namespace'| 'parent'| 'preceding'| 'preceding-sibling'| 'self'
[7] NodeTest ::= NameTest | NodeType '(' ')' | 'processing-instruction' '('
Literal ')' [8] Predicate::= '[' PredicateExpr ']' [9] PredicateExpr::= Expr [10] AbbreviatedAbsoluteLocationPath::= '//' RelativeLocationPath [11] AbbreviatedRelativeLocationPath::= RelativeLocationPath '//' Step [12] AbbreviatedStep::= '.'| '..' [13] AbbreviatedAxisSpecifier::= '@'? [14] Expr ::= OrExpr
[15] PrimaryExpr ::= VariableReference | '(' Expr ')' | Literal | Number |
FunctionCall
[16] FunctionCall ::= FunctionName '(' ( Argument ( ',' Argument )* )? ')'
[17] Argument ::= Expr
[18] UnionExpr ::= PathExpr | UnionExpr '|' PathExpr
[19] PathExpr ::= LocationPath | FilterExpr | FilterExpr '/'
RelativeLocationPath | FilterExpr '//' RelativeLocationPath
[20] FilterExpr ::= PrimaryExpr | FilterExprPredicate
[21] OrExpr ::= AndExpr | OrExpr 'or' AndExpr
[22] AndExpr ::= EqualityExpr | AndExpr 'and' EqualityExpr
[23] EqualityExpr ::= RelationalExpr | EqualityExpr '=' RelationalExpr |
EqualityExpr '!=' RelationalExpr
[24] RelationalExpr ::= AdditiveExpr | RelationalExpr '<' AdditiveExpr |
RelationalExpr '>' AdditiveExpr | RelationalExpr '<=' AdditiveExpr |
RelationalExpr '>=' AdditiveExpr
[25] AdditiveExpr ::= MultiplicativeExpr | AdditiveExpr '+'
MultiplicativeExpr | AdditiveExpr '-' MultiplicativeExpr
[26] MultiplicativeExpr ::= UnaryExpr | MultiplicativeExpr
MultiplyOperatorUnaryExpr | MultiplicativeExpr 'div' UnaryExpr |
MultiplicativeExpr 'mod' UnaryExpr
[27] UnaryExpr ::= UnionExpr | '-' UnaryExpr
[28] ExprToken::= '(' | ')' | '[' | ']' | '.' | '..' | '@' | ',' | '::'| NameTest| NodeType|
Operator| FunctionName| AxisName| Literal| Number| VariableReference
[29] Literal::= '"' [^"]* '"'| "'" [^']* "'"
[30] Number::= Digits ('.' Digits?)?| '.' Digits
[31] Digits::= [0-9]+
[32] Operator::= OperatorName| MultiplyOperator| '/' | '//' | '|' | '+' | '-' | '=' | '!=' | '<' | '<=' | '>' | '>='
[33] OperatorName::='and' | 'or' | 'mod' | 'div' [34] MultiplyOperator::= '*'
[35] FunctionName::= QName - NodeType
[36] VariableReference::= '$' QName
[37] NameTest::= '*'| NCName ':' '*'| QName
[38] NodeType::= 'comment'| 'text'| 'processing-instruction'| 'node' [39] ExprWhitespace::= S
Sintaxe Simplificada
AxisName ::= 'ancestor' |
'ancestor-or-self' | 'attribute' | 'child' | 'descendant' |
'descendant-or-self' | 'following' |
'following-sibling' | 'namespace' | 'parent'
| 'preceding' | 'preceding-sibling' | 'self'
NodeTest ::= NameTest | NodeType '(' ')'
Predicate ::= '[' PredicateExpr ']'
Sintaxe Simplificada (cont.)
Step ::= AxisSpecifier NodeTest
Predicate*
AxisSpecifier ::= AxisName '::'
LocationPath ::= RelativeLocationPath |
AbsoluteLocationPath
AbsoluteLocationPath ::= '/'
RelativeLocationPath?
RelativeLocationPath ::= Step |
RelativeLocationPath '/' Step
Semântica Denotacional Auxiliar
Avaliação de Eixos
A
: Axis
→
Node
→
Set(Node)
A
[[child]]x = children(x)
A
[[parent]]x = parent(x)
A
[[descendant]]x = children+(x)
A
[[ancestor]]x = parent+(x)
A
[[self]]x = { x }
A
[[attribute]]x = attributes(x)
A
[[namespace]]x = namespaces(x)
Semântica Denotacional Auxiliar
Tipos de Nodos
P : Axis
→
Nodetype
P
[[child]] = Element
P
[[parent]] = Element
P
[[descendant]] = Element
P
[[ancestor]] = Element
P
[[self]] = Element
P
[[attribute]] = Attribute
P
[[namespace]] = Namespace
Semântica Denotacional Auxiliar
Direção dos Eixos
D : Axis
→
Direction
D
[[child]] = forward
D
[[parent]] = reverse
D
[[descendant]] = forward
D
[[ancestor]] = reverse
D
[[self]] = forward
D
[[attribute]] = forward
D
[[namespace]] = forward
Semântica Denotacional
Expressões Numéricas
E
: Axis
→
Expr
→
(Node, Set(Node))
→
Number
E
a[[e1 + e2]](x, S) = Ea[[e1]](x, S) + Ea[[e2]](x, S)
E
a[[e1 * e2]](x, S) = Ea[[e1]](x, S)
×
E
a[[e2]](x, S)
E
a[[i]](x, S) = i
E
a[[position()]](x, S) =
let j = size({ x1 | x1
∈
S, x1
≤
doc
x }) in
if D[[a]] = forward then j else size(S) + 1 – j
Semântica Denotacional
Expressões Booleanas
Q
: Axis
→
Qualifier
→
(Node, Set(Node))
→
Boolean
Q
a[[q1 and q2]](x, S) = Qa[[q1]](x, S)
∧
Q
a[[q2]](x, S)
Q
a[[q1 or q2]](x, S) = Qa[[q1]](x, S)
∨
Q
a[[q2]](x, S)
Q
a[[not(q)]](x, S) =
¬
Q
a[[q]](x, S)
Q
a[[e1=e2]](x, S) = Ea[[e1]](x, S) = Ea[[e2]](x, S)
Semântica Denotacional
Caminhos
S
: Axis
→
Pattern
→
(Node, Set(Node))
→
Set(Node)
S
a[[p1|p2]](x, S) = Sa[[p1]](x, S)
∪
[ S
a[[p2]](x, S)
S
a[[/p]](x, S) = Sa[[p]](root(x), { x })
S
a[[p1/p2]](x, S) =
let S1 = Sa[[p1]](x, S) in
{ x2 | x1
∈
S1, x2
∈
Sa[[p2]](x1, S1) }
S
a[[a1::p1]](x, S) = Sa1 [[p1]](x, S)
S
a[[n]](x, S) = { x1 | x1
∈
A
[[a]]x, nodetype(x1) =
Semântica Denotacional
Caminhos (cont.)
S
a[[*]](x, S) = { x1 | x1
∈
A
[[a]]x, nodetype(x1) = P[[a]] }
S
a[[text()]](x, S) = { x1 | x1
∈
A
[[a]]x, nodetype(x1) =
Text }