I try to add a namespace on xml using WITH XMLNAMESPACES.
When I execute my queries, the namespace is added with the root element but with the second element I have xmlns="" as well... and I would like to remove that...
I provided an example:
Queries for creating the table and the data:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[tblTest](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](30) NOT NULL,
CONSTRAINT [PK_tblTest] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[tblTest] ON
INSERT [dbo].[tblTest] ([Id], [Name]) VALUES (1, N'Barack')
INSERT [dbo].[tblTest] ([Id], [Name]) VALUES (2, N'Nicolas')
INSERT [dbo].[tblTest] ([Id], [Name]) VALUES (3, N'Brian')
SET IDENTITY_INSERT [dbo].[tblTest] OFF
I generate the xml with these queries:
DECLARE @Xml xml
SET @Xml = (SELECT Id, Name
FROM dbo.tblTest
FOR XML PATH('Row'), ROOT('DataRows'));
WITH XMLNAMESPACES (DEFAULT 'http://www.mynamespace.com')
SELECT @Xml FOR XML PATH('Names');
Xml generated:
<Names xmlns="http://www.mynamespace.com">
<DataRows xmlns="">
<Row>
<Id>1</Id>
<Name>Barak</Name>
</Row>
<Row>
<Id>2</Id>
<Name>Nicolas</Name>
</Row>
<Row>
<Id>3</Id>
<Name>Brian</Name>
</Row>
</DataRows>
</Names>
So, I try this as well:
DECLARE @Xml xml
;WITH XMLNAMESPACES (DEFAULT 'http://www.mynamespace.com')
SELECT @Xml = (SELECT Id, Name
FROM dbo.tblTest
FOR XML PATH('Row'), TYPE);
;WITH XMLNAMESPACES (DEFAULT 'http://www.mynamespace.com')
SELECT @Xml
FOR XML PATH('DataRows'), ROOT('Names')
the xml generated is now:
<Names xmlns="http://www.mynamespace.com">
<DataRows>
<Row xmlns="http://www.mynamespace.com">
<Id>1</Id>
<Name>Barak</Name>
</Row>
<Row xmlns="http://www.mynamespace.com">
<Id>2</Id>
<Name>Nicolas</Name>
</Row>
<Row xmlns="http://www.mynamespace.com">
<Id>3</Id>
<Name>Brian</Name>
</Row>
</DataRows>
</Names>
XML Namespaces - The xmlns Attribute When using prefixes in XML, a namespace for the prefix must be defined. The namespace can be defined by an xmlns attribute in the start tag of an element. The namespace declaration has the following syntax. xmlns:prefix="URI".
An XML namespace is a collection of names that can be used as element or attribute names in an XML document. The namespace qualifies element names uniquely on the Web in order to avoid conflicts between elements with the same name.
The Namespace starts with the keyword xmlns. The word name is the Namespace prefix.
Entity SQL introduces namespaces to avoid name conflicts for global identifiers such as type names, entity sets, functions, and so on. The namespace support in Entity SQL is similar to the namespace support in the . NET Framework.
Daniel, the xmlns=""
on the <DataRows>
element means, set the default namespace for <DataRows>
and all descendants to no namespace.
In other words, if the xmlns=""
were not there, the whole XML tree would be in the http://www.mynamespace.com
namespace. (Because namespace declarations are inherited, until overridden.) And that's probably what you wanted. But SQL Server thinks you wanted only the <Names>
element to be in that namespace. So it is "helpfully" removing the default namespace for all descendant elements.
The solution, then, is to tell SQL Server that all the elements, not just <Names>
, should be in the http://www.mynamespace.com
namespace.
(If you ask me how to do that, the answer is I don't know SQL Server XML features that well. But maybe clarifying what's happening and what needs to happen will help you figure out how to make it happen.)
Update in light of newly posted query and output:
@Daniel, your output is now technically correct. All the output elements are in the http://www.mynamespace.com
namespace. The xmlns="http://www.mynamespace.com"
declarations on the <Row>
elements are redundant... they don't change the namespace of any element.
You may not like them the extra declarations, but they should not make any difference to any downstream XML tools.
If you want to remove them, and if you can't do that by tweaking the SQL query, you could run the resulting XML through an XSLT stylesheet. Even an identity transformation will probably get rid of the redundant namespace declarations, I believe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With