8.13. Type XML

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.14, « Fonctions XML ». L'utilisation de ce type de données requiert que l'étape de compilation a 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 »), qui sont définis par XMLDecl? content du standard XML. Cela signifie que les fragments de contenu peuvent avoir plus d'un élément racine ou nœud caractère. L'expression valeurxml IS DOCUMENT permet d'évaluer si une valeur xml particulière est un document complet ou seulement un fragment de contenu.

8.13.1. Créer des valeurs XML

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ère 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 AS type )
       

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.

Lorsque les valeurs des chaînes de caractère 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.

[Note]

Note

Avec le paramètrage par défaut des options XML, vous ne pouvez pas convertir directement des chaînes de caractères dans le type xml si elles contiennent une déclaration du type de document car la définition du fragment de contenu XML ne les accepte pas. Si vous avez besoin de changer cela, soit vous utilisez XMLPARSE soit vous changez l'option XML.

8.13.2. Gestion de l'encodage

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 du bout final ; voir la Section 22.3, « Support des jeux de caractères ». Ceci inclut les représentations textuelles des valeurs XML, comme dans les exemples ci-dessus. Ceci signifie que les déclarations d'encodage contenues dans les données XML pourraient devenir invalide 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 jeu de caractères 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 case 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 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.

[Attention]

Attention

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 xpath() en particulier.

8.13.3. Accéder aux valeurs XML

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.