下列範例說明如何從 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>