Des révisions significatives aux spécifications liées à XML dans ISO/IEC 9075-14 (SQL/XML) ont été introduites par SQL:2006. L'implémentation PostgreSQL du type de données XML et des fonctions associées suivent en grande partie l'édition précédente de 2003, avec quelques emprunts dans les éditions suivantes. En particulier :
Où le standard actuel fournit une famille de types de données XML pour
contenir un « document » ou « content » dans des
variantes non typées ou typées par schéma XML, et un type
XML(SEQUENCE)
pour contenir des parties arbitraires de
contenu XML, PostgreSQL fournit le seul type
xml
, qui peut contenir un « document » ou
« content ». Il n'y a aucun équivalent au type
« sequence »standard.
PostgreSQL fournit deux fonctions introduites par SQL:2006, mais dans des variantes qui utilisent le langage XPath 1.0, plutôt que XML Query comme spécifié pour elles dans le standard.
Cette section présente certaines des différences de résultat que vous pourriez rencontrer.
Les fonctions spécifiques à PostgreSQL
xpath()
et xpath_exists()
requêtent des documents XML en utilisant le langage XPath.
PostgreSQL fournit également des variantes pour
XPath uniquement des fonctions du standard XMLEXISTS
et XMLTABLE
, qui officiellement utilisent le langage
XQuery. Pour toutes ces fonctions, PostgreSQL
se repose sur la bibliothèque libxml2,
qui ne fournit que XPath 1.0.
Il y a une forte connexion entre le langage XQuery et XPath version 2.0 et supérieure : toute expression qui est syntaxiquement valide et s'exécute avec succès avec les deux produisent le même résultat (avec une exception mineure pour les expressions contenant des références de caractères numériques ou des références d'entités prédéfinies, que XQuery remplace par le caractère correspondant alors que XPath n'y touche pas). Mais il n'y a pas une telle connexion entre ces langages et XPath 1.0 ; c'était un précédent langage qui diffère sur de nombreux aspects.
Il y a deux catégories de limitations à garder à l'esprit : la restriction de XQuery à XPath pour les fonctions spécifiées dans le standard SQL ainsi que la restriction de XPath pour la version 1.0 à la fois pour le standard et pour les fonctions PostgreSQL spécifiques.
Les fonctionnalités de XQuery allant au delà de XPath incluent :
Les expressions XQuery peuvent construire et retourner de nouveaux nœuds XML, en plus de toutes les valeurs XPath possibles. XPath peut créer et retourner des valeurs des types atomiques (nombres, chaînes et ainsi de suite), mais peuvent uniquement retourner des nœuds XML qui étaient déjà présents dans les documents fournis en entrées de l'expression.
XQuery dispose de concepts pour l'itération, tri et regroupement.
XQuery permet la déclaration et l'utilisation de fonctions locales.
Les versions récentes de XPath commencent à offrir des possibilités qui
se chevauchent avec celle-ci (comme un for-each
de
style fonctionnel, des fonctions anonymes et
parse-xml
pour créer un nœud depuis une chaîne),
mais ces fonctionnalités ne sont pas disponibles avant XPath 3.0.
Pour les développeurs familiers avec XQuery et XPath 2.0 ou plus, XPath 1.0 présente un certain nombre de différences :
Le type fondamental d'une expression 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 uniquement produire des nœuds-ensemble (contenant zéro ou plus
nœuds XML), ou une seule valeur atomique.
Contrairement à une séquence XQuery/XPath, qui peut contenir n'importe quel élément voulu dans n'importe quel ordre voulu, un nœud-ensemble XPath 1.0 n'a aucune garantie sur l'ordre et, comme n'importe quel ensemble, n'autorise pas de multiples occurences d'un même élément.
La bilbiothèque libxml2 semble toujours retourner des nœud-ensembles à PostgreSQL avec leurs membres dans le même ordre relatif qu'ils avaient dans le document en entrée. Sa documentation ne valide pas ce comportement, et une expression XPath 1.0 ne peut pas le contrôler.
Bien que XQuery/XPath fournisse tous les types définis dans XML Schema
et de nombreux opérateurs et fonctions au dessus de ces types, XPath
1.0 n'a que le nœud-ensemble et les trois types atomiques
boolean
, double
, et string
.
XPath 1.0 n'a pas d'opérateur conditionnel. Une expression
XQuery/XPath telle que if ( hat ) then hat/@size else "no hat"
n'a pas d'équivalent avec XPath 1.0.
XPath 1.0 n'a pas d'opérateur de comparaison de tri pour les chaînes
de caractère.
"cat" < "dog"
et
"cat" > "dog"
sont tous les deux faux, car
chacun est une comparaison numérique de deux NaN
s.
En comparaison, =
et !=
comparent les chaînes en tant que chaînes.
XPath 1.0 brouille la distinction entre
value comparisons et
general comparisons tels que XQuery/XPath les
définis. sale/@hatsize = 7
et
sale/@customer = "alice"
sont tous les deux
existentiellement des comparaisons quantifiées, vraies s'il y a au
moins un sale
avec la valeur donnée pour
l'attribut, mais sale/@taxable = false()
est
une comparaison de valeur de la valeur booléenne
effective d'un nœud-ensemble entier.
C'est uniquement vrai si aucun sale
n'a un attribut
taxable
.
Dans le modèle de données XQuery/XPath, un nœud
document peut avoir soit une forme de document
(c'est-à-dire exactement un élément de premier niveau, avec
uniquement des commentaires et des instructions de traitement en
dehors de celui-ci) ou une forme de contenu (avec ces contraintes
relachées). Son équivalent dans XPath 1.0, le
nœud racine, ne peut être que dans une forme de
document. C'est en partie la raison pour laquelle une valeur
xml
passée comme objet de contexte à n'importe laquelle
des fonctions PostgreSQL basée sur XPath
doit être dans une forme de document.
Les différences mises en évidence ici ne représentent pas l'intégralité des différences. Avec XQuery et les versions 2.0 et supérieures de XPath, il y a un mode de compatibilité XPath 1.0, et les listes W3C de changement de bibliothèques de fonction et de changement du langage appliqués dans ce mode offrent un compte rendu plus complet (mais toujours pas exhaustif) des différences. Le mode de compatibilité ne peut pas rendre les langages supérieurs exactement équivalents à XPath 1.0.
Avec SQL:2006 et ultérieur, les deux sens de conversion entre les types de données standard SQL et les types XML Schema sont précisément spécifiés. Cependant, les règles sont exprimées en utilisant les types et sémantiques de XQuery/XPath, et n'ont pas d'application directe pour les différents modèles de XPath 1.0.
Quand PostgreSQL fait correspondre des valeurs
de données SQL vers XML (par exemple avec
xmlelement
), ou XML vers SQL (par exemple comme les
colonnes en sortie de xmltable
), à l'exception de
quelques cas traités spécifiquement,
PostgreSQL part simplement du principe que
le type de données XML chaîne de caractère XPath 1.0 sera valide en tant
que forme d'entrée texte du type de données SQL, et réciproquement.
Cette règle à l'avantage d'être simple tout en produisant, pour de
nombreux types de données, des résultats similaires aux correspondances
spécifiées dans le standard.
Quand l'interopérabilité avec les autres systèmes est une préoccupation, pour certains types de données, il peut ne pas être nécessaire d'utiliser explicitement des fonctions de formatage de type de données (telles que celles dans Section 9.8) pour produire les correspondances standard.
Cette section concerne les limites qui ne sont pas inhérentes à la bibliothèque libxml2, mais qui s'appliquent à l'implémentation actuelle dans PostgreSQL.
BY VALUE
est
supporté
Le standard SQL définit deux mécanismes de passage
qui s'appliquent quand un argument XML est passé de SQL à une fonction
XML ou en recevant un résultat : BY REF
, pour lequel
une valeur XML particulière retient 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 spécifié
avant une liste de paramètres, comme le mécanisme par défaut pour tous
ceux-ci, ou après n'importe lequel des paramètres, pour surcharger le
mécanisme par défaut.
Pour illustrer la différence, si
x
est une valeur XML, ces deux requêtes dans
un environnement SQL:2006 produiraient respectivement vrai et faux :
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);
PostgreSQL acceptera
BY VALUE
ou BY REF
dans une
construction XMLEXISTS
ou
XMLTABLE
, mais les ignorera. Le type de données
xml
a une représentation sérialisée en chaine de caractères,
il n'y a donc pas d'identité de nœud à préserver, et le passage est dans
les faits toujours BY VALUE
.
Le support des fonctions basées sur XPath supportent de passer un paramètre afin d'être utilisé comme l'item du contexte de l'expression XPath, mais ne supporte pas de passer des valeurs supplémentaires pour être disponibles dans l'expression comme paramètre nommés.
XML(SEQUENCE)
Le type de donnéesPostgreSQL xml
ne peut contenir qu'une valeur dans une forme DOCUMENT
ou CONTENT
. Un item de contexte d'expression
XQuery/XPath doit être un unique nœud XML ou une valeur
atomique, mais XPath 1.0 le restreint en plus à n'être qu'un nœud XML, et
n'a aucun type de nœud autorisant CONTENT
. Le résultat
est qu'un DOCUMENT
formé comme il faut est la seule
forme de valeur XML que PostgreSQL peut
fournir à un item de contexte XPath.