Serialización de datos XML

Cuando el tipo de datos xml se convierte de manera explícita o implícita a un tipo SQL binario o de cadena, el contenido del tipo de datos xml se serializa de acuerdo con las reglas que se describen en este tema.

Codificación de la serialización

Si el tipo SQL de destino es VARBINARY, el resultado se serializa en UTF-16 con una marca de orden de bytes UTF-16 delante, pero sin una declaración XML. Si el tipo de destino es demasiado pequeño, se genera un error.

Por ejemplo:

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

El resultado es el siguiente:

0xFFFE3C0094032F003E00

Si el tipo SQL de destino es NVARCHAR o NCHAR, el resultado se serializa en UTF-16 sin una marca de orden de bytes y sin una declaración XML. Si el tipo de destino es demasiado pequeño, se genera un error.

Por ejemplo:

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

El resultado es el siguiente:

<?/>

Si el tipo SQL de destino es VARCHAR o NCHAR, el resultado se serializa en la codificación que corresponda a la página de códigos de intercalación de la base de datos, sin marca de orden de bytes ni declaración XML. Si el tipo de destino es demasiado pequeño o el valor no se puede asignar a la página de códigos de intercalación de destino, se genera un error.

Por ejemplo:

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

Se puede generar un error si la página de códigos de la intercalación actual no puede representar el carácter Unicode ?, o se representará en la codificación específica.

Cuando se devuelven los resultados XML al cliente, los datos se envían codificados como UTF-16. Después, el proveedor del cliente expondrá los datos de acuerdo con sus reglas de API.

Serialización de las estructuras XML

El contenido de un tipo de datos xml se serializa de la forma habitual. Concretamente, los nodos de elementos se asignan a marcado de elemento y los nodos de texto se asignan a contenido de texto. No obstante, en las siguientes secciones se describen las circunstancias en las que se crean entidades para los caracteres y cómo se serializan los valores atómicos con tipo.

Creación de entidades para caracteres XML durante la serialización

Todas las estructuras XML serializadas deberían poder analizarse de nuevo. Por tanto, algunos caracteres deben serializarse como entidades para que conserven su funcionalidad de ida y vuelta durante la fase de normalización del analizador XML. Sin embargo, deben crearse entidades para algunos caracteres con el fin de que el formato del documento sea correcto, y, por tanto, se pueda analizar. A continuación se exponen las reglas de creación de entidades que se aplican durante la serialización:

  • Para los caracteres &, < y > siempre se crean las entidades &amp;, &lt; y &gt;, respectivamente, si aparecen en valores de atributos o en el contenido de elementos.
  • Dado que SQL Server utiliza comillas (U+0022) para incluir los valores de los atributos, para la comilla de los valores de atributo se crea la entidad &quot;.
  • La entidad que se crea para un par suplente es una única referencia de carácter numérico, sólo cuando la conversión se realiza en el servidor. Por ejemplo, el par suplente U+D800 U+DF00 pasa a ser la entidad de referencia de carácter numérico &#x00010300;.
  • Para impedir que un carácter de tabulación (U+0009) o avance de línea (LF, U+000A) se normalice durante el análisis, tendrán como entidades sus referencias de carácter numérico (&#x9; y &#xA; respectivamente) en los valores de atributos.
  • Para impedir que un carácter de retorno de carro (CR, U+000D) se normalice durante el análisis, tendrá como entidad su referencia de carácter numérico (&#xD;) en los valores de atributos y en el contenido de elementos.
  • Para proteger los nodos de texto que sólo contienen espacios en blanco, se crea una entidad para uno de los caracteres de espacio en blanco, generalmente el último, que se corresponde con su referencia de carácter numérico. De esta manera, cuando se vuelve a realizar el análisis, se conserva el nodo de texto de espacio en blanco independientemente de la configuración del control de espacios en blanco durante el análisis.

Por ejemplo:

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))

El resultado es el siguiente:

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

Si no se desea aplicar la regla de protección del último espacio en blanco, se puede utilizar la opción explícita de CONVERT 1 al convertir el tipo xml en un tipo de cadena o binario. Por ejemplo, para evitar la creación de entidades, tiene las opciones siguientes:

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

Tenga en cuenta que el método query() (tipo de datos xml) genera una instancia de tipo de datos xml. Por tanto, se crearán entidades para cualquier resultado del método query() que se convierta en un tipo binario o de cadena de acuerdo con las reglas previamente descritas. Si se desean obtener los valores de cadena sin creación de entidades, en su lugar debe utilizarse query() (método de tipo de datos xml). A continuación se ofrece un ejemplo de uso del método query():

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

El resultado es el siguiente:

This example contains an entitized char: &lt;.

A continuación se ofrece un ejemplo de uso del método value():

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

El resultado es el siguiente:

This example contains an entitized char: <.

Serializar un tipo de datos xml con tipo

Una instancia de tipo de datos xml con tipo contiene valores cuyos tipos se corresponden con los tipos de su esquema XML. Estos valores se serializan según su tipo de esquema XML, en el mismo formato que genera la conversión XQuery a xs:string. Para obtener más información, vea Reglas de conversión de tipos en XQuery.

Por ejemplo, el valor 1.34e1 de tipo xs:double se serializa como 13.4, como se observa en el ejemplo siguiente:

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

Se obtiene el valor de cadena 13.4.

Vea también

Referencia

Reglas de conversión de tipos en XQuery

Otros recursos

CAST y CONVERT (Transact-SQL)

Ayuda e información

Obtener ayuda sobre SQL Server 2005