para saída do caminho xml ('')

9

Quando executo o seguinte

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

Eu recebo essa saída

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

Se eu executar o seguinte

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

Eu recebo essa saída

Green/Blue/Red/

Por que adicionar a concatenação no select leva à remoção das tags de tipo e da saída em uma linha do arquivo xml? Executando o SQL Server 2012.

kevinnwhat
fonte

Respostas:

15

XML é maluco

Ao adicionar a seqüência concatenada, você perde o "elemento do caminho".

Por exemplo, se você fizer isso:

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

Você recebe de volta:

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

O nome da coluna ou alias atua como o elemento do caminho.

Alguns outros exemplos que podem ajudar

Usando 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;

No primeiro exemplo, você obtém o nome do elemento "linha" genérico, mas no segundo, obtém a linha / tipo.

Ao 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;

A primeira consulta retorna XML válido-ish, a segunda gera um erro porque o elemento path não possui um identificador.

Usando AUTO, o alias da tabela e o nome da coluna se transformam no caminho:

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;

Mas sem um alias, você recebe um erro semelhante:

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

Eu daria um exemplo, FOR XML EXPLICITmas seria irresponsável começar a beber agora.

Erik Darling
fonte