Share via


Types de données XPath (SQLXML 4.0)

S’applique à :SQL ServerAzure SQL Database

Microsoft SQL Server, XPath et schéma XML (XSD) ont des types de données très différents. Par exemple, XPath n’a pas de types de données entiers ou date, mais SQL Server et XSD en ont plusieurs. XSD utilise une précision nanoseconde pour les valeurs de temps, et SQL Server utilise une précision de 1/300 seconde maximum. Par conséquent, le mappage d'un type de données à un autre n'est pas toujours possible. Pour plus d’informations sur le mappage SQL Server types de données aux types de données XSD, consultez Contraintes de type de données et l’annotation sql:datatype (SQLXML 4.0).

XPath a trois types de données : chaîne, nombre et booléen. Le type de données number est toujours un virgule flottante à double précision IEEE 754. Le type de données SQL Server float(53) est le plus proche du nombre XPath. Cependant, float(53) n’est pas exactement IEEE 754. Par exemple, ni la valeur NaN (Not-a-Number,), ni une valeur infinie n'est employée. La tentative de conversion d’une chaîne non numérique en nombre et la tentative de division par zéro entraîne une erreur.

Conversions XPath

Lorsque vous utilisez une requête XPath, telle que OrderDetail[@UnitPrice > "10.0"], les conversions de type de données implicites et explicites peuvent modifier la signification de la requête de manière subtile. Par conséquent, il est primordial de comprendre la manière dont les types de données Xpath sont implémentés. La spécification du langage XPath, XML Path Language (XPath) version 1.0 W3C Proposed Recommandation 8 octobre 1999, est disponible sur le site Web W3C à l’adresse http://www.w3.org/TR/1999/PR-xpath-19991008.html.

Les opérateurs XPath sont divisés en quatre catégories :

  • Opérateurs booléens (et, ou)

  • Opérateurs relationnels (<, , <>=, >=)

  • Opérateurs d'égalité (=, !=)

  • Opérateurs arithmétiques (+, -, *, div, mod)

Chaque catégorie d'opérateur convertit ses opérandes de manière distincte. Les opérateurs XPath convertissent implicitement leurs opérandes si cela est nécessaire. Les opérateurs arithmétiques convertissent leurs opérandes en nombre et aboutissent à une valeur de nombre. Les opérateurs booléens convertissent leurs opérandes en booléens et aboutissent à une valeur booléenne. Les opérateurs relationnels et d'égalité génèrent une valeur booléenne. Toutefois, ils suivent des règles de conversion différentes en fonction des types de données d'origine de leurs opérandes comme le montre le tableau ci-après.

Opérande Opérateur relationnel Opérateur d’égalité
Les deux opérandes sont des éléments node-set. TRUE si et uniquement s’il existe un nœud dans un ensemble et un nœud dans le deuxième ensemble, de sorte que la comparaison de leurs valeurs de chaîne est TRUE. Idem.
L’un est un ensemble de nœuds, l’autre une chaîne. TRUE si et uniquement s’il existe un nœud dans le jeu de nœuds, de sorte qu’en cas de conversion en nombre, la comparaison de celui-ci avec la chaîne convertie en nombre est TRUE. TRUE si et uniquement s’il existe un nœud dans le jeu de nœuds, de sorte qu’en cas de conversion en chaîne, la comparaison de celui-ci avec la chaîne est TRUE.
L’un est un ensemble de nœuds, l’autre un nombre. TRUE si et uniquement s’il existe un nœud dans l’ensemble de nœuds, de sorte qu’en cas de conversion en nombre, la comparaison de celui-ci avec le nombre est TRUE. Idem.
L’un est un ensemble de nœuds, l’autre un booléen. TRUE si et uniquement s’il existe un nœud dans le jeu de nœuds, de sorte qu’en cas de conversion en booléen , puis en nombre, la comparaison de celui-ci avec le booléen converti en nombre est TRUE. TRUE si et uniquement s’il existe un nœud dans le jeu de nœuds, de sorte qu’en cas de conversion en booléen, la comparaison de celui-ci avec le booléen est TRUE.
Ni l'un ni l'autre n'est un élément node-set. Convertissez les deux opérandes en nombre , puis comparez. Convertissez les deux opérandes en un type commun, puis comparez-les. Convertissez en booléen si l’un est booléen, nombre si l’un est nombre ; sinon, convertissez en chaîne.

Notes

