Hinzufügen von Namespaces zu Abfragen mit WITH XMLNAMESPACES
Gilt für:SQL ServerAzure SQL-DatenbankAzure SQL Managed Instance
WITH XMLNAMESPACES (Transact-SQL) bietet folgende Namespace-URI-Unterstützung:
Macht das Namespacepräfix für die URI-Zuordnung bei Abfragen mit Erstellen von XML mit FOR XML verfügbar.
Macht die Namespace-URI-Zuordnung für den statischen Namespacekontext für XML-Datentypmethodenverfügbar.
Verwenden von WITH XMLNAMESPACES in FOR XML-Abfragen
Mit WITH XMLNAMESPACES können Sie XML-Namespaces in FOR XML-Abfragen einbeziehen. Nehmen Sie beispielsweise folgende FOR XML-Abfrage:
SELECT ProductID, Name, Color
FROM Production.Product
WHERE ProductID IN (316, 317)
FOR XML RAW;
Dies ist das Ergebnis:
<row ProductID="316" Name="Blade" />
<row ProductID="317" Name="LL Crankarm" Color="Black" />
Um Namespaces zu dem durch die FOR XML-Abfrage erstellten XML hinzuzufügen, legen Sie zuerst mit der WITH NAMESPACES-Klausel die Zuordnungen der Namespacepräfixe zu URIs fest. Verwenden Sie anschließend in der folgenden geänderten Abfrage die Namespacepräfixe, um die in der Abfrage verwendeten Namen festzulegen. Die WITH XMLNAMESPACES-Klausel gibt das Namespacepräfix (ns1
) zu URI (uri
) -Zuordnung an. Das ns1
-Präfix wird dann beim Festlegen der Element- und Attributnamen verwendet, die durch die FOR XML-Abfrage erstellt werden sollen.
WITH XMLNAMESPACES ('uri' as ns1)
SELECT ProductID as 'ns1:ProductID',
Name as 'ns1:Name',
Color as 'ns1:Color'
FROM Production.Product
WHERE ProductID IN (316, 317)
FOR XML RAW ('ns1:Prod'), ELEMENTS;
Das XML-Ergebnis enthält die Namespacepräfixe:
<ns1:Prod xmlns:ns1="uri">
<ns1:ProductID>316</ns1:ProductID>
<ns1:Name>Blade</ns1:Name>
</ns1:Prod>
<ns1:Prod xmlns:ns1="uri">
<ns1:ProductID>317</ns1:ProductID>
<ns1:Name>LL Crankarm</ns1:Name>
<ns1:Color>Black</ns1:Color>
</ns1:Prod>
Für die WITH XMLNAMESPACES-Klausel gilt Folgendes:
Sie wird nur im RAW-, AUTO- und PATH-Modus der FOR XML-Abfragen unterstützt. Der EXPLICIT-Modus wird nicht unterstützt.
Sie wirkt sich nur auf die Namespacepräfixe von FOR XML-Abfragen und auf die xml -Datentypmethode aus – aber nicht auf den XML-Parser. Die folgende Abfrage gibt beispielsweise einen Fehler zurück, weil das XML-Dokument keine Namespacedeklaration für das myNS-Präfix enthält.
Die FOR XML-Direktiven, XMLSCHEMA und XMLDATA können nicht verwendet werden, wenn eine WITH XMLNAMESPACES-Klausel verwendet wird.
CREATE TABLE T (x xml); GO WITH XMLNAMESPACES ('https://abc' as myNS ) INSERT INTO T VALUES('<myNS:root/>'); GO
Verwenden der XSINIL-Direktive
Sie können das XSI-Präfix in der WITH XMLNAMESPACES-Klausel nicht definieren, wenn Sie die ELEMENTS XSINIL-Direktive verwenden. Stattdessen wird es automatisch hinzugefügt, wenn Sie ELEMENTS XSINIL verwenden. Die folgende Abfrage verwendet ELEMENTS XSINIL, die elementzentriertes XML generiert, wo Elementen, deren xsi:nil -Attribut auf TRUE festgelegt ist, Nullwerte zugeordnet werden.
WITH XMLNAMESPACES ('uri' as ns1)
SELECT ProductID as 'ns1:ProductID',
Name as 'ns1:Name',
Color as 'ns1:Color'
FROM Production.Product
WHERE ProductID = 316
FOR XML RAW, ELEMENTS XSINIL;
Dies ist das Ergebnis:
<row xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns1="uri">
<ns1:ProductID>316</ns1:ProductID>
<ns1:Name>Blade</ns1:Name>
<ns1:Color xsi:nil="true" />
</row>
Angeben von Standardnamespaces
Statt ein Namespacepräfix zu deklarieren, können Sie mit dem DEFAULT-Schlüsselwort einen Standardnamespace deklarieren. In der FOR XML-Abfrage wird der Standardnamespace mit den XML-Knoten des resultierenden XML verbunden. Im folgenden Beispiel definiert WITH XMLNAMESPACES zwei Namespacepräfixe, die gemeinsam über einen Standardnamespace definiert sind.
WITH XMLNAMESPACES ('uri1' as ns1,
'uri2' as ns2,
DEFAULT 'uri2')
SELECT ProductID,
Name,
Color
FROM Production.Product
WHERE ProductID IN (316, 317)
FOR XML RAW ('ns1:Product'), ROOT('ns2:root'), ELEMENTS;
Die FOR XML-Abfrage generiert elementzentriertes XML. Die Abfrage verwendet beide Namespacepräfixe in Benennungsknoten. In der SELECT-Klausel geben "ProductID", "Name" und "Color" keinen Namen mit einem Präfix an. Daher gehören die entsprechenden Elemente des resultierenden XML zum Standardnamespace.
<ns2:root xmlns="uri2" xmlns:ns2="uri2" xmlns:ns1="uri1">
<ns1:Product>
<ProductID>316</ProductID>
<Name>Blade</Name>
</ns1:Product>
<ns1:Product>
<ProductID>317</ProductID>
<Name>LL Crankarm</Name>
<Color>Black</Color>
</ns1:Product>
</ns2:root>
Die folgende Abfrage ähnelt der vorherigen, allerdings ist der FOR XML AUTO-Modus festgelegt.
WITH XMLNAMESPACES ('uri1' as ns1, 'uri2' as ns2,DEFAULT 'uri2')
SELECT ProductID,
Name,
Color
FROM Production.Product as "ns1:Product"
WHERE ProductID IN (316, 317)
FOR XML AUTO, ROOT('ns2:root'), ELEMENTS;
Verwenden vordefinierter Namespaces
Wenn Sie vordefinierte Namespaces verwenden, müssen Sie (mit Ausnahme von xml-Namespace und xsi-Namespace, wenn ELEMENTS XSINIL verwendet wird) die Namespacebindung mit WITH XMLNAMESPACES explizit festlegen. Die folgende Abfrage definiert explizit den Namespacepräfix für die URI-Bindung für den vordefinierten Namespace (urn:schemas-microsoft-com:xml-sql
).
WITH XMLNAMESPACES ('urn:schemas-microsoft-com:xml-sql' as sql)
SELECT 'SELECT * FROM Customers FOR XML AUTO, ROOT("a")' AS "sql:query"
FOR XML PATH('sql:root');
Dies ist das Ergebnis. SQLXML-Benutzer kennen diese XML-Vorlage. Weitere Informationen finden Sie unter SQLXML 4.0-Programmierkonzepte.
<sql:root xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<sql:query>SELECT * FROM Customers FOR XML AUTO, ROOT("a")</sql:query>
</sql:root>
Nur das xml-Namespacepräfix kann verwendet werden ohne explizit in WITH XMLNAMESPACES definiert zu sein, was die folgende Abfrage im PATH-Modus zeigt. Wenn das Präfix deklariert wird, muss es außerdem mit dem Namespace http://www.w3.org/XML/1998/namespace verbunden werden. Die in der SELECT-Klausel angegebenen Namen beziehen sich auf das XML-Namespacepräfix, das nicht explizit mithilfe von WITH XMLNAMESPACES definiert ist.
SELECT 'en' as "English/@xml:lang",
'food' as "English",
'ger' as "German/@xml:lang",
'Essen' as "German"
FOR XML PATH ('Translation');
GO
Die @xml:lang
-Attribute verwenden den vordefinierten XML-Namespace. Da die XML-Version 1.0 die explizite Deklaration der XML-Namespacebindung nicht erfordert, enthält das Ergebnis keine explizite Deklaration der Namespacebindung.
Dies ist das Ergebnis:
<Translation>
<English xml:lang="en">food</English>
<German xml:lang="ger">Essen</German>
</Translation>
Verwenden von WITH XMLNAMESPACES mit den XML-Datentypmethoden
Die xml-Datentypmethoden , die in einer SELECT-Abfrage oder in UPDATE angegeben sind, wenn sie die modify()
Methode ist, müssen alle die Namespacedeklaration in ihrem Prolog wiederholen. Dies kann einige Zeit in Anspruch nehmen. Die folgende Abfrage ruft beispielsweise Produktmodell-IDs ab, deren Katalogbeschreibungen eine Spezifikation enthalten. Das heißt, das <Specifications>
Element ist vorhanden.
SELECT ProductModelID, CatalogDescription.query('
declare namespace pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
<Product
ProductModelID= "{ sql:column("ProductModelID") }"
/>
') AS Result
FROM Production.ProductModel
WHERE CatalogDescription.exist('
declare namespace pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
/pd:ProductDescription[(pd:Specifications)]'
) = 1;
In der vorherigen Abfrage deklarieren sowohl die Methoden exist()
als auch die query()
Methoden denselben Namespace in ihrem Prolog. Beispiel:
declare namespace pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
Alternativ können Sie zuerst WITH XMLNAMESPACES deklarieren und in der Abfrage dann die Namespacepräfixe verwenden. In diesem Fall müssen die query()
Methoden keine exist()
Namespacedeklarationen in ihr Prolog einschließen.
WITH XMLNAMESPACES ('https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription' as pd)
SELECT ProductModelID, CatalogDescription.query('
<Product
ProductModelID= "{ sql:column("ProductModelID") }"
/>
') AS Result
FROM Production.ProductModel
WHERE CatalogDescription.exist('
/pd:ProductDescription[(pd:Specifications)]'
) = 1;
GO
Eine explizite Deklaration im XQuery-Prolog setzt das Namespacepräfix und den Standardelementnamespace außer Kraft, der in der WITH-Klausel definiert ist.
Siehe auch
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für