Puede usar information_schema.columns
y for xml path
así para obtener la estructura que desea.
select
'MyTable' as 'TABLE/@name',
(select XMLCol as '*'
from (select XMLCol
from MyTable
cross apply
(select
COLUMN_NAME as 'COL/@name',
case COLUMN_NAME when 'FirstName' then FirstName end as COL,
case COLUMN_NAME when 'LastName' then LastName end as COL
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = 'MyTable'
for xml path(''), root('ROW'), type) as Row(XMLCol)
) as Rows
for xml path(''), type) as 'TABLE'
for xml path('')
Pero en tu caso no veo otra opción que construir esto dinámicamente.
declare @TableName varchar(50) = 'MyTable'
declare @ColList varchar(8000)
select @ColList = coalesce(@ColList+', ', '') + 'case COLUMN_NAME when '''+COLUMN_NAME+''' then '+COLUMN_NAME+' end as COL'
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = @TableName
declare @SQL varchar(max) =
'select
''_TABLENAME_'' as ''TABLE/@name'',
(select XMLCol as ''*''
from (select XMLCol
from _TABLENAME_
cross apply
(select
COLUMN_NAME as ''COL/@name'',
_COLLIST_
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = ''_TABLENAME_''
for xml path(''''), root(''ROW''), type) as Row(XMLCol)
) as Rows
for xml path(''''), type) as ''TABLE''
for xml path('''')'
set @SQL = replace(@SQL, '_TABLENAME_', @TableName)
set @SQL = replace(@SQL, '_COLLIST_', @ColList)
exec (@SQL)