8.13. Tipo de dados XML #

8.13.1. Criação de valores XML
8.13.2. Tratamento da codificação
8.13.3. Acesso aos valores XML

O tipo de dados xml é usado para armazenar dados XML. Sua vantagem com relação a armazenar dados XML em um campo text, é que ele verifica se os valores da entrada estão bem formados, e há funções de suporte para realizar operações seguras sobre esse tipo de dados; veja a Seção 9.15. O uso desse tipo de dados requer que a instalação do PostgreSQL tenha sido construída com configure--with-libxml.

O tipo de dados xml pode armazenar documentos bem formados, conforme definido pelo padrão XML, assim como fragmentos de conteúdo, referindo-se ao nó de documento mais permissivo dos modelos de dados XQuery [51] e XPath [52]. Grosso modo, isso significa que os fragmentos de conteúdo podem ter mais de um elemento de nível superior ou nó de caractere. A expressão xmlvalue IS DOCUMENT pode ser usada para avaliar se um determinado valor xml é um documento completo, ou apenas um fragmento do conteúdo.

Limites e notas de conformidade para o tipo de dados xml podem ser encontrados na Seção D.3.

8.13.1. Criação de valores XML #

Para produzir um valor do tipo de dados xml a partir de dados do tipo de dados caractere deve ser usada a função xmlparse:

XMLPARSE ( { DOCUMENT | CONTENT } valor)

Exemplos:

XMLPARSE (DOCUMENT '<?xml version="1.0"?><book><title>Manual</title><chapter>...</chapter></book>')
XMLPARSE (CONTENT 'abc<foo>bar</foo><bar>foo</bar>')

Embora essa seja a única maneira de converter cadeias de caracteres em valores XML segundo o padrão SQL, as sintaxes específicas do PostgreSQL

xml '<foo>bar</foo>'
'<foo>bar</foo>'::xml

também podem ser usadas.

O tipo de dados xml não valida os valores de entrada com relação à declaração de tipo de documento (DTD), mesmo que o valor de entrada especifique uma DTD. Também não há no momento suporte nativo para validação em relação a outras linguagens de esquema XML, como XML Schema.

Para realizar a operação inversa, que produz um valor do tipo de dados cadeia de caracteres a partir do tipo de dados xml, deve ser usada a função xmlserialize:

XMLSERIALIZE ( { DOCUMENT | CONTENT } valor AS tipo_de_dados [ [ NO ] INDENT ] )

tipo que pode ser character, character varying ou text (ou um alias para um destes). Novamente, de acordo com o padrão SQL esta é a única maneira de converter entre o tipo de dados xml e tipos de dados de caractere, mas o PostgreSQL também permite que você simplesmente converta o valor.

A opção INDENT faz com que o resultado seja formatado de forma legível, enquanto NO INDENT (que é o padrão) apenas mostra a cadeia de caracteres de entrada original. Converter para um tipo de dados de caractere também produz a cadeia de caracteres original.

Quando o valor de uma cadeia de caracteres é convertida de/para um tipo de dados xml sem passar por XMLPARSE ou XMLSERIALIZE, respectivamente, a escolha entre DOCUMENT versus CONTENT é determinada pelo parâmetro de configuração da sessão XML OPTION, que pode ser definido usando o comando padrão

SET XML OPTION { DOCUMENT | CONTENT };

ou usando a sintaxe mais do tipo PostgreSQL

SET xmloption TO { DOCUMENT | CONTENT };

O padrão é CONTENT, portanto são permitidas todas as formas de dados XML.

8.13.2. Tratamento da codificação #

Deve-se tomar cuidado ao lidar com codificações de caracteres diferentes no cliente, no servidor e nos dados XML passados por eles. Ao usar o modo texto para enviar consultas ao servidor e resultados de consultas ao cliente (que é o modo normal), o PostgreSQL converte todos os dados de caracteres passados ​​entre o cliente e o servidor, e vice-versa, para a codificação de caracteres da respectiva extremidade; veja a Seção 23.3. Isto inclui representações em formato de cadeias de caracteres de valores XML, como nos exemplos acima. Normalmente, isto significa que as declarações de codificação contidas em dados XML podem se tornar inválidas à medida que os dados de caracteres são convertidos para outras codificações durante a transmissão entre o cliente e o servidor, porque a declaração de codificação incorporada não é alterada. Para lidar com este comportamento, as declarações de codificação contidas nas cadeias de caracteres apresentadas como entrada para o tipo de dados xml são ignoradas, e assume-se que o conteúdo esteja na codificação corrente do servidor. Consequentemente, para um processamento correto, as cadeias de caracteres dos dados XML devem ser enviadas pelo cliente na codificação corrente do cliente. É responsabilidade do cliente converter os documentos para a codificação corrente do cliente antes de enviá-los ao servidor, ou ajustar a codificação do cliente adequadamente. Na saída, os valores do tipo de dados xml não terão uma declaração de codificação e os clientes devem assumir que todos os dados estão na codificação corrente do cliente.

Ao usar o modo binário para passar parâmetros de consulta para o servidor e os resultados da consulta de volta para o cliente, nenhuma conversão de codificação é executada, portanto a situação é diferente. Nesse caso, a declaração de codificação nos dados XML será observada e, se estiver ausente, os dados serão assumidos como UTF-8 (conforme exigido pelo padrão XML; observe que o PostgreSQL não tem suporte para UTF-16). Na saída, os dados terão uma declaração de codificação especificando a codificação do cliente, a menos que a codificação do cliente seja UTF-8, caso onde será omitida.

É desnecessário dizer que o processamento de dados XML com o PostgreSQL será menos propenso a erros e mais eficiente se a codificação dos dados XML, a codificação do cliente e a codificação do servidor forem as mesmas. Como os dados XML são processados internamente em UTF-8, os cálculos serão mais eficientes se a codificação do servidor também for UTF-8.

Cuidado

Algumas funções relacionadas a XML podem não funcionar em dados não ASCII quando a codificação do servidor não for UTF-8. Isso é conhecido por ser um problema para as funções xmltable() e xpath() em particular.

8.13.3. Acesso aos valores XML #

O tipo de dados xml é incomum, porque não fornece nenhum operador de comparação. Isso acontece, porque não existe um algoritmo de comparação bem definido e universalmente útil para os dados XML. Uma consequência disso é não se poder buscar linhas comparando uma coluna do tipo de dados xml com um valor de procura. Os valores XML devem ser, portanto, normalmente acompanhados por um campo-chave separado, como um ID. Uma solução alternativa para comparar valores XML é convertê-los primeiro em cadeias de caracteres, mas note-se que a comparação de cadeias de caracteres tem pouco a ver com um método útil de comparação XML.

Como não há operadores de comparação para o tipo de dados xml, não é possível criar um índice diretamente em uma coluna desse tipo de dados. Se for desejado fazer procuras rápidas em dados XML, as possíveis soluções alternativas incluem converter a expressão em um tipo de dados cadeia de caracteres e indexá-lo, ou indexar uma expressão XPath. Obviamente, a consulta real teria que ser ajustada para procurar pela expressão indexada.

A funcionalidade de procura de texto no PostgreSQL também pode ser usada para acelerar procuras de documentos completos de dados XML. Entretanto, o suporte de pré-processamento necessário ainda não está disponível na distribuição do PostgreSQL.



[51] XQuery está para XML o que SQL está para bancos de dados. XQuery é projetado para consultar dados XML. XQuery Tutorial (N. T.)

[52] XPath é um elemento importante no padrão XSLT. XPath pode ser usado para navegar pelos elementos e atributos em um documento XML. XPath Tutorial (N. T.)