共用方式為


範例:使用PATH模式

下列範例說明如何從 SELECT 查詢產生 XML 時使用PATH模式。 這些查詢中有許多是針對儲存在 ProductModel 資料表的 [指示] 資料行中儲存的自行車製造指示 XML 檔所指定。

指定簡單的路徑模式查詢

此查詢會指定 FOR XML PATH 模式。

USE AdventureWorks2012;  
GO  
SELECT   
       ProductModelID,  
       Name  
FROM Production.ProductModel  
WHERE ProductModelID=122 OR ProductModelID=119  
FOR XML PATH;  
GO  

下列結果是以元素為中心的 XML,其中產生的數據列集中的每個數據行值都會包裝在 元素中。 SELECT因為 子句未指定數據行名稱的任何別名,因此產生的子專案名稱與 子句中SELECT對應的數據行名稱相同。 針對行集中的每一行,會新增 <row> 標記。

<row>

<ProductModelID>122</ProductModelID>

<Name>All-Purpose Bike Stand</Name>

</row>

<row>

<ProductModelID>119</ProductModelID>

<Name>Bike Wash</Name>

</row>

以下結果與含有指定選項的ELEMENTS模式查詢相同。 它會傳回以元素為中心的 XML,其中包含結果集中每個數據列的預設 <row> 元素。

USE AdventureWorks2012;  
GO  
SELECT ProductModelID,  
       Name  
FROM Production.ProductModel  
WHERE ProductModelID=122 OR ProductModelID=119  
FOR XML RAW, ELEMENTS;  

您可以選擇性指定資料欄項目名稱來覆寫預設 <row>。 例如,下列查詢會為數據列集中的每一行傳回 <ProductModel> 元素。

USE AdventureWorks2012;  
GO  
SELECT ProductModelID,  
       Name  
FROM Production.ProductModel  
WHERE ProductModelID=122 or ProductModelID=119  
FOR XML PATH ('ProductModel');  
GO  

產生的 XML 將具有指定的數據列項目名稱。

<ProductModel>

<ProductModelID>122</ProductModelID>

<Name>All-Purpose Bike Stand</Name>

</ProductModel>

<ProductModel>

<ProductModelID>119</ProductModelID>

<Name>Bike Wash</Name>

</ProductModel>

如果您指定長度為零的字串,則不會產生包裝元素。

USE AdventureWorks2012;  
GO  
SELECT ProductModelID,  
       Name  
FROM Production.ProductModel  
WHERE ProductModelID=122 OR ProductModelID=119  
FOR XML PATH ('');  
GO  

以下是結果:

<ProductModelID>122</ProductModelID>

<Name>All-Purpose Bike Stand</Name>

<ProductModelID>119</ProductModelID>

<Name>Bike Wash</Name>

指定類似 XPath 的數據行名稱

在下列查詢中, ProductModelID 指定的數據行名稱以 『@』 開頭,且不包含斜線標記 ('/')。 因此,在產生的 XML 中會建立具有對應數據行值的 元素屬性 <row> 。

USE AdventureWorks2012;  
GO  
SELECT ProductModelID AS "@id",  
       Name  
FROM Production.ProductModel  
WHERE ProductModelID=122 OR ProductModelID=119  
FOR XML PATH ('ProductModelData');  
GO  

以下是結果:

< ProductModelData id="122">

<Name>All-Purpose Bike Stand</Name>

</ ProductModelData >

< ProductModelData id="119">

<Name>Bike Wash</Name>

</ ProductModelData >

FOR XML中指定root選項,以新增一個單一的最上層元素。

SELECT ProductModelID AS "@id",  
       Name  
FROM Production.ProductModel  
WHERE ProductModelID=122 or ProductModelID=119  
FOR XML PATH ('ProductModelData'), root ('Root');  
GO  

若要產生階層,您可以包含類似PATH的語法。 例如,將數據行的數據行名稱 Name 變更為 「SomeChild/ModelName」,而您將取得具有階層的 XML,如下列結果所示:

<Root>

<ProductModelData id="122">

<SomeChild>

<ModelName>All-Purpose Bike Stand</ModelName>

</SomeChild>

</ProductModelData>

<ProductModelData id="119">

<SomeChild>

<ModelName>Bike Wash</ModelName>

</SomeChild>

</ProductModelData>

</Root>

除了產品型號標識碼和名稱,下列查詢會擷取產品型號的製造指示位置。 由於 Instructions 欄位的類型為 xml,因此指定 xml 類型資料的 query() 方法來擷取位置。