Étant donné que les opérateurs relationnels XPath convertissent toujours leurs opérandes en nombre, les comparaisons de chaînes ne sont pas possibles. Pour inclure les comparaisons de dates, SQL Server 2000 offre cette variante à la spécification XPath : lorsqu’un opérateur relationnel compare une chaîne à une chaîne, un jeu de nœuds à une chaîne ou un ensemble de nœuds à valeur de chaîne à un ensemble de nœuds à valeur de chaîne, une comparaison de chaînes (et non une comparaison de nombres) est effectuée.

Conversions des éléments node-set

Les conversions des éléments node-set ne sont pas toujours intuitives. Un jeu de nœuds est converti en chaîne en prenant la valeur de chaîne du seul premier nœud de l’ensemble. Un jeu de nœuds est converti en nombre en le convertissant en chaîne, puis en le convertissant en nombre. Un jeu de nœuds est converti en booléen en testant son existence.

Notes

SQL Server n’effectue pas de sélection positionnelle sur les jeux de nœuds : par exemple, la requête Customer[3] XPath désigne le troisième client ; ce type de sélection positionnelle n’est pas pris en charge dans SQL Server. Par conséquent, les conversions node-set-to-string ou node-set-to-number telles que décrites par la spécification XPath ne sont pas implémentées. SQL Server utilise la sémantique « any » partout où la spécification XPath spécifie la sémantique « first ». Par exemple, en fonction de la spécification XPath W3C, la requête Order[OrderDetail/@UnitPrice > 10.0] XPath sélectionne les commandes avec le premier OrderDetail qui a un UnitPrice supérieur à 10.0. Dans SQL Server, cette requête XPath sélectionne ces commandes avec n’importe quel OrderDetail dont la valeur UnitPrice est supérieure à 10.0.

La conversion en booléen génère un test d’existence ; par conséquent, la requête Products[@Discontinued=true()] XPath équivaut à l’expression SQL « Products.Discontinued n’est pas null », et non à l’expression SQL « Products.Discontinued = 1 ». Pour rendre la requête équivalente à la dernière expression SQL, commencez par convertir le jeu de nœuds en un type non booléen , tel que nombre. Par exemple : Products[number(@Discontinued) = true()].

Du fait que la plupart des opérateurs sont définis pour être vrais (TRUE) s'ils le sont pour un nœud quelconque ou l'un des nœuds de l'élément node-set, ces opérations prennent toujours la valeur FALSE si l'élément node-set est vide. Ainsi donc, si A est vide, A = B et A != B ont tous les deux la valeur FALSE et not(A=B) et not(A!=B) ont la valeur TRUE.

En règle générale, un attribut ou un élément mappé à une colonne existe si la valeur de cette colonne dans la base de données n’est pas null. Les éléments mappés aux lignes existent si tous leurs enfants existent.

Notes

Les éléments annotés avec is-constant existent toujours. Par conséquent, les prédicats XPath ne peuvent pas être utilisés sur des éléments is-constant .

Lorsqu’un jeu de nœuds est converti en chaîne ou en nombre, son type XDR (le cas échéant) est inspecté dans le schéma annoté et ce type est utilisé pour déterminer la conversion requise.

Mappage des types de données XDR et XPath

Le type de données XPath d’un nœud est dérivé du type de données XDR dans le schéma, comme indiqué dans le tableau suivant (le nœud EmployeeID est utilisé à des fins d’illustration).

Type de données XDR Équivalent

