2012-07-12 59 views
0

有点卡在这一个。我有一个名称/值列的表:FOR XSINIL使用动态节点名称

NameValue table 
----------------------------------------------------------- 
Name varchar(100) Value varchar(100) 
----------------------------------------------------------- 
FirstName   First value 
SecondName   Second value 
ThirdName   Null or Empty String 
etc...    

我试图让我的结果看起来像下面的XML,但我不能完全到达那里。

<MyValues xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <FirstName>First value</FirstName> 
    <SecondName>Second value</SecondName> 
    <ThirdName xsi:nil="true" /> 
</MyValues> 

要获得动态名称的工作,我Concat的XML并铸成XML像这样:

select cast('<' + name + '>' + value + '</' + name + '>' as xml) 
from NameValue 
for xml raw(''), root('MyValues'), elements xsinil 

上面的查询生成这个XML没有xsi:nil="true"

<MyValues xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <FirstName>First value</FirstName> 
    <SecondName>Second value</SecondName> 
    <ThirdName /> 
</MyValues> 

如果我不作为XML格式化后,我剩下以下内容:

<MyValues xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
&lt;FirstName&gt;First value&lt;/FirstName&gt;&lt; 
etc... 

我尝试在连接中添加xsi:nil="true",但收到有关缺少名称空间的错误。我猜,使这项工作,我将不得不在同一个命名空间添加到包含null或空字符串每一行,所以结果看起来就会像下面这样:

<MyValues> 
    <FirstName>First value</FirstName> 
    <SecondName>Second value</SecondName> 
    <ThirdName xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" /> 
</MyValues> 

有可能是在结果集中有几百个这样的空字符串,所以我宁愿将该名称空间放在根级别以节省带宽。这是可能吗?

回答

0

而不是使用FOR XML,我只是将整个XML作为concatinated字符串。

declare @xml varchar(max) 
set @xml = '<MyValues xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' 

select @xml = '<' + name + 
    case when len(value) = 0 then 'xsi:nil="true" />' 
     else '>' + value + '</' + name + '>' 
    end 
from NameValue 

select @xml + "</MyValues>"