Xpath como sub-sistema do XSLT Biztalk 2010 [pt-BR]

Como já publiquei em posts anteriores, o BizTalk Server 2010 permite através da utilização de mapas (ficheiros .btm), realizar transformações a dados de um ficheiro xml, ou como mais se costuma retractar este fenómeno, mapear um ficheiro xml noutro. Ou seja, o BizTalk contém um conjunto de functoids (meras funções) que encapsulam código simples em C#, XSLT ou VB mas que é muitas vezes utilizado como o caso de concatenação de strings, operações matemáticas e até casos mais complexos como ciclos ou iterações. O grande objectivo desta ferramenta do BizTalk é simples: Permitir que uma mensagem seja lida num formato e seja transformada noutro formato (schema) que depois será lido pelo sistema alvo do processo em causa.

Como não posso abordar todos os tópicos dos mapas de uma vez só, vou abordar hoje um componente da tecnologia de transformação de ficheiros xml mais utilizada, o XSLT, que é sem dúvida a mais fácil, viciante e elegante solução para transformar dados em XML. Mas aquilo de que vos quero falar é um subsistema do XSLT, o Xpath, que é nada mais nada menos que o bot de pesquisa de elementos xml dentro de uma mensagem. O Xpath é assim uma linguagem para especificar a posição relativa ao root node de um elemento ou atributo, dentro de um XML. A sua sintaxe é semelhante à utilizada para percorrer ficheiros na linha de comandos do Windows, isto porque a sua função é quase igual, encontrar o URL completo para um elemento ou atributo (no Windows seria um ficheiro ou pasta) e desta forma fornecer os caminhos para os elementos que o XSLT deverá manipular e transformar.

Posto isto e antes de passar à acção importa justificar o público-alvo deste post, para todos aqueles que utilizam xslt nos seus script functoids, ou até fora do BizTalk em documentos de manipulação de XML e não têm grande à-vontade com o Xpath. Decidi assim fazer um pequeno guia para que rapidamente se situem dentro desta linguagem e percebam a importância do conhecimento de Xpath aquando da manipulação da linguagem XSLT.

Como sabemos, um ficheiro XML contém três tipos de componentes principais, elementos, atributos e valores atómicos. Estes últimos, que são nodos sem descendentes ou ascendentes são os valores que uma determinada instância observa para aquela mensagem, por exemplo na tag xml <pessoa sexo=”masculino”>Rui</pessoa>, pessoa seria o elemento, sexo um atributo e “Rui” o valor do elemento pessoa nesta instância.

O XSLT pretende normalmente manipular este tipo de dados, os valores atómicos, mas para lá chegar pede ao Xpath que construa o URL baseado no nome dos elementos, ou seja para o Xpath não interessa o valor “Rui” mas sim o nome do elemento “Pessoa” pois será o URL para “Pessoa” que o XSLT lhe pedirá. Mas vamos tentar perceber isto com código.

A sintaxe do Xpath é relativamente reduzida contendo seis elementos para trabalhar:

 

/                                             -> Selecciona o root node do ficheiro XML (raiz do documento)

//                                           -> Selecciona todos os nodos do documento desde o corrente

.                                              -> Selecciona o nodo corrente (onde se encontra)

..                                            -> Selecciona o nodo pai do corrente (acima na hierarquia)

@                                           -> Selecciona atributos

Nomenodo    -> Se indicarem só o nome do nodo, selecciona todos os descendentes desse mesmo nodo.

Nota: Um nodo é um qualquer elemento.

Sempre que utilizamos um destes elementos devemos imediatamente seguir indicar o nome a seleccionar, quer seja para um nodo ou para um atributo.

Como podemos constatar a sintaxe é reduzida e muito similar ao que utilizamos da linha de comandos do Windows ou no Unix com apenas algumas características próprias.

Existem apenas alguns comandos bastantes úteis e utilizados que devemos reter e que normalmente chamam wild-cards. Importa salientar que também existem em praticamente todas as linguagens de programação:

 

*                                            -> Selecciona um qualquer nodo do tipo elemento.

@*                                        -> Selecciona um qualquer nodo do tipo atributo

nodo()                 -> Selecciona um nodo de qualquer tipo

 

Por último, uma wilcard bastante poderosa e que presumo que será bem entendida pelos utilizadores de BizTalk, um pipeline:

 

|           -> Este wild-card, pipeline ou somente pipe corresponde ao AND lógico.

 

