在 OPENXML 中指定中繼屬性
適用於:SQL Server
Azure SQL 資料庫
Azure SQL 受控執行個體
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 節點的全文件識別碼 (由系統產生)。 只要文件未經過重新剖析,此識別碼就會參照相同的 XML 節點。 XML 識別碼為 0 ,表示元素為根元素。 其父系 XML 識別碼為 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 識別碼 (由系統產生)。parent
資料行會對應到@mp:parentid
,表示該資料行包含項目父元素的 XML 識別碼。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;
查詢將傳回含有 root 名稱的根元素,以及根元素所包含的資料。
C. 指定 xmltext 中繼屬性用來在資料行中擷取未耗用的資料
此範例使用 OPENXML 來建立範例 XML 文件的資料列集檢視。 範例顯示如何將 xmltext
中繼屬性對應到 OPENXML 的資料列集欄位,以檢索尚未使用的 XML 資料。
將 comment
資料行對應到 @mp:xmltext
中繼屬性,從而識別其為溢位資料行。
flags 參數是設為 9
(XML_ATTRIBUTE 和 XML_NOCOPY)。 這表示 attribute-centric
映射,並指出只有未使用的資料應該複製到溢位資料行。
然後 SELECT 陳述式將傳回由 OPENXML 所提供的資料列集。
在此範例中,@mp:parentlocalname
中繼屬性是針對 OPENXML 所產生資料列集的 ParentLocalName
資料行來設定。 因此,此資料行含有父元素的本機名稱。
資料列集內還指定了另外兩個資料行: parent
及 comment
。
parent
資料行會對應到 @mp:parentid
,表示該資料行包含元素之父元素的 XML 識別碼。 註解欄藉由對應到 @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"/>