Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add Attribute to ElementNode created by TSQL FOR XML Path

I am trying to match some XML output in a SQL Server 2008 TSQL query. The XML I am matching can return Lists of items. The lists are identified by attribute name - not the node name.

The XML Path functions will return a wrapper node but I can't find a way to add any attributes to that node. In my case they will be hard coded values based on the table name I am running they select against.

I have the 'x' as 'x' in there to keep the two lists separated. In my actual data that is not a problem as these are in different nodes. The problem is just how to get attributes added to the "List" node.

Here is a SQL Fiddle page for the example below:

Sample Schema

create table Table1 (Value varchar(50)); 
create table Table2 (Value varchar(50)); 

insert Table1 values
('A'), ('B'), ('C');

insert Table2 values
('X'), ('Y'), ('Z');

Sample Select

select 
(
 select Value as '@I'
 from Table1
 for XML PATH('L'), TYPE
) as List,
'x' as 'x', -- needed to keep the Lists apart.
(
 select Value as '@I'
 from Table2
 for XML PATH('L'), TYPE
) as List

for XML PATH

Actual Output

<row>
  <List>
    <L I="A"/>
    <L I="B"/>
    <L I="C"/>
  </List>

  <x>x</x>

  <List>
    <L I="X"/>
    <L I="Y"/>
    <L I="Z"/>
  </List>
</row>

Desired Output: (Adding the "Name" attribute to the list wrapper.)

<row>
  <List Name='Table1'>  <!-- Added Attribute "Name" here -->
    <L I="A"/>
    <L I="B"/>
    <L I="C"/>
  </List>

  <x>x</x>

  <List Name='Table2'>  <!-- Added Attribute "Name" here -->
    <L I="X"/>
    <L I="Y"/>
    <L I="Z"/>
  </List>
</row>
like image 509
Mark Elder Avatar asked Jul 20 '12 19:07

Mark Elder


1 Answers

This appears to give the correct output. An extra level of XML PATH nesting is required to get the attribute onto the List node:

SELECT
(SELECT 'Table1' AS '@name',
  (SELECT Value AS '@I'
   FROM Table1
   FOR XML PATH ('L'))
 FOR XML PATH('List'), TYPE)
,'x' AS'x'
,( SELECT 'Table2' AS '@name',
  (SELECT Value AS '@I'
   FROM Table2
   FOR XML PATH ('L'))
 FOR XML PATH('List'), TYPE
)

FOR XML PATH;
like image 127
Ed Harper Avatar answered Nov 15 '22 10:11

Ed Harper