Type de données XPath
Conversion SQL Server utilisée
Nonebin.base64bin.hex N/A NoneEmployeeID
boolean boolean CONVERT(bit, EmployeeID)
number, int, float,i1, i2, i4, i8,r4, r8ui1, ui2, ui4, ui8 nombre CONVERT(float(53), EmployeeID)
id, idref, idrefsentity, entities, enumerationnotation, nmtoken, nmtokens, chardate, Timedate, Time.tz, string, uri, uuid string CONVERT(nvarchar(4000), EmployeeID, 126)
fixed14.4 N/A (aucun type de données XPath n'équivaut au type de données XDR fixed14.4) CONVERT(money, EmployeeID)
Date string LEFT(CONVERT(nvarchar(4000), EmployeeID, 126), 10)
time

time.tz
string SUBSTRING(CONVERT(nvarchar(4000), EmployeeID, 126), 1 + CHARINDEX(N'T', CONVERT(nvarchar(4000), EmployeeID, 126)), 24)

Les conversions de date et d’heure sont conçues pour fonctionner, que la valeur soit stockée dans la base de données à l’aide du type de données SQL Server datetime ou d’une chaîne. Notez que le type de données SQL Server datetime n’utilise pas de fuseau horaire et a une précision inférieure à celle du type de données heure XML. Pour inclure le type de données de fuseau horaire ou une précision supplémentaire, stockez les données dans SQL Server à l’aide d’un type chaîne.

Lorsque vous convertissez un nœud du type de données XDR en type de données XPath, une conversion supplémentaire est parfois nécessaire (d'un type de données XPath vers un autre type de données XPath). Par exemple, imaginez la requête XPath suivante :

(@m + 3) = 4  

Si @m est du type de données XDR fixe14.4 , la conversion du type de données XDR en type de données XPath s’effectue à l’aide de :

CONVERT(money, m)  

Dans cette conversion, le nœud m est converti de fixed14.4 en money. Toutefois, l'ajout de la valeur 3 nécessite une autre conversion :

CONVERT(float(CONVERT(money, m))  

L'expression XPath est évaluée comme suit :

CONVERT(float(CONVERT(money, m)) + CONVERT(float(53), 3) = CONVERT(float(53), 3)  

Comme le montre le tableau ci-dessous, il s'agit de la même conversion que celle appliquée à d'autres expressions XPath (telles que des littéraux ou des expressions composées).

X est inconnu X est une chaîne X est un nombre X est booléen
string(X) CONVERT (nvarchar(4000), X, 126) - CONVERT (nvarchar(4000), X, 126) CASE WHEN X THEN N'true' ELSE N'false' END
number(X) CONVERT (float(53), X) CONVERT (float(53), X) - CASE WHEN X THEN 1 ELSE 0 END
boolean(X) - LEN(X) > 0 X != 0 -

Exemples

R. Convertir un type de données dans une requête XPath

Dans la requête XPath suivante spécifiée par rapport à un schéma XSD annoté, la requête sélectionne tous les nœuds Employee avec la valeur d’attribut EmployeeID E-1, où « E- » est le préfixe spécifié à l’aide de l’annotation sql:id-prefix .

Employee[@EmployeeID="E-1"]

Le prédicat dans la requête équivaut à l'expression SQL suivante :

N'E-' + CONVERT(nvarchar(4000), Employees.EmployeeID, 126) = N'E-1'

Étant donné que EmployeeID est l’une des valeurs de type de données id (idref, idrefs, nmtoken, nmtokens, etc.) dans le schéma XSD, EmployeeID est converti en type de données XPath de chaîne à l’aide des règles de conversion décrites précédemment.

CONVERT(nvarchar(4000), Employees.EmployeeID, 126)

Le préfixe « E - » est ajouté à la chaîne et le résultat est ensuite comparé avec N'E-1'.

B. Effectuer plusieurs conversions de types de données dans une requête XPath.

Examinez la requête XPath suivante définie par rapport à un schéma XSD annoté : OrderDetail[@UnitPrice * @OrderQty > 98]

Cette requête XPath retourne tous les <éléments OrderDetail> satisfaisant le prédicat @UnitPrice * @OrderQty > 98. Si unitPrice est annoté avec un type de données fixed14.4 dans le schéma annoté, ce prédicat est équivalent à l’expression SQL :

CONVERT(float(53), CONVERT(money, OrderDetail.UnitPrice)) * CONVERT(float(53), OrderDetail.OrderQty) > CONVERT(float(53), 98)

Lors de la conversion des valeurs dans la requête XPath, la première conversion convertit le type de données XDR en type de données XPath. Étant donné que le type de données XSD de UnitPrice est fixe14.4, comme décrit dans le tableau précédent, il s’agit de la première conversion utilisée :

CONVERT(money, OrderDetail.UnitPrice))   

Étant donné que les opérateurs arithmétiques convertissent leurs opérandes en type de données nombre XPath, la deuxième conversion (d’un type de données XPath vers un autre type de données XPath) est appliquée dans laquelle la valeur est convertie en float(53) (float(53) est proche du type de données nombre XPath :

CONVERT(float(53), CONVERT(money, OrderDetail.UnitPrice))   

En supposant que l’attribut OrderQty n’a pas de type de données XSD, OrderQty est converti en un type de données XPath numérique en une seule conversion :

CONVERT(float(53), OrderDetail.OrderQty)  

De même, la valeur 98 est convertie en nombre XPath type de données :

CONVERT(float(53), 98)  

Notes

Si le type de données XSD utilisé dans le schéma est incompatible avec le type de données SQL Server sous-jacent dans la base de données, ou si une conversion de type de données XPath impossible est effectuée, SQL Server peut retourner une erreur. Par exemple, si l’attribut EmployeeID est annoté avec l’annotation id-prefix , le XPath Employee[@EmployeeID=1] génère une erreur, car EmployeeID a l’annotation id-prefix et ne peut pas être converti en nombre.