在 XML 文档中,元属性是描述 XML 项目的属性。这些项目可以是元素、属性或任何其他 DOM 节点。 XML 文档文本中不存在这些属性。 但是,OPENXML 为所有 XML 项提供这些元属性。 通过这些元属性,可以提取 XML 节点的本地定位和命名空间信息等信息。 此信息提供的详细程度超出了通过文字形式所能看到的。
可以使用 ColPattern 参数将这些元属性映射到 OPENXML 语句中的行集列。 这些列将包含要映射到的元属性的值。 有关 OPENXML 语法的详细信息,请参阅 OPENXML (Transact-SQL)。
若要访问元属性,将提供特定于 SQL Server 的命名空间。 此命名空间 urn:schemas-microsoft-com:xml-metaprop 允许用户访问元属性。 如果 OPENXML 查询的结果以边缘表格式返回,则边缘表包含每个元属性的一列,但 xmltext 元属性除外。
某些元属性用于处理目的。 例如, xmltext 元属性用于溢出处理。 溢出处理指的是文档中未消费和未处理的数据。 行集中由 OPENXML 生成的列之一可以标识为溢出列。 为此,请使用 ColPattern 参数将其映射到 xmltext 元属性。 然后,该列接收溢出数据。 flags 参数确定列是包含所有内容还是仅包含未使用的数据。
下表列出了每个分析的 XML 元素拥有的元属性。 可以使用命名空间 urn:schemas-microsoft-com:xml-metaprop 访问这些元属性。 忽略用户使用这些元属性直接在 XML 文档中设置的任何值。
注释
不能在任何 XPath 导航中引用这些元属性。
| Metaproperty 属性 | DESCRIPTION |
|---|---|
| @mp:id | 提供系统生成的用于整个文档范围的 DOM 节点标识符。 只要文档未重新解析,此 ID 将引用相同的 XML 节点。 XML ID 为 0 表示元素是根元素。 其父 XML ID 为 NULL。 |
| @mp:localname | 存储节点名称的本地部分。 它与前缀和命名空间 URI 一起使用来命名元素或属性节点。 |
| @mp:namespaceuri | 提供当前元素的命名空间 URI。 如果此属性的值为 NULL,则不存在命名空间 |
| @mp:prefix | 存储当前元素名称的命名空间前缀。 如果没有前缀(NULL),并且给定了 URI,则表示指定的命名空间是默认命名空间。 如果未提供 URI,则不会附加任何命名空间。 |
| @mp:prev | 存储相对于节点的上一个同级。 这将提供有关文档中元素排序的信息。 @mp:prev 包含同一父元素下与它同级的上一个元素的 XML ID。 如果元素位于同级列表的前面, 则 @mp:prev 为 NULL。 |
| @mp:xmltext | 用于处理目的。 它是元素及其属性的文本序列化,也是 OPENXML 溢出处理中使用的子元素。 |
此表显示提供的其他父属性,并允许检索有关层次结构的信息。
| 父元属性 | DESCRIPTION |
|---|---|
| @mp:parentid | 对应于 ../@mp:id |
| @mp:parentlocalname | 对应于 ../@mp:localname |
| @mp:parentnamespacerui | 对应于 ../@mp:namespaceuri |
| @mp:parentprefix | 对应于 ../@mp:prefix |
例子
以下示例演示了 OPENXML 如何用于创建不同的行集视图。
答: 将 OPENXML 行集列映射到元属性
此示例使用 OPENXML 创建示例 XML 文档的行集视图。 具体而言,它演示了如何使用 ColPattern 参数将各种元属性映射到 OPENXML 语句中的行集列。
OPENXML 语句说明了以下内容:
ID 列映射到 @mp:id 元属性,并指示该列包含元素的系统生成的唯一 XML ID。
父列映射到 @mp:parentid,并指示该列包含元素父级的 XML ID。
parentLocalName 列映射到 @mp:parentlocalname,并指示该列包含父级的本地名称。
然后,SELECT 语句返回 OPENXML 提供的行集:
DECLARE @idoc int
DECLARE @doc nvarchar(1000)
-- Sample XML document
SET @doc = N'<root>
<Customer cid= "C1" name="Janine" city="Issaquah">
<Order oid="O1" date="1/20/1996" amount="3.5" />
<Order oid="O2" date="4/30/1997" amount="13.4">Customer was very satisfied</Order>
</Customer>
<Customer cid="C2" name="Ursula" city="Oelde" >
<Order oid="O3" date="7/14/1999" amount="100" note="Wrap it blue white red">
<Urgency>Important</Urgency>
</Order>
<Order oid="O4" date="1/20/1996" amount="10000"/>
</Customer>
</root>'
-- Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
-- Execute a SELECT statement using OPENXML rowset provider.
SELECT *
FROM OPENXML (@idoc, '/root/Customer/Order', 9)
WITH (id int '@mp:id',
oid char(5),
date datetime,
amount real,
parentIDNo int '@mp:parentid',
parentLocalName varchar(40) '@mp:parentlocalname')
EXEC sp_xml_removedocument @idoc
结果如下:
id oid date amount parentIDNo parentLocalName
--- ------- ---------------------- ---------- ------------ ---------------
6 O1 1996-01-20 00:00:00.000 3.5 2 Customer
10 O2 1997-04-30 00:00:00.000 13.4 2 Customer
19 O3 1999-07-14 00:00:00.000 100.0 15 Customer
25 O4 1996-01-20 00:00:00.000 10000.0 15 Customer
B. 检索整个 XML 文档
在此示例中,OPENXML 用于创建示例 XML 文档的一列行集视图。 此列 Col1 映射到 xmltext 元属性,并成为溢出列。 因此,该列接收未使用的数据。 在本例中,它是整个文档。
然后,SELECT 语句返回完整的行集。
DECLARE @idoc int
DECLARE @doc nvarchar(1000)
SET @doc = N'<?xml version="1.0"?>
<root>
<Customer cid= "C1" name="Janine" city="Issaquah">
<Order oid="O1" date="1/20/1996" amount="3.5" />
<Order oid="O2" date="4/30/1997" amount="13.4">Customer was very
satisfied</Order>
</Customer>
<Customer cid="C2" name="Ursula" city="Oelde" >
<Order oid="O3" date="7/14/1999" amount="100" note="Wrap it blue
white red">
<MyTag>Testing to see if all the subelements are returned</MyTag>
<Urgency>Important</Urgency>
</Order>
<Order oid="O4" date="1/20/1996" amount="10000"/>
</Customer>
</root>'
-- Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
-- Execute a SELECT statement using OPENXML rowset provider.
SELECT *
FROM OPENXML (@idoc, '/')
WITH (Col1 ntext '@mp:xmltext')
若要检索没有 XML 声明的整个文档,可以指定查询,如下所示:
SELECT *
FROM OPENXML (@idoc, '/root')
WITH (Col1 ntext '@mp:xmltext')
EXEC sp_xml_removedocument @idoc
查询返回具有名称根的根元素以及根元素包含的数据
C. 指定 xmltext 元属性以检索列中未处理的数据
此示例使用 OPENXML 创建示例 XML 文档的行集视图。 该示例演示如何通过将 xmltext 元属性映射到 OPENXML 中的行集列来检索未处理 XML 数据。
注释列通过将其映射到 @mp:xmltext 元属性来标识为溢出列。 标志参数设置为 9(XML_ATTRIBUTE和XML_NOCOPY)。 这表示 以属性为中心的 映射,并指示只应将未使用的数据复制到溢出列。
然后,SELECT 语句返回 OPENXML 提供的行集。
在此示例中,为 OPENXML 生成的行集中的列 ParentLocalName 设置 @mp:parentlocalname 元属性。 因此,此列包含父元素的本地名称。
在行集中指定了另外两列:parent 和 comment。 父列映射到 @mp:parentid,并指示该列包含元素父元素的 XML ID。 注释列通过将其映射到 @mp:xmltext 元属性来标识为溢出列。
DECLARE @idoc int
DECLARE @doc nvarchar(1000)
-- sample XML document
SET @doc = N'<root>
<Customer cid= "C1" name="Janine" city="Issaquah">
<Order oid="O1" date="1/20/1996" amount="3.5" />
<Order oid="O2" date="4/30/1997" amount="13.4">Customer was very satisfied</Order>
</Customer>
<Customer cid="C2" name="Ursula" city="Oelde" >
<Order oid="O3" date="7/14/1999" amount="100" note="Wrap it blue white red">
<Urgency>Important</Urgency>
</Order>
<Order oid="O4" date="1/20/1996" amount="10000"/>
</Customer>
</root>
'
-- Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
-- Execute a SELECT statement using OPENXML rowset provider.
SELECT *
FROM OPENXML (@idoc, '/root/Customer/Order', 9)
WITH (oid char(5),
date datetime,
comment ntext '@mp:xmltext')
EXEC sp_xml_removedocument @idoc
结果如下: 由于 oid 列和日期列已经被使用,所以它们不会显示在溢出列中。
oid date comment
----- --------------------------- ----------------------------------------
O1 1996-01-20 00:00:00.000 <Order amount="3.5"/>
O2 1997-04-30 00:00:00.000 <Order amount="13.4">Customer was very
satisfied</Order>
O3 1999-07-14 00:00:00.000 <Order amount="100" note="Wrap it blue
white red"><Urgency>
Important</Urgency></Order>
O4 1996-01-20 00:00:00.000 <Order amount="10000"/>