Question : Problem using WITH XMLNAMESPACES with nested queries

Greetings!

I'm building some large xml documents from a number of relational tables in my database (SQL Server 2005).  Due to the scale of it, I have a number of scalar UDFs that return xml and I use them inline in queries to build the different levels of my xml output.

The output document needs to conform to a schema, which has a target namespace specific to my application.  Therefore, I'd like to add a default namespace to the xml that comes out of the database.  I can do this using:

WITH XMLNAMESPACES (DEFAULT 'http://myDefaultNS')
SELECT ...

The problem is that when I then use my udf inline, the root node generated in the udf comes out with a default namespace defined as an empy string, thus invalidating itself and everything beneath it (as far as the schema is concerned).

The attached code snippet give a good example and produces the following output:

http://myDefaultNS">
 


Could this be a bug or have i missed a trick somewhere?

[Note: building in the namespaces (and hence the xml) using strings is out of the question.  i've been there and it doesn't scale well at all.  Also, i'm aware that you can use embedded queries instead of inline udfs, though that would eliminate any modularity, and it also outputs a default namespace on every element (though at least the correct one: "http://myDefaultNS")]

Any ideas?

Thanks,
Eric
Code Snippet:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
 
-- create the child function
CREATE FUNCTION fnGetChildXML ()
RETURNS xml
AS
BEGIN
	RETURN CONVERT(xml,'')
END
GO
 
-- select xml
WITH XMLNAMESPACES (DEFAULT 'http://myDefaultNS')
SELECT dbo.fnGetChildXML() AS '*'
FOR XML PATH('root'), TYPE
GO
 
-- tidy
DROP FUNCTION fnGetChildXML
GO

Answer : Problem using WITH XMLNAMESPACES with nested queries

Ok, i've found the following article that i think explains what's going on:

http://msdn.microsoft.com/en-us/library/ms345137(SQL.90).aspx

The relevant paragraph reads:

"Note that if there are nested XML documents with no default namespace included in the result, a slight performance penalty has to be paid to make sure that they preserve their absence of a default namespace."

What I'm doing is trying to get SQL Server to ignore the fact that I'm inserting some xml without a default namespace, into xml with a default namespace, wanting my child to inherit the default namespace of the parent.  I think it's too smart for this and knows that the insertion will change the default namespace of the child, unless it explicitly sets xmlns="" for the child xml.

This suggests that I'd have to add the default namespace in every level of my xml, which I really don't want to do.  Maybe another way to look at it is "can I add a default namespace to the root of an existing document", so i can create the document without a default namespace, and then add it to the root afterwards.  I've not yet succeeded in doing this... i run into the same problem where it wants to "correct" the default namespace for everything under the node you add the explicit default namespace to.

Eric
Random Solutions  
 
programming4us programming4us