Kinda stuck on this one. I have a table with name/value columns:
NameValue table
-----------------------------------------------------------
Name varchar(100) Value varchar(100)
-----------------------------------------------------------
FirstName First value
SecondName Second value
ThirdName Null or Empty String
etc...
I’m trying to get my result to look like the following XML, but I can’t quite get there.
<MyValues xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<FirstName>First value</FirstName>
<SecondName>Second value</SecondName>
<ThirdName xsi:nil="true" />
</MyValues>
To get the dynamic names working, I concat the XML and cast as XML like so:
select cast('<' + name + '>' + value + '</' + name + '>' as xml)
from NameValue
for xml raw(''), root('MyValues'), elements xsinil
The above query produces this XML without xsi:nil="true"
<MyValues xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<FirstName>First value</FirstName>
<SecondName>Second value</SecondName>
<ThirdName />
</MyValues>
If I don’t cast as XML, I’m left with the following:
<MyValues xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<FirstName>First value</FirstName><
etc...
I tried adding the xsi:nil="true" in the concatination, but receive errors about the missing namespace. I’m guessing to make this work, I’m going to have to add the same namespace to every single row that contains null or empty string, so the result would look like the following:
<MyValues>
<FirstName>First value</FirstName>
<SecondName>Second value</SecondName>
<ThirdName xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" />
</MyValues>
There could be a few hundred of these empty strings in the resultset, so I’d prefer to put the namespace at the root level to conserve on bandwidth. Is this at all possible?
Instead of using FOR XML, I simply did the entire XML as a concatinated string.