Des révisions significatives des spécifications relatives au XML dans ISO/IEC 9075-14 (SQL/XML) ont été introduites avec SQL:2006. L'implémentation de PostgreSQL du type de données XML et des fonctions relatives suit largement l'édition 2003, avec quelques emprunts aux éditions ultérieures. En particulier :
Quand le standard actuel fournit une famille de types de données XML
pour contenir un « document » ou un « content »
dans des variants non typés ou typés XML Schema, et un type
XML(SEQUENCE)
pour contenir des parties arbitraires d'un
contenu XML, PostgreSQL fournit le seul type
xml
, qui peut contenir « document » ou
« content ». Il n'y a pas d'équivalent au type
« sequence » du standard.
PostgreSQL fournit deux fonctions introduites avec SQL:2006, mais des variantes qui utilisent le langage XPath 1.0, plutôt que XML Query comme indiqué dans le standard.
Cette section présente certaines des différences résultantes que vous pourriez rencontrer.
Les fonctions PostgreSQL
xpath()
et xpath_exists()
requêtent des documents XML en utilisant le langage XPath.
PostgreSQL fournit aussi les variantes XPath
des fonctions standards XMLEXISTS
et
XMLTABLE
, qui utilisent officiellement le langage
XQuery. Pour toutes ces fonctions, PostgreSQL
se base sur la bibliothèque libxml2, qui
fournit seulement XPath 1.0.
Il existe un lien fort entre le langage XQuery et XPath version 2.0 et ultérieures : toute expression qui est syntaxiquement valide et qui exécute avec succès dans les deux langages produit le même résultat (avec une exception mineure pour les expressions contenant des références numériques de caractères ou des références d'entités prédéfinies, que XQuery remplace avec le caractère correspondant alors que XPath les ignore). Mais il n'y a pas un tel lien entre ces langages et XPath 1.0 ; il s'agissait d'un langage précédent et il diffère en de nombreux aspects.
Il existe deux catégories de limitation à garder à l'esprit : la restriction de XQuery à XPath pour les fonctions spécifiées dans le standard SQL standard, et la restriction de XPath à version 1.0 pour les fonctions standards et spécifiques à PostgreSQL.
Les fonctionnalités de XQuery en dehors de celles d'XPath incluent :
Les expressions XQuery peuvent construire et rnevoyer de nouveaux nœuds XML, en plus de toutes les valeurs XPath possibles. XPath peut créer et renvoyer des valeurs des types atomiques (nombres, chaînes, et ainsi de suite) mais peut seulement renvoyer des nœuds XML qui étaient déjà présents dans les documents fournis en entrée de l'expression.
XQuery a des constructions de contrôle pour l'itération, le tri et le regroupement.
XQuery permet la déclaration et l'utilisation de fonctions locales.
Les versions XPath récentes commencent à offrir des possibilités
surchargeant celles-ci (comme for-each
et
sort
, les fonctions anonymes, et
parse-xml
pour créer un nœud à partir d'une
chaîne), mais ces fonctionnalités n'étaient pas disponibles avant XPath
3.0.
Pour les développeurs familiers avec XQuery et XPath 2.0 ou ultérieur, XPath 1.0 présente un certain nombre de différences :
Le type fondamental d'une XQuery/XPath, la sequence
, qui
peut contenir des nœuds XML, des valeurs atomiques, ou les deux,
n'existe pas dans XPath 1.0. Une expression 1.0 peut seulement
produire un ensemble de nœuds (contenant zéro ou plus de nœuds
XML), ou une simple valeur atomique.
Contrairement à une séquence XQuery/XPath, qui peut contenir tout élément désiré dans un ordre désiré, un ensemble de nœuds XPath 1.0 n'offre pas de garantie d'ordre et, comme tout ensemble, n'autorise pas plusieurs apparences du même élément.
La bibliothèque libxml2 ne semble pas toujours renvoyer des ensembles de nœuds à PostgreSQL avec tous leurs membres dans le même ordre relatif au document en entrée. Sa documentation ne garantie pas ce comportement, et une expression XPath 1.0 ne permet pas de la contrôler.
Alors que XQuery/XPath fournit tous les types définis dans un XML
Schema et de nombreux opérateurs et fonctions sur ces types, XPath
1.0 a seulement les ensembles de nœuds et les trois types atomiques
boolean
, double
et string
.
XPath 1.0 n'a pas d'opérateur conditionnel. Toute expression
XQuery/XPath telle que if ( hat ) then hat/@size else "no
hat"
n'a pas d'équivalent XPath 1.0.
XPath 1.0 n'a pas d'opération de comparaison de tri pour les chaînes.
"cat" < "dog"
et "cat" >
"dog"
sont faux parce que ce sont des comparaisons
numériques de deux valeurs NaN
. Par contre,
=
and !=
comparent les chaînes
en tant que chaînes.
XPath 1.0 brouille la distinction entre comparaisons de
valeurs et comparaisons générales
telles que XQuery/XPath les définit.sale/@hatsize =
7
et sale/@customer = "alice"
sont des
comparaisons quantifiées, vrai s'il existe au moins un
sale
avec la valeur donnée pour l'attribut, mais
sale/@taxable = false()
est une comparaison de
valeur pour la valeur booléenne réelle de
l'ensemble complet de nœuds. C'est vrai uniquement si aucun
sale
n'a d'attribut taxable
.
Dans le modèle de données XQuery/XPath, un nœud
document peut avoir soit une forme document (exactement
un élément de haut niveau, avec seulement des commentaires et des
instructions de traitement en dehors) ou une forme contenu (avec ces
contraintes diminuées). Son équivalent avec XPath 1.0, le
nœud racine, peut seulement être en forme
document. C'est une des raisons pour lesquelles une valeur
xml
passée à l'élément de contexte pour toute fonction
PostgreSQL basée sur XPath doit être dans
une forme document.
Les différences soulignées ici ne sont pas complètes. Dans XQuery et les versions 2.0 et ultérieures de XPath, il existe un mode de compatibilité XPath 1.0, et les listes W3C des modifications de fonctions et des modifications de langage appliqués dans ce mode offre une liste plus complète (bien que non exhaustive) des différences. Le mode de compatibilité ne peut pas rendre les nouveaux langages exactement équivalent à XPath 1.0.
Dans SQL:2006 et ultérieurs, les deux directions de conversion entre les types de données du standard SQL et les types XML Schema sont spécifiées précisément. Néanmoins, les règles sont exprimées en utilisant les types et sémantiques de XQuery/XPath, et n'ont pas d'application directe vers le modèle de données de XPath 1.0.
Quand PostgreSQL fait une correspondance des
valeurs de données SQL en XML (comme dans
xmlelement
), ou de XML vers SQL (comme dans les
colonnes en sortie de xmltable
), sauf pour quelques
cas traités spécifiquement, PostgreSQL
suppose simplement que la chaîne XPath 1.0 du type de données XML sera
valide sous la forme textuelle du type de données SQL, et inversement.
Cette règle a l'avantage de la simplicité tout en produisant pour de
nombreux types de données des résultats similaires aux correspondances
indiquées dans le standard. Dans cette version, une conversion explicite
est nécessaire si une expression de colonne
xmltable
produit une valeur booléenne ou
double ; voir Section D.3.2.
Quand l'interopérabilité avc d'autres systèmes est importante, pour certains types de données, il pourrait être nécessaire d'utiliser explicitement les fonctions de formatage des types de données (telles que celles disponibles dans Section 9.8) pour produire les correspondances standards.
Cette section concerne les limites qui ne sont pas inhérentes à la bibliothèque libxml2 mais s'appliquent à l'implémentation dans PostgreSQL.
xmltable
Une expression de colonne xmltable
évaluée en un
booléen ou nombre résultat XPath produira une erreur « unexpected
XPath object type ». Le contournement reviendra à réécrire
l'expression de colonne dans la fonction string
XPath ; PostgreSQL affectera alors la
valeur chaîne à une colonne SQL en sortie, de type boolean ou double.
Dans cette version, une expression de colonne
xmltable
qui évalue en un ensemble de nœuds XML
peut être assignée à une colonne résultat SQL d'un type XML, produisant
une concaténation de : pour la plupart des types de nœud dans
l'ensembl de nœuds, un nœud texte contenant la valeur
chaîne XPath 1.0 du nœud, mais pour un nœud élément, une
copie du nœud lui-même. Un tel ensemble de nœuds pourrait être affecté
à une colonne SQL d'un type non XML seulement si l'ensmble de nœuds a
un seul nœud, avec la valeur textuelle de la plupart des nœuds types
remplacée par une chaîne vide, la valeur textuelle d'un nœud élément
remplacée avec une concaténation de seulement ses nœuds enfants directs
(excluant les descendants), et la valeur textuelle d'un nœud texte ou
attribut défini dans XPath 1.0. Une valeur textuelle XPath affectée à
une colonne résultat d'un type XML doit être analysable comme du XML.
Il est préférable de ne pas développer du code qui se base sur ces comportements, qui ont peu de ressemblances avec les spécifications, et sont changés dans PostgreSQL 12.
BY VALUE
est supporté
Le standard SQL définit deux mécanismes de
passage qui s'appliquent lors du passage d'un argument XML
du SQL vers une fonction XML ou recevant un résultat : BY
REF
, pour lequel une valeur XML particulière conserve son
identité de nœud, et BY VALUE
, pour lequel le
contenu du XML est passé mais l'identité du nœud n'est pas préservée.
Un mécanisme peut être indiqué avant une liste de paramètres, comme
mécanisme par défaut pour tous, et après un paramètre pour surcharger le
mécanisme par défaut.
Pour illustrer la différence, si x
est une
valeur XML, ces deux requêtes produiront, respectivement, true et false
dans un environnement SQL:2006 :
SELECT XMLQUERY('$a is $b' PASSING BY REFx
AS a,x
AS b NULL ON EMPTY); SELECT XMLQUERY('$a is $b' PASSING BY VALUEx
AS a,x
AS b NULL ON EMPTY);
Dans cette version, PostgreSQL acceptera
BY REF
dans une construction
XMLEXISTS
ou XMLTABLE
, mais
l'ignorera. Le type de données xml
détient une
représentation textuelle sérialisée, donc il n'existe pas d'identité de
nœud à préserver. Le passage est donc forcément BY
VALUE
.
Les fonctions basées sur XPath supportent de passer un paramètre pour servir en tant que l'élément de contexte de l'expression XPath, mais ne supportent pas de valeurs supplémentaires dans l'expression, disponibles en tant que paramètres nommés.
XML(SEQUENCE)
Le type de données xml
de
PostgreSQL peut seulement détenir une valeur
dans la forme DOCUMENT
ou CONTENT
.
Un élément de contexte dans une expressions XQuery/XPath doit être un
seul nœud XML ou une valeur atomique, mais XPath 1.0 restreint cela
encore plus au point que ce soit seulement un nœud XML et qui n'a pas
de type de nœud permettant CONTENT
. La conséquence
est qu'un DOCUMENT
bien formé est la seule forme de
valeur XML que PostgreSQL peut fournir en
tant qu'élément de contexte XPath.