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 識別符。 如果元素位於同層級清單的前面, @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。
父數據行會對應至 @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 數據。
批注欄位透過映射至 @mp:xmltext 中繼屬性,被識別為溢位欄位。 flags 參數設定為 9 (XML_ATTRIBUTE 和 XML_NOCOPY)。 這表示 以屬性為中心的 對應,並指出只應該將未處理的數據複製到溢位數據行。
然後 SELECT 陳述式將傳回由 OPENXML 所提供的資料列集。
在此範例中, @mp:parentlocalname 中繼屬性是針對 OPENXML 所產生的數據列集中的數據行 ParentLocalName 設定。 因此,此資料行含有父元素的本機名稱。
在該行集中指定了兩個額外的列,parent 和 comment。 父數據行會對應至 @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"/>