具有名称的列

以下是在特定条件下将具有名称的行集列按区分大小写的方式映射到生成的 XML:

  • 列名以 at 符号 (@) 开头。

  • 列名不以符号“@”开头。

  • 列名称不以“@”符号开头,并且包含斜杠(/)。

  • 多个列共享相同的前缀。

  • 一列具有不同的名称。

列名称以 At 符号开头(@)

如果列名以符号 (@) 开头,并且不包含斜杠标记 (/),则会创建具有相应列值的元素的属性 <row> 。 例如,以下查询返回两列(@PmId,名称)行集。 在生成的 XML 中, PmId 属性将添加到相应的 <row> 元素,并为其分配 ProductModelID 的值。

  
SELECT ProductModelID as "@PmId",  
       Name  
FROM Production.ProductModel  
WHERE ProductModelID=7  
FOR XML PATH   
go  
  

结果如下:

<row PmId="7">  
  <Name>HL Touring Frame</Name>  
</row>  

请注意,属性必须位于同一级别的任何其他节点类型(如元素节点和文本节点)之前。 以下查询将返回错误:

SELECT Name,  
       ProductModelID as "@PmId"  
FROM Production.ProductModel  
WHERE ProductModelID=7  
FOR XML PATH   
go  

列名不以 At 符号开头(@)

如果列名称不以符号(@)开头、不是 XPath 节点测试之一且不包含斜杠符号(/),则默认会创建一个作为行元素子元素的 XML 元素,如 <row> 。

以下查询指定了列名称和结果。 因此,将 <result> 元素子元素添加到 <row> 元素。

SELECT 2+2 as result  
for xml PATH  

结果如下:

<row>  
  <result>4</result>  
</row>  

以下查询为针对 xml 类型的指令列指定的 XQuery 返回的 XML 指定了列名 ManuWorkCenterInformation。 因此,将 <ManuWorkCenterInformation> 元素添加为元素的 <row> 子元素。

