Guia para aula de laboratório

O guia da 1º aula de laboratório está disponível online. Os tópicos abordados incluem conceitos básicos relacionados com a linguagem XML, XSD e XSLT.

XML

A eXtensible Markup Language (XML) (em tradução livre: linguagem de "tags" extensível) é um formato de representação de dados em texto. As partes do texto são etiquetadas para lhes atribuir significado específico. As tags são representadas da seguinte forma:

  • Abertura: <elem>
  • Fecho: </elem>
  • Abertura e fecho imediato: <elem />
  • Atributo: <elem atrib="value" />
Segue-se um exemplo simples para a representação de uma mensagem em XML:

<mensagem xmlns="urn:empresa.pt:mensagem" id="74536">
<!-- isto é um comentário -->
<de>Bruno</de>
<para>Helena</para>
<assunto>Reunião</assunto>
<texto>Confirmo a reunião dia 18</texto>
</mensagem>


As principais utilizações actuais da XML são:
  • Troca de dados entre aplicações: alternativa a formatos proprietários.
  • Ficheiros de configuração de aplicações informáticas.
  • Desenvolvimento de sistemas distribuídos segundo o paradigma dos "Web services".

Documentos XML bem-formados

Um documento XML diz-se bem-formado quando respeita as seguintes regras:

  • Existe um elemento raiz único
  • Todos os elementos têm que ser fechados
  • Os elementos fecham pela ordem inversa em que abrem, i.e., têm de estar encadeados
  • Os elementos têm de começar por uma letra ou 'underscore' (_)
  • Os nomes são 'case sensitive'

O significado atribuído pelas etiquetas é livre, o que torna a linguagem extensível.

Representação de dados em XML

A linguagem XML pode ser utilizada para representar diferentes tipos de dados. Os dados podem ser simples ou compostos. Os dados simples representam valores que podem ter vários tipos, incluindo texto, numéricos e datas. Os dados compostos resultam da combinação de vários dados simples. São normalmente estruturas de dados (registos com vários campos) ou vectores (vários valores semelhantes indexados), em que cada elemento é um dado simples.

Por exemplo, para representar o nome de uma pessoa em XML, as seguintes alternativas são válidas:

<nome>Bruno Emanuel Martins</nome>

ou

<nome>
<primeiro>Bruno</primeiro>
<meio>Emanuel</meio>
<apelido>Martins</apelido>
</nome>


ou ainda

<nome>
<primeiro>Bruno</primeiro>Emanuel Martins
</nome>


Na primeira, o nome foi considerado um dado simples. Na segunda, foi considerado um dado composto, que se dividiu em três partes. Qual a melhor opção? Depende do fim a que se destinam os dados.

Espaços de nomes

Os espaços de nomes XML (namespaces) são uma forma de qualificar os nomes das tags, para evitar conflitos de nomes. Por exemplo, o nome de tag 'mensagem' é um nome bastante comum. Tanto pode aparecer nos formatos XML de uma aplicação de uma empresa, em que tem uma dada estrutura:

<mensagem xmlns="urn:empresa.pt:mensagem" id="49532">
<de>Bruno</de>
<para>Helena</para>
<assunto>Almoço</assunto>
<texto>Que tal um almoço na sexta?</texto>
</mensagem>


Como nos formatos XML de outra aplicação de outra empresa, em que pode ter outra estrutura:

<mensagem xmlns="urn:outraempresa.pt:sisenc">
<prioridade>Urgente</prioridade>
<remetente>Loja</remetente>
<destinatario>Armazém</destinatario>
<conteudo>
<encomenda nr="20031">
<produto numSerie="282831031" />
<produto numSerie="243498333" />
</encomenda>
</conteudo>
</mensagem>


Neste exemplo, não só a estrutura que é diferente, mas também o próprio significado das tags.

Para evitar confusões no tratamento automático de dados, é necessário qualificar os nomes das tags com um espaço de nomes. A forma de o fazer é através do atributo xmlns, como é mostrado nos exemplos anteriores.

