Reputation: 504
I have a table with following structure
StreetNumber varchar(50)
Apartment varchar(50)
Floor varchar(50)
I want to convert the data to XML like this:
<Attributes>
<AddressAttribute ID="1">
<AddressAttributeValue>
<Value>3</Value>
</AddressAttributeValue>
</AddressAttribute>
<AddressAttribute ID="3">
<AddressAttributeValue>
<Value>1</Value>
</AddressAttributeValue>
</AddressAttribute>
<AddressAttribute ID="2">
<AddressAttributeValue>
<Value>2</Value>
</AddressAttributeValue>
</AddressAttribute>
</Attributes>
Is there any way to convert each column to element with the same name and differs only with attribute ID
?
Upvotes: 2
Views: 577
Reputation: 67341
There is one accepted answer already, which is great. Just as an alternative...
Short explanation: Normally the engine would not allow to place several elements with the same name in the same level in one go. But the ,''
(empty elements) in between tell the engine to close one element and to start a new one.
DECLARE @Addr TABLE(StreetNumber varchar(50),Apartment varchar(50),Floor varchar(50));
INSERT INTO @Addr VALUES('SomeStreet', 'App 1', 'Floor 2');
SELECT 1 AS [AddressAttribute/@ID]
,a.StreetNumber [AddressAttribute/AddressAttributeValue/Value]
,''
,2 AS [AddressAttribute/@ID]
,a.Apartment [AddressAttribute/AddressAttributeValue/Value]
,''
,3 AS [AddressAttribute/@ID]
,a.Floor AS [AddressAttribute/AddressAttributeValue/Value]
,''
FROM @Addr AS a
FOR XML PATH(''),ROOT('Attributes');
The result
<Attributes>
<AddressAttribute ID="1">
<AddressAttributeValue>
<Value>SomeStreet</Value>
</AddressAttributeValue>
</AddressAttribute>
<AddressAttribute ID="2">
<AddressAttributeValue>
<Value>App 1</Value>
</AddressAttributeValue>
</AddressAttribute>
<AddressAttribute ID="3">
<AddressAttributeValue>
<Value>Floor 2</Value>
</AddressAttributeValue>
</AddressAttribute>
</Attributes>
Upvotes: 1
Reputation: 139010
You can create the XML in a subquery in the column list where you unpivot the values in a table constructor, giving each column an ID.
Here is a sample that uses a table variable as the source of data. You should of course use your table instead.
declare @T table
(
StreetNumber varchar(50),
Apartment varchar(50),
Floor varchar(50)
);
insert into @T values('Street', 'Apartment', 'Floor');
select (
select R.ID as '@ID',
R.Value as 'AddressAttributeValue/Value'
from (values(1, T.StreetNumber),
(2, T.Apartment),
(3, T.Floor)) as R(ID, Value)
for xml path('AddressAttribute'), root ('Attributes'), type
)
from @T as T;
Result:
<Attributes>
<AddressAttribute ID="1">
<AddressAttributeValue>
<Value>Street</Value>
</AddressAttributeValue>
</AddressAttribute>
<AddressAttribute ID="2">
<AddressAttributeValue>
<Value>Apartment</Value>
</AddressAttributeValue>
</AddressAttribute>
<AddressAttribute ID="3">
<AddressAttributeValue>
<Value>Floor</Value>
</AddressAttributeValue>
</AddressAttribute>
</Attributes>
Upvotes: 4