SELECT   
       ProductModelID,  
       Name,  
       Instructions.query('declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";  
                /MI:root/MI:Location   
              ') as ManuWorkCenterInformation  
FROM Production.ProductModel  
WHERE ProductModelID=7  
FOR XML PATH   
go  

结果如下:

<row>  
  <ProductModelID>7</ProductModelID>  
  <Name>HL Touring Frame</Name>  
  <ManuWorkCenterInformation>  
    <MI:Location ...LocationID="10" ...></MI:Location>  
    <MI:Location ...LocationID="20" ...></MI:Location>  
     ...  
  </ManuWorkCenterInformation>  
</row>  

列名称不以 At 符号开头 (@) 并包含斜杠标记 (/)

如果列名不以符号 (@) 开头,但包含斜杠标记 (/),则列名称指示 XML 层次结构。 例如,如果列名称为“Name1/Name2/Name3.../Namen ”,则每个 Namei 表示嵌套在当前行元素(for i=1)中的元素名称,或者位于名称为i-1 的元素下。 如果 Namen 以“@”开头,则它映射到 Namen-1 元素的属性。

例如,以下查询返回一个员工 ID 和名称,这些 ID 和名称表示为包含 First、Middle 和 Last name 的复杂元素 EmpName。

SELECT EmployeeID "@EmpID",   
       FirstName  "EmpName/First",   
       MiddleName "EmpName/Middle",   
       LastName   "EmpName/Last"  
FROM   HumanResources.Employee E, Person.Contact C  
WHERE  E.EmployeeID = C.ContactID  
AND    E.EmployeeID=1  
FOR XML PATH  

列名称用作在 PATH 模式下构造 XML 的路径。 包含员工 ID 值的列名以“@”开头。因此,将属性 EmpID 添加到 <row> 元素。 所有其他列在指示层次结构的列名称中包含斜杠标记('/')。 生成的 XML 将在<row>元素下具有<EmpName>子级,并且<EmpName>子级将具有<First>、<Middle>和<Last>元素子级。

<row EmpID="1">  
  <EmpName>  
    <First>Gustavo</First>  
    <Last>Achong</Last>  
  </EmpName>  
</row>  

员工中间名称为 null,默认情况下,null 值映射到缺少元素或属性。 如果希望为 NULL 值生成元素,可以使用 XSINIL 指定 ELEMENTS 指令,如此查询中所示。

SELECT EmployeeID "@EmpID",   
       FirstName  "EmpName/First",   
       MiddleName "EmpName/Middle",   
       LastName   "EmpName/Last"  
FROM   HumanResources.Employee E, Person.Contact C  
WHERE  E.EmployeeID = C.ContactID  
AND    E.EmployeeID=1  
FOR XML PATH, ELEMENTS XSINIL  

结果如下:

<row xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
      EmpID="1">  
  <EmpName>  
    <First>Gustavo</First>  
    <Middle xsi:nil="true" />  
    <Last>Achong</Last>  
  </EmpName>  
</row>  

默认情况下,PATH 模式生成以元素为中心的 XML。 因此,在 PATH 模式查询中指定 ELEMENTS 指令不起作用。 但是,如前面的示例所示,ELEMENTS 指令对于 XSINIL 非常有用,用于为 null 值生成元素。

除了 ID 和名称,以下查询还检索员工地址。 根据地址列的列名称路径,一个<Address>子元素将添加到<row>元素中,并且地址详细信息将作为<Address>元素的子元素添加。

SELECT EmployeeID   "@EmpID",   
       FirstName    "EmpName/First",   
       MiddleName   "EmpName/Middle",   
       LastName     "EmpName/Last",  
       AddressLine1 "Address/AddrLine1",  
       AddressLine2 "Address/AddrLIne2",  
       City         "Address/City"  
FROM   HumanResources.Employee E, Person.Contact C, Person.Address A  
WHERE  E.EmployeeID = C.ContactID  
AND    E.AddressID = A.AddressID  
AND    E.EmployeeID=1  
FOR XML PATH  

结果如下:

<row EmpID="1">  
  <EmpName>  
    <First>Gustavo</First>  
    <Last>Achong</Last>  
  </EmpName>  
  <Address>  
    <AddrLine1>7726 Driftwood Drive</AddrLine1>  
    <City>Monroe</City>  
  </Address>  
</row>  

多个列共享相同的路径前缀

如果多个后续列共享相同的路径前缀,则它们按同一名称组合在一起。 如果使用不同的命名空间前缀,即使它们绑定到同一命名空间,路径也会被视为不同。 在前面的查询中,FirstName、MiddleName 和 LastName 列共享相同的 EmpName 前缀。因此,它们被添加为元素的 <EmpName> 子级。 在上一个示例中创建 <Address> 元素时,也会出现这种情况。

一列具有不同的名称

如果两者之间出现名称不同的列,它将中断分组,如以下修改后的查询所示。 该查询通过在 FirstName 和 MiddleName 列之间添加地址列来中断在上一个查询中指定的 FirstName、MiddleName 和 LastName 的分组。

SELECT EmployeeID "@EmpID",   
       FirstName "EmpName/First",   
       AddressLine1 "Address/AddrLine1",  
       AddressLine2 "Address/AddrLIne2",  
       City "Address/City",  
       MiddleName "EmpName/Middle",   
       LastName "EmpName/Last"  
FROM   HumanResources.EmployeeAddress E, Person.Contact C, Person.Address A  
WHERE  E.EmployeeID = C.ContactID  
AND    E.AddressID = A.AddressID  
AND    E.EmployeeID=1  
FOR XML PATH  

因此,查询将创建两个 <EmpName> 元素。 第一个<EmpName>元素具有<FirstName>元素子元素,第二个<EmpName>元素具有<MiddleName>和<LastName>元素子元素。

结果如下:

<row EmpID="1">  
  <EmpName>  
    <First>Gustavo</First>  
  </EmpName>  
  <Address>  
    <AddrLine1>7726 Driftwood Drive</AddrLine1>  
    <City>Monroe</City>  
  </Address>  
  <EmpName>  
    <Last>Achong</Last>  
  </EmpName>  
</row>  

另请参阅

将 PATH 模式与 FOR XML 配合使用