Caso existam vários espaços de nomes em utilização no mesmo documento, cada xmlns deve definir um prefixo, como xmlns:en1="urn:empresa.pt:mensagem" e xmlns:en2="urn:outraempresa.pt:sisenc": mensagensJuntas.xml

<mensagensJuntas xmlns:en1="urn:empresa.pt:mensagem"
xmlns:en2="urn:outraempresa.pt:sisenc">
<en1:mensagem en1:id="49532">
<en1:de>Bruno</en1:de>
<en1:para>Helena</en1:para>
<en1:assunto>Almoço</en1:assunto>
<en1:texto>Que tal um almoço na sexta?</en1:texto>
</en1:mensagem>

<en2:mensagem>
<en2:prioridade>Urgente</en2:prioridade>
<en2:remetente>Loja</en2:remetente>
<en2:destinatario>Armazém</en2:destinatario>
<en2:conteudo>
<en2:encomenda en2:nr="20031">
<en2:produto en2:numSerie="282831031" />
<en2:produto en2:numSerie="243498333" />
</en2:encomenda>
</en2:conteudo>
</en2:mensagem>
</mensagensJuntas>


en1:mensagem é uma abreviatura de {urn:empresa.pt:mensagem}mensagem. en2:mensagem é uma abreviatura de {urn:outraempresa.pt:sisenc}mensagem. Sendo assim, não há confusão. Uma aplicação usa o elemento en1:mensagem que tem uma definição e a outra aplicação usa o elemento en2:mensagem que tem outra definição.

O espaço de nomes é uma cadeia de caracteres que deve ser única. Por este motivo, tipicamente são utilizados endereços Internet (URLs), como "http://www.ist.utl.pt/" que são pertença de uma dada entidade (neste exemplo, o endereço é pertença do IST, da UTL, de Portugal).

A utilização de uma cadeia de caracteres como "http://www.ist.utl.pt/" serve apenas para garantir que é uma cadeia de caracteres única no mundo, não serve para obter nenhum documento pela rede.

Documentos XML válidos

Um documento XML diz-se válido se, além de ser bem-formado, respeita também as restrições impostas por um esquema XSD (XML Schema Definition). Um esquema XSD especifica um vocabulário XML, que define:
  • Os elementos que podem existir num documento.
  • Os atributos que podem existir num documento.
  • Que elementos são elementos filhos.
  • Qual a ordem dos elementos filhos.
  • Qual o número de elementos filhos.
  • Se um elemento é vazio ou pode conter texto.
  • Tipos de dados para elementos e atributos.
  • Valores fixos ou por omissão para elementos e atributos.
Exemplo simples:

<mensagem xmlns="urn:empresa.pt:mensagem"
id="49532"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:empresa.pt:mensagem mensagem.xsd">
<de>Bruno</de>
<para>Helena</para>
<assunto>Almoço</assunto>
<texto>Que tal um almoço na sexta?</texto>
</mensagem>


A linha xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" indica que o documento deve ser validado usando XSD. A linha xsi:schemaLocation="urn:empresa.pt:mensagem mensagem.xsd" especifica onde o esquema reside (neste caso, estará na mesma directoria do ficheiro). Existe também a variante xsi:noNamespaceSchemaLocation quando o documento a validar não está num espaço de nomes. Segue-se o esquema XSD relativo ao exemplo apresentado anteriormente:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="urn:empresa.pt:mensagem"
xmlns:tns="urn:empresa.pt:mensagem"
elementFormDefault="qualified">
<xsd:complexType name="MensagemType">
<xsd:sequence>
<xsd:element name="de" type="xsd:string"/>
<xsd:element name="para" type="xsd:string"/>
<xsd:element name="assunto" type="xsd:string" minOccurs="0" maxOccurs="1"/>
<xsd:element name="texto" type="xsd:string"
minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:element name="mensagem" type="tns:MensagemType"/>
</xsd:schema>


