Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add a namespace on an xml generated by a query

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>
like image 387
Dan Avatar asked Sep 28 '10 21:09

Dan


People also ask

How do I add a namespace to an XML file?

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".

What is namespace in XML with examples?

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.

Which keyword is used to declare a namespace in XML?

The Namespace starts with the keyword xmlns. The word name is the Namespace prefix.

What is namespace in SQL?

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.


1 Answers

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.

like image 69
LarsH Avatar answered Sep 29 '22 15:09

LarsH