SELECT ProductModelID AS "@id",  
       Name,  
       Instructions.query('declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";  
                /MI:root/MI:Location   
              ') AS ManuInstr  
FROM Production.ProductModel  
WHERE ProductModelID = 7  
FOR XML PATH ('ProductModelData'), root ('Root');  
GO  

以下是部份結果。 因為查詢將 ManuInstr 指定為資料行名稱,因此由方法 query() 傳回的 XML 會包裝在 <ManuInstr> 標記中,如下所示:

<Root>

<ProductModelData id="7">

<Name>HL Touring Frame</Name>

<ManuInstr>

<MI:Location xmlns:MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions"

<MI:step>...</MI:step>...

</MI:Location>

...

</ManuInstr>

</ProductModelData>

</Root>

在先前的 FOR XML 查詢中,您可能想要包含 和 <ProductModelData> 元素的<Root>命名空間。 您可以先使用 WITH XMLNAMESPACES 定義命名空間繫結的前置詞,然後在 FOR XML 查詢中使用這些前置詞。 如需詳細資訊,請參閱 使用WITH XMLNAMESPACES 將命名空間新增至查詢

USE AdventureWorks2012;  
GO  
WITH XMLNAMESPACES (  
   'uri1' AS ns1,    
   'uri2' AS ns2,  
   'https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions' as MI)  
SELECT ProductModelID AS "ns1:ProductModelID",  
       Name           AS "ns1:Name",  
       Instructions.query('  
                /MI:root/MI:Location   
              ')   
FROM Production.ProductModel  
WHERE ProductModelID=7  
FOR XML PATH ('ns2:ProductInfo'), root('ns1:root');  
GO  

請注意,<c0 /> 前綴也在 WITH XMLNAMESPACES 中定義。 因此, query() 指定之型別的 xml 方法不會在查詢初構中定義前置詞。 以下是結果:

<ns1:root xmlns:MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions" xmlns="uri2" xmlns:ns2="uri2" xmlns:ns1="uri1">

<ns2:ProductInfo>

<ns1:ProductModelID>7</ns1:ProductModelID>

<ns1:Name>HL Touring Frame</ns1:Name>

<MI:Location xmlns:MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions"

LaborHours="2.5" LotSize="100" MachineHours="3" SetupHours="0.5" LocationID="10" xmlns="">

<MI:step>

Insert <MI:material>aluminum sheet MS-2341</MI:material> into the <MI:tool>T-85A framing tool</MI:tool>.

</MI:step>

...

</MI:Location>

...

</ns2:ProductInfo>

</ns1:root>

使用PATH模式產生值清單

針對每個產品模型,此查詢會建構產品標識碼的值清單。 針對每個產品識別碼,查詢也會建構 <ProductName> 巢狀元素,如下列 XML 片段所示:

<ProductModelData ProductModelID="7" ProductModelName="..."

ProductIDs="product id list in the product model" >

<ProductName>...</ProductName>

<ProductName>...</ProductName>

...

</ProductModelData>

這是產生您要之 XML 的查詢:

USE AdventureWorks2012;  
GO  
SELECT ProductModelID     AS "@ProductModelID",  
       Name               S "@ProductModelName",  
      (SELECT ProductID AS "data()"  
       FROM   Production.Product  
       WHERE  Production.Product.ProductModelID =   
              Production.ProductModel.ProductModelID  
       FOR XML PATH ('')) S "@ProductIDs",  
       (SELECT Name AS "ProductName"  
       FROM   Production.Product  
       WHERE  Production.Product.ProductModelID =   
              Production.ProductModel.ProductModelID  
        FOR XML PATH ('')) as "ProductNames"  
FROM   Production.ProductModel  
WHERE  ProductModelID= 7 or ProductModelID=9  
FOR XML PATH('ProductModelData');  

請注意下列項目是從上一個查詢而來:

  • 第一個巢狀 SELECT 使用 data() 作為欄位名稱,傳回 ProductID 清單。 因為查詢會將空字串指定為 中的 FOR XML PATH數據列專案名稱,因此不會產生任何專案。 而是將值清單指派給 ProductID 屬性。

  • 第二個巢狀 SELECT 檢索產品模型中每個產品的名稱。 它會產生<ProductName>元素,這些元素被包裝在<ProductNames>元素中返回,因為查詢將ProductNames指定為列名稱。

以下是部份結果:

<ProductModelData PId="7"

ProductModelName="HL Touring Frame"

ProductIDs="885 887 ...">

<ProductNames>

<ProductName>HL Touring Frame - Yellow, 60</ProductName>

<ProductName>HL Touring Frame - Yellow, 46</ProductName></ProductNames>

...

</ProductModelData>

<ProductModelData PId="9"

ProductModelName="LL Road Frame"

ProductIDs="722 723 724 ...">

<ProductNames>

<ProductName>LL Road Frame - Black, 58</ProductName>

<ProductName>LL Road Frame - Black, 60</ProductName>

<ProductName>LL Road Frame - Black, 62</ProductName>

...

</ProductNames>

</ProductModelData>

建構產品名稱的子查詢會傳回結果作為已實體化的字串,然後新增至 XML。 如果您加入 type 指示詞, FOR XML PATH (''), type則子查詢會傳回結果做為 xml 類型,而且不會發生任何實體化。

USE AdventureWorks2012;  
GO  
SELECT ProductModelID AS "@ProductModelID",  
      Name AS "@ProductModelName",  
      (SELECT ProductID AS "data()"  
       FROM   Production.Product  
       WHERE  Production.Product.ProductModelID =   
              Production.ProductModel.ProductModelID  
       FOR XML PATH ('')  
       ) AS "@ProductIDs",  
       (  
       SELECT Name AS "ProductName"  
       FROM   Production.Product  
       WHERE  Production.Product.ProductModelID =   
              Production.ProductModel.ProductModelID  
       FOR XML PATH (''), type  
       ) AS "ProductNames"  
  
FROM Production.ProductModel  
WHERE ProductModelID= 7 OR ProductModelID=9  
FOR XML PATH('ProductModelData');  

在產生的 XML 中新增命名空間

使用WITH XMLNAMESPACES 新增命名空間中所述,您可以使用WITH XMLNAMESPACES在PATH模式查詢中包含命名空間。 例如,SELECT 子句中指定的名稱包含命名空間前置詞。 下列 PATH 模式查詢會建構具有命名空間的 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新增至 <English> 元素的屬性定義於預先定義的 xml 命名空間中。

以下是結果:

<Translation>

<English xml:lang="en">food</English>

<German xml:lang="ger">Essen</German>

</Translation>

下列查詢類似於範例 C,不同之處在於它用來 WITH XMLNAMESPACES 在 XML 結果中包含命名空間。 如需詳細資訊,請參閱 使用WITH XMLNAMESPACES 將命名空間新增至查詢

USE AdventureWorks2012;  
GO  
WITH XMLNAMESPACES ('uri1' AS ns1,  DEFAULT 'uri2')  
SELECT ProductModelID AS "@ns1:ProductModelID",  
      Name AS "@ns1:ProductModelName",  
      (SELECT ProductID AS "data()"  
       FROM   Production.Product  
       WHERE  Production.Product.ProductModelID =   
              Production.ProductModel.ProductModelID  
       FOR XML PATH ('')  
       ) AS "@ns1:ProductIDs",  
       (  
       SELECT ProductID AS "@ns1:ProductID",   
              Name AS "@ns1:ProductName"  
       FROM   Production.Product  
       WHERE  Production.Product.ProductModelID =   
              Production.ProductModel.ProductModelID  
       FOR XML PATH , type   
       ) AS "ns1:ProductNames"  
FROM Production.ProductModel  
WHERE ProductModelID= 7 OR ProductModelID=9  
FOR XML PATH('ProductModelData'), root('root');  

以下是結果:

<root xmlns="uri2" xmlns:ns1="uri1">

<ProductModelData ns1:ProductModelID="7" ns1:ProductModelName="HL Touring Frame" ns1:ProductIDs="885 887 888 889 890 891 892 893">

<ns1:ProductNames>

<row xmlns="uri2" xmlns:ns1="uri1" ns1:ProductID="885" ns1:ProductName="HL Touring Frame - Yellow, 60" />

<row xmlns="uri2" xmlns:ns1="uri1" ns1:ProductID="887" ns1:ProductName="HL Touring Frame - Yellow, 46" />

...

</ns1:ProductNames>

</ProductModelData>

<ProductModelData ns1:ProductModelID="9" ns1:ProductModelName="LL Road Frame" ns1:ProductIDs="722 723 724 725 726 727 728 729 730 736 737 738">

<ns1:ProductNames>

<row xmlns="uri2" xmlns:ns1="uri1" ns1:ProductID="722" ns1:ProductName="LL Road Frame - Black, 58" />

...

</ns1:ProductNames>

</ProductModelData>

</root>

另請參閱

使用 PATH 模式搭配 FOR XML