Guia de aula laboratorial

O guia da 7º aula prática está disponível online. Os tópicos abordados incluem conceitos relacionados com a integração de dados definidos em XML com dados provenientes de fontes não-XML.

Integração de dados provenientes de fontes não-XML

Nesta aula prática iremos ver como mapear ficheiros de dados em formatos proprietários, por exemplo ficheiros de texto com valores separados por virgulas ou pelo caracter "tab" (CSV), em documentos XML, para posteriormente se poderem utilizar os dados em processos genéricos de integração de informação. Iremos ainda apresentar uma visão geral sobre ferramentas de software para a definição de tarefas complexas de integração de dados (i.e. ferramentas de ETL).

Nos exemplos que se seguem, iremos usar um processador de XQuery open source denominado Saxon ( http://saxon.sourceforge.net/ ). Na sua versão mais recente, esta ferramenta implementa os standards XQuery 1.0 e XPath 2.0. Para utilizar, o ficheiro saxon8.jar deve ser colocado no "classpath" do Java. As interrogações XQuery podem ser criadas usando um qualquer editor de texto, sendo que na linha de comandos poderão ser executadas através da instrução java -cp saxon8.jar net.sf.saxon.Query ficheiro-query.txt

O ficheiro xquery.zip ( http://web.tagus.ist.utl.pt/~bruno.martins/materials/class-materials/labs-gti/xquery/xquery.zip ) inclui a ferramenta saxon assim como alguns ficheiros de teste.

Conversão de ficheiros XML em ficheiros CSV

Enquanto que muitas aplicações modernas aceitam directamente input em XML, existem muitas aplicações antigas que não oferecem tais funcionalidades. Uma forma de importar dados em XML para utilização nestas aplicações passa por converter os documentos XML em documentos no formato CSV. A XSLT que se segue ilustra como isto pode ser feito:

<?xml version="1.0"?>

<xsl:stylesheet version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="//movie"><xsl:value-of select="normalize-space(name)"/>,<xsl:value-of select="normalize-space(year)"/>,<xsl:value-of select="normalize-space(genre)"/></xsl:template>
</xsl:stylesheet>
Note-se que o código de exemplo define o método de output como "text", usando diferentes expressões XPath para recuperar a informação a incluir no documento de saída. O processo de conversão poderia ainda ser obtido por uma XQuery equivalente, tendo-se que como exercício se sugere a construção dessa XQuery.

Conversão de ficheiros CSV em ficheiros XML

O standard XSLT 2.0 introduziu uma função unparsed-text() que retorna o conteúdo de um ficheiro externo na forma de uma string, assim como funções para a aplicação de expressões regulares ao conteúdo textual de um elemento XML. Com base nestas funções, torna-se possível definir em XSLT processos de extracção e transformação de dados a partir de ficheiros de texto.

A XSLT que se segue permite converter um ficheiro de texto com valores separados por virgulas de nome csv.csv num ficheiro XML. Para executar esta transformação é necessário recorrer a uma ferramenta que suporte XSLT 2.0, tal como o Saxon. De uma linha de comandos, poderá ser usada a instrução como java -cp saxon8.jar net.sf.saxon.Transform -s ficheiro.xml fixheiro.xslt para executar a transformação XSLT.
<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<!-- The tab delimited document, relative to the stylesheet location or an absolute location -->
<xsl:param name="doc" select="'sample.txt'"/>
<!-- The encoding for the tab delimited document -->
<xsl:param name="enc" select="'UTF-8'"/>

<!-- The result XML root element name -->

<xsl:param name="root" select="'file'"/>

<!-- The result XML element name that will mark the values from a line -->

<xsl:param name="line" select="'line'"/>

<!-- The result XML element name that will mark each value from the input document -->

<xsl:param name="entry" select="'entry'"/>

<!-- main template -->

<xsl:template match="/">

<xsl:element name="{$root}">

<xsl:call-template name="tLines">

<xsl:with-param name="value" select="unparsed-text($doc, $enc)"/>

</xsl:call-template>

</xsl:element>

</xsl:template>

<!-- tokenize lines -->

<xsl:template name="tLines">

<xsl:param name="value" select="''"/>

<xsl:analyze-string select="$value" regex="\n|\r">

<xsl:matching-substring/>

<xsl:non-matching-substring>

<xsl:element name="{$line}">

<xsl:call-template name="tValues">

<xsl:with-param name="value" select="."/>

</xsl:call-template>

</xsl:element>

</xsl:non-matching-substring>

</xsl:analyze-string>

</xsl:template>

<!-- tokenize values -->

<xsl:template name="tValues">

<xsl:param name="value" select="''"/>

<xsl:analyze-string select="$value" regex=",">

<xsl:matching-substring/>

<xsl:non-matching-substring>

<xsl:element name="{$entry}">

<xsl:value-of select="."/>

</xsl:element>

</xsl:non-matching-substring>
</xsl:analyze-string>

</xsl:template>

</xsl:stylesheet>

Tomando-se como entrada o seguinte texto de exemplo:

a1, a2, a3, a4
v1, v2, v3, V4
X1, X2, X3, X4
Seria produzido o seguinte ficheiro XML como saída:
<?xml version="1.0" encoding="UTF-8"?>

<file>
<line>
<entry>a1</entry>
<entry>a2</entry>
<entry>a3</entry>
<entry>a4</entry>
</line>
<line>
<entry>v1</entry>
<entry>v2</entry>
<entry>v3</entry>
<entry>V4</entry>
</line>
<line>
<entry>X1</entry>
<entry>X2</entry>
<entry>X3</entry>
<entry>X4</entry>
</line>
</file>
Uma vez gerado um ficheiro XML com o conteúdo, esta informação poderá ser integrada através dos mecanismos de integração de dados baseados em XQuery que foram apresentados na aula de laboratório anterior.

Tanto a XSLT como a XQuery têm acesso às funções matches(), replace() e tokenize(), as quais facilitam bastante tarefas de processamento de strings. A função matches() testa a correspondência de uma string com uma expressão regular, enquanto que a função replace() faz substituições em strings com base em expressões regulares. A função tokenize() aceita um separador sob a forma de uma expressão regular e retorna os vários "tokens" presentes numa string. Ha no entanto que referir que em XQuery não existe um equivalente à função unparsed-text(), embora algumas implementações ofereçam funcionalidades equivalentes através de extensões proprietárias.

No processador de XQuery Saxon, uma forma de utilizar dados provenientes de ficheiros de texto CSV numa XQuery passa por editar o ficheiro de texto por forma a incluir um cabeçalho XML sob os dados, podendo depois utilizar-se as funções associadas ao processamento de strings com expressões regulares.

Integração de dados com ferramentas de ETL ( Extraction, Transformation, Loading )

Até agora vimos como se podem utilizar as tecnologias normalmente associadas ao processamento de ficheiros XML (i.e. XSLT e XPath) para a definição de processos simples de integração de informação. No entanto, o processo analisado até agora não se adequa a tarefas mais complexas, possivelmente envolvendo a integração de várias fontes de informação de tipos diferentes (e.g. bases de dados relacionais, ficheiros de texto, ...). Mesmo em exemplos simples envolvendo a integração de ficheiros de texto CSV com ficheiros XML já são evidentes várias limitações neste processo.

Em casos práticos de grandes projectos, a definição de processos complexos de integração de informação passa pela utilização de ferramentas desenhadas para esse efeito, normalmente designadas por ferramentas de ETL (acrónimo para Extraction, Transformation and Loading). Estas ferramentas permitem lidar de uma forma integrada com a extracção, transformação e limpeza de dados provenientes de várias fontes. Mesmo no universo opensource existem já várias ferramentas ETL disponíveis, sendo que abaixo se apresenta uma lista das mais conhecidas:

Aos alunos com mais curiosidade sobre este assunto aconselha-se uma consulta à documentação e demonstrações disponíveis para as ferramentas listadas acima. Por exemplo a demonstração disponível no URL http://www.apatar.com/demo/web_demo_5/Apatar_RSS_Aggregation.htm , mostra como integrar um conjunto de feeds RSS usando a ferramenta Apatar, a qual permite a definição de um pipeline de ETL através de uma linguagem visual.

Links