共用方式為


範例:使用 PATH 模式

以下範例說明使用 PATH 模式從 SELECT 查詢產生 XML。 這些查詢中有許多是針對自行車製造指示的 XML 文件所指定,這些文件是儲存在 ProductModel 資料表的 Instructions 資料行中。

指定簡單 PATH 模式查詢

此查詢指定 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 選項之 RAW 模式查詢的結果相同。 它會為結果集中的每個資料列傳回元素中心的 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 查詢中,您可以加入 <Root> 與 <ProductModelData> 元素的命名空間。 完成此動作的方式是先使用 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

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

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

<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 會擷取產品型號中的產品名稱。 它會產生包裝在 <ProductNames> 元素中的 <ProductName> 元素,因為查詢會將 ProductNames 指定為資料行名稱。

其部分結果如下:

<ProductModelData PId="7"

ProductModelName="HL Touring Frame"

ProductIDs="885 887 ...">

<ProductNames>

&lt;ProductName&gt;HL Touring Frame - Yellow, 60&lt;/ProductName&gt;

&lt;ProductName&gt;HL Touring Frame - Yellow, 46&lt;/ProductName&gt;</ProductNames>

...

</ProductModelData>

<ProductModelData PId="9"

ProductModelName="LL Road Frame"

ProductIDs="722 723 724 ...">

<ProductNames>

&lt;ProductName&gt;LL Road Frame - Black, 58&lt;/ProductName&gt;

&lt;ProductName&gt;LL Road Frame - Black, 60&lt;/ProductName&gt;

&lt;ProductName&gt;LL Road Frame - Black, 62&lt;/ProductName&gt;

...

</ProductNames>

</ProductModelData>

建構產品名稱的子查詢會以實體化字串傳回結果,然後加入 XML。 如果您加入類型指示詞 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

加入至 <English> 元素的 @xml:lang 屬性是在預先定義的 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>

請參閱

概念

搭配 FOR XML 使用 PATH 模式