示例:指定 XMLTEXT 指令

此示例演示了如何在使用 EXPLICIT 模式的语句中使用SELECT指令解决XMLTEXT溢出列中的数据。

请考虑该 Person 表。 此表包含一个 Overflow 列,用于存储 XML 文档的未消费部分。

USE tempdb;  
GO  
CREATE TABLE Person(PersonID varchar(5), PersonName varchar(20), Overflow nvarchar(200));  
GO  
INSERT INTO Person VALUES   
    ('P1','Joe',N'<SomeTag attr1="data">content</SomeTag>')  
   ,('P2','Joe',N'<SomeTag attr2="data"/>')  
   ,('P3','Joe',N'<SomeTag attr3="data" PersonID="P">content</SomeTag>');  

此查询从 Person 表中检索列。 Overflow列中未指定AttributeName,但将指令设置为XMLTEXT,这是提供通用表列名的一部分。

SELECT 1 as Tag, NULL as parent,  
       PersonID as [Parent!1!PersonID],  
       PersonName as [Parent!1!PersonName],  
       Overflow as [Parent!1!!XMLTEST] -- No AttributeName; XMLTEXT directive  
FROM Person  
FOR XML EXPLICIT;  

在生成的 XML 文档中:

  • 由于未为Overflow列指定 AttributeName,并且xmltext指定了指令,因此元素<overflow>中的属性将追加到封闭<Parent>元素的属性列表中。

  • PersonID在<xmltext>元素中的属性与在同一元素级别检索的PersonID属性发生冲突,因此即使PersonID为 NULL,<xmltext>元素中的属性仍会被忽略。 通常,属性会替代溢出中同名的属性。

结果如下:

<Parent PersonID="P1" PersonName="Joe" attr1="data">content</Parent>

<Parent PersonID="P2" PersonName="Joe" attr2="data"></Parent>

<Parent PersonID="P3" PersonName="Joe" attr3="data">content</Parent>

如果溢出数据具有子元素,并且指定了相同的查询,则 Overflow 列中的子元素将添加为封闭 <Parent> 元素的子元素。

例如,更改表中的数据 Person ,使 Overflow 列现在具有子元素。

USE tempdb;  
GO  
TRUNCATE TABLE Person;  
GO  
INSERT INTO Person VALUES   
    ('P1','Joe',N'<SomeTag attr1="data">content</SomeTag>')  
   ,('P2','Joe',N'<SomeTag attr2="data"/>')  
    ,('P3','Joe',N'<SomeTag attr3="data" PersonID="P"><name>PersonName</name></SomeTag>');  

如果执行相同的查询,则 <xmltext> 元素中的子元素将添加为封闭 <Parent> 元素的子元素:

SELECT 1 as Tag, NULL as parent,  
       PersonID as [Parent!1!PersonID],  
       PersonName as [Parent!1!PersonName],  
       Overflow as [Parent!1!!XMLTEXT] -- no AttributeName, XMLTEXT directive  
FROM Person  
FOR XML EXPLICIT;  

结果如下:

<Parent PersonID="P1" PersonName="Joe" attr1="data">content</Parent>

<Parent PersonID="P2" PersonName="Joe" attr2="data"></Parent>

<Parent PersonID="P3" PersonName="Joe" attr3="data">

<name>PersonName</name>

</Parent>

如果通过xmltext指令指定AttributeName,则<overflow>元素的属性将作为封闭<Parent>元素的子元素的属性添加。 为 AttributeName 指定的名称将成为子元素的名称。

在此查询中,AttributeNamexmltext指令一起被指定:

SELECT 1 as Tag, NULL as parent,  
       PersonID as [Parent!1!PersonID],  
       PersonName as [Parent!1!PersonName],  
       Overflow as [Parent!1!overflow!XMLTEXT] -- Overflow is AttributeName  
                      -- XMLTEXT is a directive  
FROM Person  
FOR XML EXPLICIT  

结果如下:

<Parent PersonID="P1" PersonName="Joe">

<overflow attr1="data">content</overflow>

</Parent>

<Parent PersonID="P2" PersonName="Joe">

<overflow attr2="data" />

</Parent>

<Parent PersonID="P3" PersonName="Joe">

<overflow attr3="data" PersonID="P">

<name>PersonName</name>

</overflow>

</Parent>

在此查询元素中,为PersonName属性指定指令。 这会导致 PersonName 添加为封闭 <Parent> 元素的子元素。 这些属性 <xmltext> 仍追加到封闭 <Parent> 元素中。 < overflow > 元素的内容(子元素)被添加到封闭 <Parent> 元素的其他子元素的前面。

SELECT 1      AS Tag, NULL as parent,  
       PersonID   AS [Parent!1!PersonID],  
       PersonName AS [Parent!1!PersonName!element], -- element directive  
       Overflow   AS [Parent!1!!XMLTEXT]  
FROM Person  
FOR XML EXPLICIT;  

结果如下:

<Parent PersonID="P1" attr1="data">content<PersonName>Joe</PersonName>

</Parent>

<Parent PersonID="P2" attr2="data">

<PersonName>Joe</PersonName>

</Parent>

<Parent PersonID="P3" attr3="data">

<name>PersonName</name>

<PersonName>Joe</PersonName>

</Parent>

XMLTEXT如果列数据包含根元素的属性,则这些属性不会显示在 XML 数据架构中,并且 MSXML 分析器不会验证生成的 XML 文档片段。 例如:

SELECT 1 AS Tag,  
       0 ASParent,  
       N'<overflow a="1"/>' AS 'overflow!1!!xmltext'  
FOR XML EXPLICIT, xmldata;  

结果如下: 请注意,在返回的架构中,架构中缺少溢出属性 a

<Schema name="Schema2"

xmlns="urn:schemas-microsoft-com:xml-data"

xmlns:dt="urn:schemas-microsoft-com:datatypes">

<ElementType name="overflow" content="mixed" model="open">

</ElementType>

</Schema>

<overflow xmlns="x-schema:#Schema2" a="1">

</overflow>

另请参阅

将 EXPLICIT 模式与 FOR XML 配合使用