A própria linguagem XSD é definida em XML! O elemento raíz chama-se 'schema'. O exemplo apresentado é típico em vários aspectos:
  • A definição dos tipos compostos (complexType) é separada da definição dos elementos (element), para garantir uma boa estruturação e ao mesmo tempo permitir maior reutilização.
  • Os elementos simples são definidos recorrendo a tipos pré-definidos, nomeadamente, xsd:string. Outros tipos pré-definidos comuns são xsd:integer e xsd:date, mas existem muitos outros.
  • Os elementos compostos são sequências de elementos, definidas num tipo complexo. Pode também ser utilizado o elemento <xsd:choice>para definir elementos compostos com base na escolha de elementos mais simples.
Existem outros aspectos a salientar:
  • A cardinalidade (número de elementos filhos) é definida pelos atributos 'minOccurs' e 'maxOccurs'. Os valores por omissão são 1 e 1. Nesse caso, o elemento deve aparecer no mínimo uma vez e no máximo uma vez, ou seja, exactamente uma vez!
  • Os atributos são opcionais por omissão, mas o atributo 'id' é obrigatório devido a ter sido definido: use="required".

A linguagem XSLT

A XSLT é uma linguagem que permite expressar transformações de documentos XML, i.e. adicionar, remover, transformar e re-arranjar elementos e atributos . Permite por exemplo especificar regras para transformar um documento XML num documento XHTML, ou em qualquer outro formato XML.

A linguagem XSLT usa expressões XPath para definir quais as partes do documento XML de origem que deverão ser alvo de uma transformação, sendo que a mesma se processa depois através da aplicação de um template. Quando um "match" é feito no documento de origem, as regras expressas no template XSLT irão transformar a parte correspondente à expressão XPath no novo conjunto de elementos e atributos expresso no template.

Tome-se como exemplo o seguinte documento XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
</catalog>

Pode-se então considerar o seguinte documento XSLT (cdcatalog.xsl), o qual define um template de transformação:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:template match="/">
<html>
<body>
<h2>Os meu(s) disco(s) preferido(s)</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th align="left">Title</th>
<th align="left">Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<xsl:sort select="artist"/>
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

Após a aplicação desta XSLT, o resultado seria um documento XHTML contendo uma tabela com a informação sobre o CD. Pode-se ver no exemplo que o elemento <xsl:template> é usado para definir templates. O atributo match é usado para associar o template a um elemento XML no documento de origem através de uma expressão XPath (i.e. match="/" significa que o template será aplicado a todo o documento).

O exemplo ilustra ainda a utilização de alguns dos elementos XSLT mais importantes:
  • XSLT <template> - usado para definir templates de transformação. Pode ser usado em conjunto com o elemento <apply-templates>
  • XSLT <value-of> - usado para extrair o valor de um elemento XML e para o adicionar ao output da transformação
  • XSLT <for-each> - usado para seleccionar todos os elementos XML de um dado conjunto
  • XSLT <sort>- usado para ordenar os resultados (tipicamente dentro de um elemento <for-each>)
  • XSLT <if> - usado para construir testes condicionais sobre o conteúdo de um elemento XML
  • XSLT <choose> - usado em conjunto com os elementos <when> e <otherwise> para expressar testes condicionais múltiplos

A linguagem XSLT inclui ainda mais de 100 funções definidas internamente, as quais podem ser associadas às expressões XPath. Existem funções para processamento de strings, processamento de valores numéricos, comparações de datas, manipulação de elementos XML, etc. Para mais informações deverá ser consultada a especificação ou guias de referência sobre a linguagem. Na aula prática sobre XQuery irá ser abordada a sintaxe das expressões XPath em maior detalhe.

Ferramentas para processamento de documentos XML: JAX-P e browsers Web modernos

Existem vários editores "gráficos" que facilitam o processo de criação e edição de esquemas XSD, documentos XSLT e documentos XML em geral. Dois exemplos são o ambiente de desenvolvimento Eclipse e o Microsoft XML Notepad/XML Schema Designer.

