I tried to do it
select PersonColumn.query(' element Person { for $i in /Person/* return attribute {local-name($i)} {string($i)} } ') from MyTable
but it turns out that you cannot use dynamic attribute names
XQuery [MyTable.PersonColumn.query()]: Only constant expressions are supported for the name expression of computed element and attribute constructors.: select PersonColumn.query(' element Person { for $i in /Person/* return attribute {local-name($i)} {string($i)} } ') from MyTable
So the best I can do so far
select cast( '<Person ' + ( select PersonColumn.query(' for $i in /Person/* return concat(local-name($i), "=""", data($i), """") ').value('.', 'nvarchar(max)') for xml path('') ) + '/>' as xml) from MyTable
It is also possible to do
select cast( '<Person ' + PersonColumn.query(' for $i in /Person/* return concat(local-name($i), "=""", data($i), """") ').value('.', 'nvarchar(max)') + '/>' as xml) from MyTable
but it will not work if your data contains some characters, such as < > , etc.
source share