Sérialisation des données XML

Lors de la conversion explicite ou implicite du type de données xml en données SQL de type chaîne ou binaire, le contenu des données de type xml sera sérialisé conformément aux règles présentées dans cette rubrique.

Codage de la sérialisation

Si le type cible SQL est VARBINARY, le résultat est sérialisé au format UTF-16 avec une marque d'ordre d'octet UTF-16 au début, mais sans déclaration XML. Si le type cible est trop petit, une erreur est générée.

Par exemple :

select CAST(CAST(N'<Δ/>' as XML) as VARBINARY(MAX))

Voici le résultat obtenu :

0xFFFE3C0094032F003E00

Si le type cible SQL est NVARCHAR ou NCHAR, le résultat est sérialisé au format UTF-16 sans marque d'ordre d'octet au début ni déclaration XML. Si le type cible est trop petit, une erreur est générée.

Par exemple :

select CAST(CAST(N'<Δ/>' as XML) as NVARCHAR(MAX))

Voici le résultat obtenu :

<Δ/>

Si le type cible SQL est VARCHAR ou NCHAR, le résultat est sérialisé dans le codage correspondant à la page de codes du classement de la base de données sans marque d'ordre d'octet ni déclaration XML. Si le type cible est trop petit ou s'il est impossible de faire correspondre la valeur à la page de codes du classement de la cible, une erreur est générée.

Par exemple :

select CAST(CAST(N'<Δ/>' as XML) as VARCHAR(MAX))

Une erreur peut se produire si la page de codes du classement actuel ne peut pas représenter le caractère Unicode Δ, sinon le codage spécifique sera utilisé.

Lors du renvoi des résultats XML côté client, les données seront transmises en UTF-16. Le fournisseur côté client exposera ensuite les données d'après les règles de son API.

Sérialisation des structures XML

Le contenu d'un type de données xml est sérialisé de manière habituelle. Plus précisément, les nœuds d'élément sont mappés au balisage d'élément et les nœuds de texte sont mappés au contenu texte. Les circonstances dans lesquelles les caractères sont décomposés en entités et la façon dont les valeurs atomiques typées sont sérialisées sont décrites dans les sections suivantes.

Codage d'entité des caractères XML au cours de la sérialisation

Chaque structure XML sérialisée doit pouvoir subir une nouvelle analyse. C'est pourquoi, certains caractères doivent être sérialisées à l'aide du codage d'entité de façon à autoriser les accès répétés aux caractères, tout au long de la phase de normalisation de l'analyseur XML. Il s'avère aussi nécessaire de spécifier le codage d'entité de certains caractères afin d'assurer la bonne formation du document et son analyse. Voici les règles de codage d'entité qui s'appliquent au cours de la sérialisation :

  • Les caractères &, < et > sont toujours codés sous la forme &amp;, &lt; et &gt; respectivement, s'ils se trouvent dans la valeur d'un attribut ou dans le contenu d'un élément.

  • Dans la mesure où SQL Server utilise les guillemets (U+0022) pour délimiter les valeurs des attributs, le guillemet des valeurs de l'attribut est codé par &quot;.

  • Une paire de substitution est codée sous forme d'une seule référence de caractère numérique, lors de la conversion sur le serveur uniquement. Par exemple, la paire de substitution U+D800 U+DF00 est codée par la référence de caractère numérique &#x00010300;.

  • Pour empêcher la normalisation d'une tabulation (U+0009) et d'un saut de ligne (LF, U+000A) lors de l'analyse, ces derniers sont codés par leurs références de caractère numérique, &#x9; et &#xA; respectivement, dans les valeurs des attributs.

  • Pour empêcher la normalisation d'un retour chariot (CR, U+000D) lors de l'analyse, ce dernier est codé par sa référence de caractère numérique, &#xD; dans les valeurs des attributs et le contenu des éléments.

  • Pour protéger les nœuds de texte contenant des espaces, l'un des espaces (généralement le dernier) est codé par sa référence de caractère numérique. De cette façon, l'analyse préserve le nœud de texte contenant des espaces, quel que soit le mode de traitement choisi pour les espaces au cours de l'analyse.

Par exemple :

declare @u NVARCHAR(50)
set @u = N'<a a="&#xD;&#x9;'+NCHAR(0xD800)+NCHAR(0xDF00)+N'>">   '+NCHAR(0xA)+N'</a>'
select CAST(CONVERT(XML,@u,1) as NVARCHAR(50))

Voici le résultat obtenu :

<a a="&#xD;&#x9;&#x00010300;&gt;">   &#xA;</a>

Si vous ne voulez pas appliquer la règle de protection du dernier espace, vous pouvez utiliser explicitement l'option 1 de CONVERT lors de la conversion de xml en chaîne ou en binaire. Par exemple, vous pouvez éviter le codage d'entité en procédant ainsi :

select CONVERT(NVARCHAR(50), CONVERT(XML, '<a>   </a>', 1), 1)

Remarquez que la méthode query() (type de données xml) transmet les résultats dans une instance de type xml. Par conséquent, tout résultat de la méthode query() qui est converti en type chaîne ou binaire a recours au codage d'entité conformément aux règles précédemment décrites. Si vous souhaitez obtenir les valeurs de chaîne sans conversion en entité, utilisez la méthode value() (type de données xml). L'exemple suivant montre comment utiliser la méthode query() :

declare @x xml
set @x = N'<a>This example contains an entitized char: &lt;.</a>'
select @x.query('/a/text()')

Voici le résultat obtenu :

This example contains an entitized char: &lt;.

L'exemple suivant montre comment utiliser la méthode value() :

select @x.value('(/a/text())[1]', 'nvarchar(100)')

Voici le résultat obtenu :

This example contains an entitized char: <.

Sérialisation de données typées XML

Une instance typée xml contient des valeurs qui sont typées en fonction de leurs types de schémas XML. Ces valeurs sont sérialisées selon leur type de schéma XML au format que produit la conversion XQuery vers xs:string. Pour plus d'informations, consultez Règles de conversion de types dans XQuery.

Par exemple, la valeur xs:double 1.34e1 est sérialisée en 13.4 comme le montre l'exemple suivant :

declare @x xml
set @x =''
select CAST(@x.query('1.34e1') as nvarchar(50))

Cela renvoie la valeur de chaîne 13.4.