Le type de données xml
est utilisé pour stocker des données
au format XML. Son avantage sur un champ de type text
est
qu'il vérifie que les valeurs sont bien formées. De plus, il existe de
nombreuses fonctions pour réaliser des opérations de vérification à partir
de ce type ; voir la Section 9.15. L'utilisation
de ce type de données requiert que l'étape de compilation ait utilisé
l'option --with-libxml
.
Le type xml
peut stocker des « documents » bien
formés, suivant la définition du standard XML, ainsi que des fragments
de contenu (« content »), en référence au « nœud
de document » plus permissif des modèle de données XQuery
et XPath. Cela signifie que les fragments de contenu peuvent avoir plus
d'un élément racine ou nœud caractère. L'expression
permet d'évaluer si une valeur valeurxml
IS DOCUMENTxml
particulière
est un document complet ou seulement un fragment de contenu.
Les limites et notes de compatibilité pour le type de données
xml
sont disponibles dans Section D.3.
Pour produire une valeur de type xml
à partir d'une donnée de
type caractère, utilisez la fonction xmlparse
:
XMLPARSE ( { DOCUMENT | CONTENT } valeur
)
Quelques exemples :
XMLPARSE (DOCUMENT '<?xml version="1.0"?><book><title>Manual</title><chapter>...</chapter></book>') XMLPARSE (CONTENT 'abc<foo>bar</foo><bar>foo</bar>')
Bien que cela soit la seule façon de convertir des chaînes de caractères en valeurs XML d'après le standard XML, voici des syntaxes spécifiques à PostgreSQL :
xml '<foo>bar</foo>' '<foo>bar</foo>'::xml
Le type xml
ne valide pas les valeurs en entrée par rapport
à une déclaration de type de document (DTD),
même quand la valeur en entrée indique une DTD.
Il n'existe pas encore de support pour la validation avec d'autres langages
de schéma XML, comme XML Schema.
L'opération inverse, produisant une chaîne de caractères à partir d'une
valeur au type xml
, utilise la fonction
xmlserialize
:
XMLSERIALIZE ( { DOCUMENT | CONTENT }value
AStype
[ [ NO ] INDENT ] )
type
peut être
character
, character varying
ou
text
(ou un alias de ces derniers). Encore une fois, d'après
le standard SQL, c'est le seul moyen de convertir le type
xml
vers les types caractère, mais PostgreSQL autorise aussi
la conversion simple de la valeur.
L'option INDENT
fait que le résultat sera joliment
formaté alors que NO INDENT
(qui est la valeur par
défaut) émet simplement la chaîne de texte originale. Convertir
vers un type caractère produit de la même façon la chaîne originale.
Lorsque les valeurs des chaînes de caractères sont converties vers ou à
partir du type xml
sans passer par XMLPARSE
ou
XMLSERIALIZE
, respectivement, le choix de
DOCUMENT
ou de CONTENT
est
déterminé par un paramètre de configuration niveau session,
« XML OPTION »
, qui peut être
configuré par la commande habituelle :
SET XML OPTION { DOCUMENT | CONTENT };
ou la syntaxe PostgreSQL :
SET xmloption TO { DOCUMENT | CONTENT };
La valeur par défaut est CONTENT
, donc toutes les formes
de données XML sont autorisées.
Une grande attention doit prévaloir lors de la gestion de plusieurs
encodages sur le client, le serveur ou dans les données XML qui
passent entre eux. Lors de l'utilisation du mode texte pour passer
les requêtes au serveur et pour renvoyer les résultats au client
(qui se trouve dans le mode normal), PostgreSQL convertit toutes les
données de type caractère passées entre le client et le serveur et
vice-versa suivant l'encodage spécifique de la destination finale ; voir la
Section 23.3. Cela inclut les représentations textuelles
des valeurs XML, comme dans les exemples ci-dessus, ce qui signifie
que les déclarations d'encodage contenues dans les données XML pourraient
devenir invalides lorsque les données sont converties vers un autre
encodage lors du transfert entre le client et le serveur, alors que la
déclaration de l'encodage n'est pas modifiée. Pour s'en sortir, une
déclaration d'encodage contenue dans une chaîne de caractères
présentée en entrée du type xml
est
ignorée, et le contenu est toujours supposé être de
l'encodage du serveur. En conséquence, pour un traitement correct,
ces chaînes de caractères de données XML doivent être envoyées du client
dans le bon encodage. C'est de la responsabilité du client de soit
convertir le document avec le bon encodage client avant de l'envoyer au
serveur, soit d'ajuster l'encodage client de façon appropriée. En sortie,
les valeurs du type xml
n'auront pas une déclaration
d'encodage et les clients devront supposer que les données sont dans
l'encodage du client.
Lors de l'utilisation du mode binaire pour le passage des paramètres de la requête au serveur et des résultats au client, aucune conversion de l'encodage n'est réalisée, donc la situation est différente. Dans ce cas, une déclaration d'encodage dans les données XML sera observée et, si elle est absente, les données seront supposées être en UTF-8 (comme requis par le standard XML ; notez que PostgreSQL ne supporte pas du tout UTF-16). En sortie, les données auront une déclaration d'encodage spécifiant l'encodage client, sauf si l'encodage client est UTF-8, auquel cas elle sera omise.
Le traitement des données XML avec PostgreSQL sera moins complexe et plus efficace si l'encodage des données, l'encodage client et l'encodage serveur sont identiques. Comme les données XML sont traitées en interne en UTF-8, les traitements seront plus efficaces si l'encodage serveur est aussi en UTF-8.
Certaines fonctions relatives à XML pourraient ne pas fonctionner du tout
sur des données non ASCII quand l'encodage du serveur n'est pas UTF-8. C'est
un problème connu pour xmltable()
et
xpath()
en particulier.
Le type de données xml
est inhabituel dans le sens où il ne
dispose pas d'opérateurs de comparaison. Ceci est dû au fait qu'il n'existe
pas d'algorithme de comparaison bien défini et utile pour des données XML.
Une conséquence de ceci est que vous ne pouvez pas récupérer des lignes en
comparant une colonne xml
avec une valeur de recherche. Les
valeurs XML doivent du coup être typiquement accompagnées par un champ
clé séparé comme un identifiant. Une autre solution pour la comparaison
de valeurs XML est de les convertir en des chaînes de caractères, mais
notez que la comparaison de chaînes n'a que peu à voir avec une
méthode de comparaison XML utile.
Comme il n'y a pas d'opérateurs de comparaison pour le type de données
xml
, il n'est pas possible de créer un index directement
sur une colonne de ce type. Si une recherche rapide est souhaitée dans
des données XML, il est toujours possible de convertir l'expression en
une chaîne de caractères et d'indexer cette conversion. Il est aussi
possible d'indexer une expression XPath. La vraie requête devra bien sûr
être ajustée à une recherche sur l'expression indexée.
La fonctionnalité de recherche plein texte peut aussi être utilisée pour accélérer les recherches dans des données XML. Le support du prétraitement nécessaire n'est cependant pas disponible dans la distribution PostgreSQL.