次の方法で共有


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) へのマッピングを指定します。 その後、FOR XML クエリによって構築される要素名と属性名を指定する際に、 ns1 プレフィックスが使用されます。

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 を使用すると自動的に追加されます。 次のクエリでは、要素中心の XML を生成する 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 によって、既定の名前空間と共に定義される 2 つの名前空間プレフィックスが定義されています。

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>  

次の PATH モードクエリに示すように、WITH XMLNAMESPACES で明示的に定義せずに使用できるのは、xml 名前空間プレフィックスだけです。 また、プレフィックスが宣言されている場合は、名前空間 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>  

XML データ型メソッドでの WITH XMLNAMESPACES の使用

SELECT クエリまたは UPDATE で指定された xml データ型メソッドmodify() メソッドの場合は、すべてプロローグで名前空間宣言を繰り返す必要があります。 これには時間がかかる場合があります。 たとえば、次のクエリは、カタログの説明に仕様が含まれている製品モデル ID を取得します。 つまり、 <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)