Você está na página 1de 3

Trabalhando com documentos XML no PostgreSQL -

Introduo

possvel integrar documentos XML e uma base relacional como o PostgreSQL, criando bases de
dados hbridas. J me deparei com situaes em que o modelo relacional puro seria extremamente
ineficiente e achei uma soluo utilizando documentos XML dentro da base relacional. Alm disso,
esto surgindo aplicaes de gerenciamento de documentos XML, que podem ter como base de
dados um banco relacional. O suporte ao XML no PostgreSQL feito com uma extenso presente no
diretrio contrib/xml. um trabalho baseado em uma biblioteca de funes para manipulao de
XML e de consultas XPath (uma linguagem de consulta para documentos XML) j existente chamada
libxml. A extenso prov basicamente duas funcionalidades ao PostgreSQL:

1. Validar documentos XML com base em um DTD (atravs da funo pgxml_parse);


2. Fazer consultas XPath nos documentos armazenados (atravs da funo pgxml_xpath).

Essas duas funcionalidades so fundamentais quando se utiliza armazenamento de documentos XML


na base de dados.

Instalao
O primeiro passo para utilizar as duas funes instalar o mdulo xml. Para compilar os fontes do
mdulo xml, independente de qual plataforma seja utilizada, necessrio baixar os fontes da libxml.
Para isso basta entrar no site ftp://xmlsoft.org/, copiar o arquivo (libxml2-2.5.6.tar.gz ou a verso
mais recente) e extrair os arquivos .h da pasta include para um diretrio criado por voc com o
nome de libxml dentro de contrib/xml.

cd diretorio_fontes_postgresql/contrib/xml
gmake
gmake install

Observao
importante observar que o pacote RPM postgresql-contrib do RedHat no instala esse mdulo
(pelo menos at o RedHat 8). Algumas verses do PostgreSQL, quando instaladas a partir do ports
do FreeBSD j vm com os arquivos da libxml.
Depois de instalar o mdulo, preciso executar os comandos SQL contidos no arquivo pgxml.sql
para criar as funes na base de dados em que voc vai utiliz-las.

Utilizao
Com a primeira funo, a pgxml_parse, podemos nos certificar de que o documento XML coerente
com a sua definio (o seu DTD), e assim podemos fazer consultas XPath tranquilamente no
documento, alm de manter a base ntegra. Essa funo torna possvel a criao de uma regra de
validao de XML na insero da linha que contm o documento. A funo a seguir poderia ser
utilizada para validar o conteudo de um documento contido na tabela "documentos" com o seu DTD
que est na tabela "formatos":

CREATE OR REPLACE FUNCTION validaXML(int4, int4) RETURNS bool AS


'
SELECT pgxml_parse((SELECT dtd FROM formatos WHERE formatos.codformato = $2) ||
CONVERT(documentos.conteudo, ''LATIN1'', ''UNICODE'')) FROM documentos WHERE documentos.coddocumento = $1;
'
LANGUAGE 'sql';

Na funo acima, o cdigo do documento passado como primeiro parmetro, e o segundo o


cdigo do formato (que indica qual DTD usar na validao), e a funo "CONVERT" utilizada para
converter a codificao do documento para UNICODE, pois as funes de manipulao de XML s
trabalham com UNICODE.
Alm disso, seria possvel criar at um tipo de dados especfico para armazenar XMLs, que faa
essas verificaes automaticamente, mas no vou me aprofundar nesse ponto, pois daria outro
artigo inteiro.
A segunda funo, a pgxml_xpath, possibilita a extrao de dados especficos de dentro do
documento XML consultado. Por exemplo, voc utiliza um campo que armazena documentos XML
representando as especificaes tcnicas de um determinado produto. Digamos que essa tabela de
produtos tenha a seguinte estrutura:

CREATE TABLE Produtos (


id_produto Serial,
id_tipo_produto,
nome varchar(50),
descricao text,
especificacoes_tecnicas text);

No campo especificacoes_tecnicas inserido um documento XML contendo todas as especifiaes do


produto. Esse XML poderia ser assim:

