Přidejte obory názvů do dotazů pomocí WITH XMLNAMESPACES
platí pro:SQL Server
Azure SQL Database
azure SQL Managed Instance
WITH XMLNAMESPACES (Transact-SQL) poskytuje podporu URI oboru názvů následujícím způsobem:
Zpřístupňuje předponu oboru názvů mapování identifikátoru URI při vytváření XML pomocí dotazů FOR XML.
Zpřístupňuje mapování oboru názvů na identifikátor URI pro statický kontext oboru názvů xml metody datového typu.
Použití WITH XMLNAMESPACES v dotazech FOR XML
FUNKCE XMLNAMESPACES umožňuje zahrnout obory názvů XML do dotazů FOR XML. Představte si například následující dotaz FOR XML:
SELECT ProductID, Name, Color
FROM Production.Product
WHERE ProductID IN (316, 317)
FOR XML RAW;
Toto je výsledek:
<row ProductID="316" Name="Blade" />
<row ProductID="317" Name="LL Crankarm" Color="Black" />
Pokud chcete přidat obory názvů do XML vytvořeného dotazem FOR XML, nejprve zadejte předponu oboru názvů k mapování identifikátorů URI pomocí klauzule WITH NAMESPACES. Potom použijte předpony oboru názvů ke specifikaci názvů v dotazu, jak je uvedeno v následujícím upraveném dotazu. Klauzule WITH XMLNAMESPACES určuje mapování předpony oboru názvů (ns1
) na identifikátor URI (uri
). Předpona ns1
se pak použije při zadávání názvů elementů a atributů, které se mají vytvořit pomocí dotazu FOR XML.
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;
Výsledek XML obsahuje předpony prostorů jmen:
<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>
Následující platí pro klauzuli WITH XMLNAMESPACES:
Podporuje se pouze v režimech RAW, AUTO a PATH dotazů FOR XML. Explicitní režim není podporovaný.
Ovlivňuje pouze předpony jmenného prostoru v dotazech FOR XML a metody datového typu xml, ale ne analyzátor XML. Následující dotaz například vrátí chybu, protože dokument XML neobsahuje deklaraci oboru názvů pro předponu myNS.
Direktivy FOR XML, XMLSCHEMA a XMLDATA nelze použít při použití klauzule WITH XMLNAMESPACES.
CREATE TABLE T (x xml); GO WITH XMLNAMESPACES ('https://abc' as myNS ) INSERT INTO T VALUES('<myNS:root/>'); GO
Použití direktivy XSINIL
Pokud používáte direktivu ELEMENTS XSINIL, nemůžete definovat předponu xsi v klauzuli WITH XMLNAMESPACES. Místo toho se přidá automaticky při použití ELEMENT XSINIL. Následující dotaz používá ELEMENT XSINIL, který generuje XML zaměřené na elementy, kde jsou hodnoty null mapovány na elementy, které mají xsi:nil atribut nastaven na True.
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;
Toto je výsledek:
<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>
Určete výchozí jmenné prostory
Místo deklarování předpony oboru názvů můžete deklarovat výchozí obor názvů pomocí klíčového slova DEFAULT. V příkazu FOR XML přiřadí výchozí obor názvů uzlům XML ve výsledném XML. V následujícím příkladu definuje funkce WITH XMLNAMESPACES dvě předpony oboru názvů, které jsou definovány společně s výchozím oborem názvů.
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;
Dotaz FOR XML vygeneruje xml orientovaný na element. Dotaz používá obě předpony oboru názvů při pojmenovávání uzlů. Ve větě SELECT nemají ProductID, Name a Color přiřazený žádný název s předponou. Proto odpovídající prvky ve výsledném XML patří do výchozího oboru názvů.
<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>
Následující dotaz se podobá předchozímu dotazu s tím rozdílem, že je zadaný režim PRO XML AUTO.
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;
Použití předdefinovaných oborů názvů
Pokud používáte předdefinované obory názvů s výjimkou oboru názvů XML a oboru názvů xsi při použití ELEMENT XSINIL, musíte explicitně zadat vazbu oboru názvů pomocí WITH XMLNAMESPACES. Následující dotaz explicitně definuje předponu oboru názvů pro vazbu URI k předdefinovanému oboru názvů (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');
Toto je výsledek. Uživatelé SQLXML jsou obeznámeni s touto šablonou XML. Další informace naleznete v tématu SQLXML 4.0 Programovací koncepty.
<sql:root xmlns:sql="urn:schemas-microsoft-com:xml-sql">
<sql:query>SELECT * FROM Customers FOR XML AUTO, ROOT("a")</sql:query>
</sql:root>
Pouze předponu oboru názvů XML lze použít bez explicitního definování v WITH XMLNAMESPACES, jak je znázorněno v následujícím dotazu režimu PATH. Pokud je předpona deklarována, musí být vázána na obor názvů http://www.w3.org/XML/1998/namespace. Názvy zadané v klauzuli SELECT odkazují na předponu oboru názvů XML, která není explicitně definována pomocí WITH XMLNAMESPACES.
SELECT 'en' as "English/@xml:lang",
'food' as "English",
'ger' as "German/@xml:lang",
'Essen' as "German"
FOR XML PATH ('Translation');
GO
Atributy @xml:lang
používají předdefinovaný obor názvů XML. Protože XML verze 1.0 nevyžaduje explicitní deklaraci vazby oboru názvů XML, výsledek nebude obsahovat explicitní deklaraci vazby oboru názvů.
Toto je výsledek:
<Translation>
<English xml:lang="en">food</English>
<German xml:lang="ger">Essen</German>
</Translation>
Použijte WITH XMLNAMESPACES s metodami datového typu xml
metody datového typu XML zadané v dotazu SELECT nebo v UPDATE, když se jedná o metodu modify()
, musí všechny opakovat deklaraci oboru názvů v jeho prologu. To může být časově náročné. Následující dotaz například načte ID modelů produktů, jejichž popisy katalogu zahrnují specifikaci. To znamená, že prvek <Specifications>
existuje.
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;
V předchozím dotazu obě metody query()
a exist()
deklarují stejný obor názvů v jejich prologu. Například:
declare namespace pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";
Alternativně můžete nejprve deklarovat WITH XMLNAMESPACES a použít předpony oboru názvů v dotazu. V tomto případě nemusí metody query()
a exist()
v jejich prologu obsahovat deklarace oboru názvů.
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
Explicitní deklarace v prologu XQuery převáží předponu oboru názvů a výchozí obor názvů pro element, který je definován v klauzuli WITH.