Monday, March 12, 2012

nested FOR XML queries / with namespaces

I want to assign the result of a FOR XML query containing nested queries to an xml variable. The problem is, the namespace declarations propagate down to every nested element generated in the query.

DECLARE @.x xml
BEGIN
WITH XMLNAMESPACES('one' AS ns1, 'two' AS ns2)
SELECT @.x = (
SELECT -1 "@.id",
'invalid' "@.status",
(SELECT 'false' "@.flag",
'etc' "@.comment"
FOR XML PATH ('ns2:inner'), TYPE)
FOR XML PATH('ns1:0uter'), TYPE);
SELECT @.x
END;

This is the XML that is generated:

<ns1:0uter xmlns:ns2="two" xmlns:ns1="one" id="-1" status="invalid">
<ns2:inner xmlns:ns2="two" xmlns:ns1="one" flag="false" comment="etc" />
</ns1:0uter>

Is there an alternate way to declare a namespace in a nested query (in this case, move the namespace declaration for 'two AS ns2' out of the outer query into the nested select)? If not, then are there alternative ways to remove this extraneous stuff? This is a simple example, but real-world instances involving several levels of nesting these declarations are too much.

I have the same question. I simply need to add

xmlns="urn:xxxx.yyyyy.zzzzz"

in the header of the XML only.

I review the MDSN details: http://msdn2.microsoft.com/en-us/library/ms177400.aspx but don't see how to accomplish this simple thing.

I can't even fake it out:

SELECT

'en-US' AS "MessageLanguage",

'2007-05-08T18:13:51.0Z' AS "IssueDate",

'urn:xxxx.yyyyy.zzzzz' AS "@.xmlns",

The select returns error:

'xmlns' is invalid in XML tag name in FOR XML PATH, or when WITH XMLNAMESPACES is used with FOR XML.

|||

I have the same problem with this query:

Code Snippet

declare @.category_name as varchar(512);
set @.category_name = 'Bolt';

with xmlnamespaces ('http://services.ihs.com/schemas/structured_content' as sc)

select id as [@.sc:id], 'ADD' as [@.sc:action], cat_id as [@.sc:categoryId],

(select attribute_id as [@.sc:attributeId], value as [data()]

from Item_Detail (nolock)

where item_id = Item.id

for xml path('sc:VALUE'), type)

from Item (nolock)

where cat_id = (select id from Category (nolock) where name = @.category_name)

for xml path('sc:ITEM'), root('sc:ITEMS')
;

Each of the 22 million nested sc:VALUE result elements unnecessarily rebind the namespace prefix:

Code Snippet

<sc:ITEMS xmlns:sc="http://services.ihs.com/schemas/structured_content">

<sc:ITEM sc:id="ABE9639D-3C7B-4E66-BF32-00001A294577" sc:action="ADD" sc:categoryId="68541B13-9C60-4D90-B694-68C28F346832">

<sc:VALUE xmlns:sc="http://services.ihs.com/schemas/structured_content" sc:attributeId="E9BD274C-34C2-44A1-8F54-6E5218C71A9A">STEEL ALLOY</sc:VALUE>

...

No comments:

Post a Comment