Além destas ferramentas específicas, praticamente todos os Web browsers modernos incluem suporte para XML e XSLT. Por exemplo no FireFox, para visualizar um documento XML basta abri-lo normalmente no browser. Ao mostrar o documento, o browser usa um código de cores para distinguir os elementos e os atributos XML, sendo ainda possível navegar pela estrutura do documento expandindo ou escondendo elementos específicos. Os dois exemplos que se seguem podem ser utilizados para testar as funcionalidades de visualização de documentos XML no broswer.

Para se utilizar um browser Web na aplicação de transformações XSLT, o documento XML de origem deverá fazer referência ao documento XSLT a aplicar. Voltando a um exemplo anterior, ao abrir o seguinte documento num browser iriam ser aplicados os templates de transformação expressos no ficheiro cdcatalog.xsl (o código do ficheiro cdcatalog.xsl foi mostrado no parágrafo sobre XSLT):

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="cdcatalog.xsl"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
</catalog>

As linguagens de programação e ferramentas de desenvolvimento modernas também incluem praticamente todas suporte para o processamento de documentos XML. Por exemplo no universo Java, a Java API for XML Processing (JAX-P) é a biblioteca standard da plataforma para processamento de documentos XML. Esta biblioteca suporta dois modelos tradicionais de processamento: SAX e DOM; suporta também um modelo mais recente, designado por StAX. Não se pode dizer que um dos modelos de processamento seja "melhor" que os outros. A melhor escolha depende dos requisitos de utilização.

SAX

SAX significa Simple API for XML. O SAX processa um documento XML em série, transformando uma sequência de caracteres numa sequência de eventos: início de documento, início de elemento, atributo, fim de elemento, fim de documento. Faz mais sentido usar SAX quando se pretende processar documentos muito grandes sem precisar de aceder a toda a informação em simultâneo.

DOM

DOM significa Document Object Model. O DOM tira partido do interpretador SAX e trata os eventos que são gerados. Em resposta aos eventos, contrói uma árvore em memória. Nesta árvore todo o conteúdo do documento XML é representado em nós: elementos, atributos, texto e até comentários! A manipulação de árvore em memória é conveniente quando pretendemos manter a informação em memória para ser modificada interactivamente.

Os excertos de código seguintes ilustram como criar, ler e apagar nós de uma árvore XML.

// create
Element root = (Element) document.createElement("rootElement");
document.appendChild(root);
root.appendChild(document.createTextNode("Some"));
root.appendChild(document.createTextNode(" "));
root.appendChild(document.createTextNode("text"));
...
// read
getFirstChild();
getParent();
getNextSibling();
getPreviousSibling();
...
// delete
removeAllChildren();
removeFromParent();
removeChild(index);
removeChild(node);


Associado ao modelo DOM existe a linguagem XPath que permite uma forma declarativa de aceder a nós da árvore.

O excerto seguinte mostra uma expressão XPath que, utilizando o exemplo anterior do ficheiro XML descrevendo uma mensagem, selecciona todo o texto da mensagem destinada a Bruno (mais exactamente, selecciona o texto sob o nó 'texto', contido no nó 'mensagem' cujo sub-nó 'para' tem o valor 'Bruno').

//msg:mensagem[msg:para='Bruno']/msg:texto/text()


StAX

StAX significa Streaming API for XML. O StAX também processa um documento XML em série, sendo por isso semelhante ao SAX. A diferença é que o controlo de processamento do programa fica do lado da aplicação e do lado da biblioteca. O StAX corresponde a uma mistura entre SAX e DOM, procurando as vantagens de ambos.

Exemplos

O ficheiro xml.zip ( http://web.tagus.ist.utl.pt/~bruno.martins/materials/class-materials/labs-gti/xml/xml.zip ) inclui exemplos na linguagem Java relativos ao processamento de documentos XML. Os exemplos cobrem:
  • SAX - geração de eventos de leitura de documento
  • DOM - leitura de documento e construção de árvore, navegação, modificação e escrita
  • Validation - validação de documento XML com esquema XSD
  • XPath - navegação em árvore DOM através da avaliação de expressões XPath
  • XSLT - linguagem de transformação de XML
Links