2010-09-28 4 views
6

Ich versuche, einen Namespace in XML mit WITH XMLNAMESPACES hinzuzufügen.Fügen Sie einen Namespace in einem XML-Objekt hinzu, das von einer Abfrage generiert wurde

Wenn ich meine Abfragen ausführen, wird der Namensraum mit dem Root-Element hinzugefügt, aber mit dem zweiten Element I Xmlns haben = „“ und ... und das würde ich entfernen möchte ...

I zur Verfügung gestellt ein Beispiel:

fragt die Tabelle für die Erstellung und die Daten:

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 

ich die XML mit diesen Abfragen generieren:

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 generiert: So

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

, versuche ich dies auch:

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') 

die erzeugte XML ist jetzt:

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

Antwort

5

Daniel, der xmlns="" auf den <DataRows> Elementmittel Setzen Sie den Standardnamespace für <DataRows> und alle Nachkommen auf keinen Namespace.

Mit anderen Worten, wenn die xmlns="" nicht da wäre, wäre die gesamte XML-Struktur im http://www.mynamespace.com Namespace. (Weil Namespace-Deklarationen vererbt werden, bis sie überschrieben werden.) Und das ist wahrscheinlich das, was Sie wollten. Aber SQL Server denkt, dass Sie nur das Element <Names> in diesem Namespace haben möchten. Daher ist es "hilfreich", den Standard-Namespace für alle untergeordneten Elemente zu entfernen.

Die Lösung, dann ist SQL Server zu sagen, dass alle die Elemente, nicht nur <Names> im http://www.mynamespace.com Namensraum sein sollten.

(Wenn Sie mich fragen, wie man das macht, ist die Antwort, dass ich SQL Server XML-Funktionen nicht gut kenne. Aber vielleicht klärt man, was passiert und was passieren muss, um herauszufinden, wie man es machen kann.

)

aktualisieren im Lichte der neu geschrieben Abfrage und Ausgabe:

@ Daniel, ist die Ausgabe nun technisch korrekt. Alle Ausgabeelemente befinden sich im Namespace http://www.mynamespace.com. Die xmlns="http://www.mynamespace.com" Deklarationen auf den <Row> Elementen sind redundant ... sie ändern nicht den Namensraum irgendeines Elements.

Sie mögen die zusätzlichen Deklarationen nicht mögen, aber sie sollten keinen Unterschied zu nachgeschalteten XML-Tools machen.

Wenn Sie diese entfernen möchten und dies nicht durch Anpassen der SQL-Abfrage möglich ist, können Sie das resultierende XML über ein XSLT-Stylesheet ausführen. Selbst ein identity transformation wird wahrscheinlich die redundanten Namespace-Deklarationen loswerden, glaube ich.

+0

@Daniel, was passiert, wenn Sie 'WITH XMLNAMESPACES (DEFAULT 'http://www.mynamespace.com')' auf Ihre erste SELECT in der 'SET @ XML = ...' Anweisung setzen?(Und wo es bereits ist) – LarsH

+0

Ich habe versucht, aber ich kann nicht ein WITH XMLNAMESPACES in einem SET ... Eine andere Sache, tatsächlich jedes Mal, wenn es ein SELECT gibt, wird der Namespace von Sql Server festgelegt. – Dan

+0

Also, ich habe das SET durch ein SELECT ersetzen und ich habe die WITH XMLNAMESPACES kurz zuvor. Die Abfrage wird jetzt ausgeführt, aber nur den Namespace mit den "Row" -Elementen platzieren ... – Dan