para salida de ruta xml ('')

9

Cuando ejecuto lo siguiente

select t.type
  from (values ('Green'),('Blue'),('Red')) as t(type)
   for xml path('')

Recibo esta salida

<type>Green</type>
<type>Blue</type>
<type>Red</type>

Si ejecuto lo siguiente

select t.type + '/'
  from (values ('Green'),('Blue'),('Red')) as t(type)
   for xml path('')

Recibo esta salida

Green/Blue/Red/

¿Por qué agregar la concatenación en la selección lleva a la eliminación de las etiquetas de tipo y la salida en una línea en el archivo xml? Ejecutando SQL Server 2012.

kevinnwhat
fuente

Respuestas:

15

XML es loco

Cuando agrega la cadena concatenada, pierde el "elemento de ruta".

Por ejemplo, si haces esto:

SELECT t.type + '/' AS type
FROM   ( VALUES ( 'Green' ), ( 'Blue' ), ( 'Red' )) AS t ( type )
FOR XML PATH('');

SELECT t.type + '/' 
FROM   ( VALUES ( 'Green' ), ( 'Blue' ), ( 'Red' )) AS t ( type )
FOR XML PATH('type');

Obtienes esto de vuelta:

<type>Green/</type>
<type>Blue/</type>
<type>Red/</type>

El nombre de columna o alias actúa como el elemento de ruta.

Algunos otros ejemplos que pueden ayudar

Utilizando RAW, ELEMENTS

SELECT t.type + '/'
FROM   ( VALUES ( 'Green' ), ( 'Blue' ), ( 'Red' )) AS t ( type )
FOR XML RAW, ELEMENTS;

SELECT t.type + '/' AS type
FROM   ( VALUES ( 'Green' ), ( 'Blue' ), ( 'Red' )) AS t ( type )
FOR XML RAW, ELEMENTS;

En el primer ejemplo, obtienes el nombre genérico del elemento "fila", pero en el segundo obtienes fila / tipo.

Al usar RAW, TYPE:

SELECT t.type + '/' AS type
FROM   ( VALUES ( 'Green' ), ( 'Blue' ), ( 'Red' )) AS t ( type )
FOR XML RAW, TYPE;

SELECT t.type + '/'
FROM   ( VALUES ( 'Green' ), ( 'Blue' ), ( 'Red' )) AS t ( type )
FOR XML RAW, TYPE;

La primera consulta devuelve XML válido-ish, la segunda arroja un error porque el elemento de ruta carece de un identificador.

Usando AUTO, el alias de la tabla y el nombre de la columna se convierten en la ruta:

SELECT type + '/' AS type
FROM   ( VALUES ( 'Green' ), ( 'Blue' ), ( 'Red' )) AS t ( type )
FOR XML AUTO;

SELECT type 
FROM   ( VALUES ( 'Green' ), ( 'Blue' ), ( 'Red' )) AS t ( type )
FOR XML AUTO;

Pero sin un alias, obtienes un error similar:

SELECT type + '/'
FROM   ( VALUES ( 'Green' ), ( 'Blue' ), ( 'Red' )) AS t ( type )
FOR XML AUTO;

Me gustaría dar un ejemplo, FOR XML EXPLICITpero sería irresponsable para mí comenzar a beber en este momento.

Erik Darling
fuente