<especificacoes>
<medidas>
<peso>
13 Kg
</peso>
<altura>
1,77 m
</altura>
<largura>
1,50 m
</largura>
</medidas>
</especificacoes>

Caso eu queira listar todos os produtos do tipo 1 e seus respectivos pesos eu poderia usar um SQL
com a funo XPath:

SELECT nome, pgxml_xpath(string_contendo_dtd || especificacoes_tecnicas,


'//especificacoes/medidas/peso/text()','','') as peso
FROM Produtos
WHERE id_tipo_produto = 1;

Nesse caso, eu concatenei manualmente uma string contendo o DTD do documento XML no primeiro
parmetro da funo, que deve receber o documento XML a ser processado. No segundo parmetro,
eu passei uma string especificando a busca a ser realizada dentro do XML, no caso:
//especificacoes/medidas/peso/text() o que significa que eu quero o texto do item peso dentro do
item medidas dentro de especificaces. As duas barras (//) no incio da string indicam que todos os
itens filhos devem ser processados (no caso, todos os filhos de "especificacoes"), e o text() no fim
da string significa que eu quero retornar somente o contedo do item peso (segundo o exemplo,
seria: "13 Kg") e no o item inteiro (que seria: " 13 Kg ").
Poderamos usar um documento um pouco mais complexo para explorar melhor o potencial do
XPath, aproveitemos o exemplo anterior e vamos acrescentar atributos a alguns itens do XML:

<especificacoes>
<medidas>
<peso unidade="kg">
13 kg
</peso>
<peso unidade="lbs">
28,7 lbs
</peso>
<altura>
1,77 m
</altura>
<largura>
1,50 m
</largura>
</medidas>
</especificacoes>

Agora, digamos que eu queira o mesmo retorno do exemplo anterior (produtos do tipo 1 e seus
respectivos pesos), mas dessa vez eu quero filtrar os itens peso, para que ele me traga somente
aqueles que estiverem em libras:

SELECT nome, pgxml_xpath(string_contendo_dtd || especificacoes_tecnicas,


'//especificacoes/medidas/peso[@unidade=''lbs'']/text()','','') as peso
FROM Produtos WHERE id_tipo_produto = 1;
Claro que os exemplos utilizados aqui so muito simplrios, mas devem ilustrar o potencial dessa
ferramenta, pois assim como eu usei filtros em um determinado atributo, eu poderia usar uma srie
de outros recursos definidos pela linguagem XPath. Ainda seria possvel utilizar funes que facilitem
a busca por determinados grupos de informao, ou at funes que retornem o documento XML
como uma outra tabela. Outra possibilidade interessante seria o armazenamento de objetos em
formato xml na base de dados, de modo que eu possa fazer buscas nos objetos armazenados e
instanciar o objeto diretamente de um campo do banco de dados. Alm disso, existem vrias outras
possibilidades, s uma questo de criatividade e estudo.

A especificao da liguagem XPath pode ser lida em: http://www.w3.org/TR/xpath


Um site onde existe uma boa documentao sobre XPath o site da Microsoft:
http://msdn.microsoft.com/library/default.asp?url=/library/enus/xmlsdk/htm/
xpath_ref_overview_0pph.asp

Observao
Uma observao importante para quem pretende trabalhar com XML em PostgreSQL, que as
funes de XML s trabalham com textos codificados em UNICODE, e importante observar o
atributo encoding (codificao) do seu banco de dados. O encoding definido no momento da
criao do banco de dados no comando CREATE DATABASE. A codificao padro, utilizada quando
no se especifica nada no create database definida no comando initdb. Caso ele no
seja UNICODE, no se preocupe, o PostgreSQL tem uma funo de converso que pode ser utilizada
para transformar campos de uma codificao em outra, a funo convert:

convert('Texto', 'Codificao_Origem', 'Codificao_Destino')

Copyleft (c) por Diogo de Oliveira Biazus (diogo.biazus@pop.com.br)


Esse texto licenciado sob a licena GNU FDL .
GNU FDL: GPL-pt_BR.txt (http://www.postgresql.org.br/GPL-pt_BR.txt)

http://www.sqlmagazine.com.br/artigos/postgre/03_TrabalhandoComXML.asp