Agora que já conhecemos a sintaxe básica, umas palavras sobre a formulação de um URL ou PATH para um nodo. Existem duas formas de definir um caminho como já se sabe de todo um conjunto de outras linguagens: absoluto ou relativo.

Se optarmos por um caminho absoluto temos de começar obrigatoriamente pelo componente Xpath “/” (slash, sem as aspas), isto porque a raiz de um caminho absoluto é o elemento mais acima de uma hierarquia e como não há nada acima do root node é ele o primeiro.

Se por outro lado utilizarmos um caminho relativo podemos começar numa qualquer parte do documento xml.

As vantagens de utilizar caminhos absolutos versus caminhos relativos é muito discutida pelo que eu prefiro caminhos relativos não vá eu pretender fazer alterações no XML e terei de mudar igualmente o Xpath, no entanto absoluto é muito mais fácil de ler.

O Xpath suporta outras componentes como operadores lógicos e matemáticos bem como a implementação de “axes” que abordarei noutro post por não achar que será algo com que quem começa se deva preocupar, não deixando de ser muito importantes.

 

=== Exercício Prático ===

 

Consideremos o seguinte documento XML:

 

<?Xml version=”1.0″ encoding=”ISO-8859-1″?>

 

<listaPessoas>

<pessoa sexo=”masculino” idade=”22″>

<nome>Rui Machado</nome>

<morada>Rua de Cima</morada>

<codigoPostal>4430</codigoPostal>

<numPorta>130</numPorta>

<distrito>Porto</distrito>

<email>ruimachado@live.com.pt</email>

</pessoa>

<pessoa sexo=”feminino” idade=”22″>

<nome>Vanessa Sousa</nome>

<morada>Rua de Baixo</morada>

<codigoPostal>4430</codigoPostal>

<numPorta>777</numPorta>

<distrito>Porto</distrito>

<email>vanessa@omail.com</email>

</pessoa>

<pessoa sexo=”masculino” idade=”34″>

<nome>Fernando Machado</nome>

<morada>Rua de Meio</morada>

<codigoPostal>4430</codigoPostal>

<numPorta>2121</numPorta>

<distrito>Porto</distrito>

<email>fmachado@gmaily.com</email>

</pessoa>

<namespace:pessoa xmlns:namespace=”uri:meunamespace”>

<namespace:Nome>Eu</namespace:Eu>

<namespace:Idade>22</namespace:Idade>

</namespace:pessoa>

</ListaPessoas>

 

Q1 – Selecionar todos os nomes da lista de pessoas

R: /ListaPessoas/pessoa/nome

 

Q2 – Seleccionar o número de porta do terceiro elemento

R2: /ListaPessoas/pessoa[3]/numPorta

 

NOTA: O w3c definiu que o primeiro elemento corresponde ao índice 1, no entanto o internet Explorer encara o primeiro elemento como o 0.

 

Q3 – Selecciona as pessoas cujo distrito é Porto

R: /ListaPessoas/pessoa[distrito=’Porto’]/distrito

 

Neste query estamos a dizer claramente ao xpath, seleciona da lista de pessoas todas as pessoas cujo distrito é porto e mostra o distrito. Caso não quiséssemos ver o distrito podíamos somente fazer /ListaPessoas/pessoa[distrito=’Porto’] e mostraria só o nome da pessoa.

 

Q4 – Todas as pessoas dentro da lista de pessoas

R: ListaPessoas/*

 

Q5 – A idade da primeira pessoa

R: ListaPessoas/pessoa[1]/@idade

 

Q6 – Todas as pessoas com atributo sexo

R: ListaPessoas/pessoa[@sexo]

 

Q7 – Todos os atributos existentes no namespace actual

R: @namespace:*

 

Q7 – Todos os elementos existentes no namespace actual

R: namespace:*

 

Q8 – O nome da primeira pessoa, a idade da segunda e o distrito da terceira

R: ListaPessoa/pessoa[1]/nome | ListaPessoa/pessoa[2]/idade | ListaPessoa/pessoa[3]/distrito

Anúncios

Deixe uma Resposta

Preencha os seus detalhes abaixo ou clique num ícone para iniciar sessão:

Logótipo da WordPress.com

Está a comentar usando a sua conta WordPress.com Terminar Sessão / Alterar )

Imagem do Twitter

Está a comentar usando a sua conta Twitter Terminar Sessão / Alterar )

Facebook photo

Está a comentar usando a sua conta Facebook Terminar Sessão / Alterar )

Google+ photo

Está a comentar usando a sua conta Google+ Terminar Sessão / Alterar )

Connecting to %s