在 OPENXML 中指定元属性
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 导航中引用这些元属性。 |
元属性特性 | 说明 |
---|---|
@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 溢出处理中所使用的子元素的文本序列化。 |
下表显示了使您得以检索关于层次结构的信息的其他父属性。
父元属性特性 | 说明 |
---|---|
@mp:parentid |
与 ../@mp:id 相对应 |
@mp:parentlocalname |
与 ../@mp:localname 相对应 |
@mp:parentnamespacerui |
与 ../@mp:namespaceuri 相对应 |
@mp:parentprefix |
与 ../@mp:prefix 相对应 |
示例
下列示例说明了如何使用 OPENXML 来创建不同的行集视图。
A. 将 OPENXML 行集列映射到元属性
此示例使用 OPENXML 创建该示例 XML 文档的行集视图。它专门显示了如何使用 ColPattern 参数将各种元属性特性映射到 OPENXML 语句中的行集列。
OPENXML 语句说明了以下信息:
- id 列将映射到 @mp:id 元属性特性,表明该列包含该元素由系统生成的唯一 XML ID。
- parent 列将映射到 @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 数据。
comment 列将映射到 @mp:xmltext 元属性,从而被标识为溢出列。flags 参数将设置为 9(XML_ATTRIBUTE 和 XML_NOCOPY)。这指明了 attribute-centric 映射,并指明只有未用完的数据才应当被复制到溢出列中。
然后,SELECT 语句返回由 OPENXML 生成的行集。
在本例中,为 OPENXML 所生成行集中的 ParentLocalName 列设置了 @mp:parentlocalname 元属性。因此,此列包含父元素的本地名。
在行集中另外还指定了两列,parent 和 comment。parent 列将映射到 @mp:parentid,表明该列包含该元素的父元素的 XML ID。comment 列将映射到 @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 列和 date 列已经用完,因此它们不会出现在溢出列中。
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"/>