共用方式為


使用 WITH XMLNAMESPACES 將命名空間加入至查詢

WITH XMLNAMESPACES (Transact-SQL) 會以下列方式支援命名空間 URI:

在 FOR XML 查詢中使用 WITH XMLNAMESPACES

WITH XMLNAMESPACES 讓您可以在 FOR XML 查詢中包括 XML 命名空間。 例如,請看下列的 FOR XML 查詢:

SELECT ProductID, Name, Color  
FROM   Production.Product  
WHERE  ProductID=316 or ProductID=317  
FOR XML RAW  

以下是結果:

<row ProductID="316" Name="Blade" />  
<row ProductID="317" Name="LL Crankarm" Color="Black" />  
  

若要將命名空間加入到 FOR XML 查詢所建構的 XML 中,請先使用 WITH NAMESPACES 子句,指定命名空間前置詞到 URI 的對應。 接著,使用命名空間前置詞,在查詢中指定名稱,如下列修改過的查詢所示。 請注意,WITH XMLNAMESPACES 子句會指定命名空間前置詞(ns1)對應到 URI(uri)。 然後 ns1 前置詞會用來指定 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=316 or ProductID=317  
FOR XML RAW ('ns1:Prod'), ELEMENTS  
  

XML 結果會包括命名空間前置詞:

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

下列適用於 WITH XMLNAMESPACES 子句:

  • 只有 FOR XML 查詢的 RAW、AUTO 及 PATH 模式才支援。 不支援 EXPLICIT 模式。

  • 它只會影響 FOR XML 查詢的命名空間前置詞及 xml 資料類型方法,但不會影響 XML 剖析器。 例如,下列查詢會傳回錯誤,因為 XML 文件沒有 myNS 前置詞的命名空間宣告。

  • 使用WITH XMLNAMESPACES 子句時,無法使用 FOR XML 指示詞、XMLSCHEMA 和 XMLDATA。

    CREATE TABLE T (x xml)  
    go  
    WITH XMLNAMESPACES ('http://abc' as myNS )  
    INSERT INTO T VALUES('<myNS:root/>')  
    

使用 XSINIL 指示詞

如果您使用 ELEMENTS XSINIL 指示詞,則無法在 WITH XMLNAMESPACES 子句中定義 xsi 前綴。 相反地,當您使用 ELEMENTS XSINIL 時,會自動新增它。 下列查詢會使用 ELEMENTS XSINIL,以產生元素中心的 XML,其中 Null 值會對應到 xsi:nil 屬性設為 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  

以下是結果:

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

指定預設命名空間

您可以使用 DEFAULT 關鍵字來宣告預設的命名空間,而不需要宣告命名空間前置詞。 在 FOR XML 查詢中,它會將預設的命名空間繫結到產生之 XML 中的 XML 節點。 在下面的範例中,WITH XMLNAMESPACES 定義兩個連同預設命名空間一起定義的命名空間前置詞。

WITH XMLNAMESPACES ('uri1' as ns1,   
                    'uri2' as ns2,  
                    DEFAULT 'uri2')  
SELECT ProductID,   
      Name,  
      Color  
FROM Production.Product   
WHERE ProductID=316 or ProductID=317  
FOR XML RAW ('ns1:Product'), ROOT('ns2:root'), ELEMENTS  

此 FOR XML 查詢會產生元素中心的 XML。 請注意,查詢會在命名節點中使用命名空間前置詞。 在 SELECT 子句中,ProductID、Name 和 Color 不會指定任何前置詞的名稱。 因此,產生之 XML 中的對應元素會隸屬於預設的命名空間。

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

下列查詢和前一個查詢很類似,差別只在下列查詢指定了 FOR XML AUTO 模式。

WITH XMLNAMESPACES ('uri1' as ns1,  'uri2' as ns2,DEFAULT 'uri2')  
SELECT ProductID,   
      Name,  
      Color  
FROM Production.Product as "ns1:Product"  
WHERE ProductID=316 or ProductID=317  
FOR XML AUTO, ROOT('ns2:root'), ELEMENTS  

使用預先定義的命名空間

使用預先定義的命名空間時,除了使用 ELEMENTS XSINIL 時的 xml 命名空間及 xsi 命名空間之外,您必須使用 WITH XMLNAMESPACES 明確地指定命名空間繫結。 下列查詢針對預先定義的命名空間 (urn:schemas-microsoft-com:xml-sql) 明確地定義了命名空間前置詞到 URI 的繫結。

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

以下是結果。 SQLXML 的使用者對這個 XML 範本很熟悉。 如需詳細資訊,請參閱 SQLXML 4.0 程式設計概念

<sql:root xmlns:sql="urn:schemas-microsoft-com:xml-sql">  
  <sql:query>SELECT * FROM Customers FOR XML AUTO, ROOT("a")</sql:query>  
</sql:root>  

只有 xml 命名空間的前綴可以在不明確定義於 WITH XMLNAMESPACES 的情況下使用,如以下 PATH 模式查詢所示。 同時,若前置詞已經宣告了,就必須將它繫結到命名空間 http://www.w3.org/XML/1998/namespace 。 SELECT 子句中指定的名稱,會參考尚未使用 WITH XMLNAMESPACES 明確定義的 xml 命名空間前綴。

SELECT 'en'    as "English/@xml:lang",  
       'food'  as "English",  
       'ger'   as "German/@xml:lang",  
       'Essen' as "German"  
FOR XML PATH ('Translation')  
go  

@xml:lang 屬性會使用預先定義的 XML 命名空間。 由於 XML 1.0 版不需要 xml 命名空間系結的明確宣告,因此結果不會包含命名空間系結的明確宣告。

以下是結果:

<Translation>  
  <English xml:lang="en">food</English>  
  <German xml:lang="ger">Essen</German>  
</Translation>  

使用 WITH XMLNAMESPACES 結合 XML 資料類型的操作方法

在 SELECT 查詢中指定的 xml 資料類型方法 ,或在 UPDATE 中指定為 modify() 方法時,所有方法都必須在其初構中重複命名空間宣告。 這可能會很費時。 例如,下列查詢會擷取其目錄描述確實包括規格的產品型號識別碼。 也就是說,元素 <Specifications> 存在。

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  

在上一個查詢中, query()exist() 方法都會在其初構中宣告相同的命名空間。 例如:

declare namespace pd="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelDescription";  

另外,您也可以先宣告 WITH XMLNAMESPACES,然後在查詢中使用命名空間前置詞。 在此情況下, query()exist() 方法不需要在其初構中包含命名空間宣告。

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  

請注意,XQuery 初構中的明確宣告會覆寫命名空間前置詞和 WITH 子句中定義的預設元素命名空間。

另請參閱

xml 資料類型方法
Xquery 語言參考 (SQL Server)
WITH XMLNAMESPACES (Transact-SQL)
FOR XML (SQL Server)