sp_xml_preparedocument _使用 處理XML文檔

 

 

有時會在存儲過程當中處理一些XML格式的數據,因此會用到sp_xml_preparedocument,他能夠將XML數據進行讀取,而後使用 MSXML 分析器 (Msxmlsql.dll) 對其進行分析。咱們就能夠很容易的在存儲過程當中獲得XML中咱們想要的數據。下面的代碼就是使用sp_xml_preparedocument讀取XML:sql

DECLARE @hdoc int
DECLARE @doc varchar(1000)
SET @doc ='
<ROOT>
<Customer CustomerID="VINET" ContactName="Paul Henriot">
   <Order CustomerID="VINET" EmployeeID="5" OrderDate="1996-07-04T00:00:00">
      <OrderDetail OrderID="10248" ProductID="11" Quantity="12"/>
      <OrderDetail OrderID="10248" ProductID="42" Quantity="10"/>
   </Order>
</Customer>
<Customer CustomerID="LILAS" ContactName="Carlos Gonzlez">
   <Order CustomerID="LILAS" EmployeeID="3" OrderDate="1996-08-16T00:00:00">
      <OrderDetail OrderID="10283" ProductID="72" Quantity="3"/>
   </Order>
</Customer>
</ROOT>'

EXEC sp_xml_preparedocument @hdoc OUTPUT, @doc

上面只是讀取了XML,要想獲取XML數據還須要使用OPENXML,代碼以下:架構

SELECT *
FROM openxml(@hdoc,'/ROOT/Customer',1)
WITH (CustomerID VARCHAR(40),ContactName VARCHAR(40)) 

OPENXML有三個參數:post

  • 第一個是sp_xml_preparedocument讀取是的OUTPUT參數,在本示例中就是@hdoc;
  • 第二個是一個XPath表達式,用來獲取指定位置的數據;
  • 第三個是一個可選項,用來表示獲取的方式,有0,1,2,8四種取值,詳細解釋請看

FROM後面的WITH也是可選的,用來指定獲取哪些數據字段,上面代碼中只取了CustomerID和ContactName。上面的查詢結果以下: CustomerID                               ContactName ---------------------------------------- ---------------------------------------- VINET   Paul Henriot LILAS                                    Carlos Gonzlez 若是不指定WITH子句,查詢出來的是一個默認的表結構,以下:spa

表格列的解釋說明:code

列名 數據類型 說明
id bigint 文檔節點的惟一 ID。 根元素的 ID 值爲 0。保留負 ID 值。
parentid bigint 標識節點的父節點。此 ID 標識的父節點不必定是父元素。具體狀況取決於此 ID 所標識節點的子節點的節點類型。例如,若是節點爲文本節點,則其父節點多是一個屬性節點。 若是節點位於 XML 文檔的頂層,則其 ParentID 爲 NULL。
節點類型 int 標識節點類型,是對應於 XML 對象模型 (DOM) 節點類型編號的一個整數。 下列值是能夠顯示在此列中以指明節點類型的值: 1 = 元素節點 2 = 屬性節點 3 = 文本節點 4 = CDATA 部分節點 5 = 實體引用節點 6 = 實體節點 7 = 處理指令節點 8 = 註釋節點 9 = 文檔節點 10 = 文檔類型節點 11 = 文檔片斷節點 12 = 表示法節點 有關詳細信息,請參閱 Microsoft XML (MSXML) SDK 中的「節點類型屬性」主題。
localname nvarchar(max) 提供元素或屬性的本地名稱。若是 DOM 對象沒有名稱,則爲 NULL。
prefix nvarchar(max) 節點名稱的命名空間前綴。
namespaceuri nvarchar(max) 節點的命名空間 URI。若是值是 NULL,則命名空間不存在。
datatype nvarchar(max) 元素或屬性行的實際數據類型,不然是 NULL。數據類型是從內聯 DTD 中或從內聯架構中推斷得出。
prev bigint 前一個同級元素的 XML ID。若是前面沒有同級元素,則爲 NULL。
text ntext 包含文本形式的屬性值或元素內容。若是邊緣表項不須要值則爲 NULL。

在WITH子句中,咱們還能夠經過設置來獲取父級元素的屬性值:xml

DECLARE @hdoc int
DECLARE @doc varchar(1000)
SET @doc ='
<ROOT>
<Customer CustomerID="VINET" ContactName="Paul Henriot">
   <Order OrderID="10248" CustomerID="VINET" EmployeeID="5"
           OrderDate="1996-07-04T00:00:00">
      <OrderDetail ProductID="11" Quantity="12"/>
      <OrderDetail ProductID="42" Quantity="10"/>
   </Order>
</Customer>
<Customer CustomerID="LILAS" ContactName="Carlos Gonzlez">
   <Order OrderID="10283" CustomerID="LILAS" EmployeeID="3"
           OrderDate="1996-08-16T00:00:00">
      <OrderDetail ProductID="72" Quantity="3"/>
   </Order>
</Customer>
</ROOT>'

EXEC sp_xml_preparedocument @hdoc OUTPUT, @doc
SELECT *
FROM   OPENXML (@hdoc, '/ROOT/Customer/Order/OrderDetail',2)
         WITH (OrderID       int         '../@OrderID',
               CustomerID  varchar(10) '../@CustomerID',
               OrderDate   datetime    '../@OrderDate',
               ProdID      int         '@ProductID',
               Qty         int         '@Quantity')

查詢的結果爲: OrderID     CustomerID OrderDate               ProdID      Qty ----------- ---------- ----------------------- ----------- ----------- 10248       VINET      1996-07-04 00:00:00.000 11          12 10248       VINET      1996-07-04 00:00:00.000 42          10 10283       LILAS      1996-08-16 00:00:00.000 72          3 有時候XML中的數據並非以屬性的方式存在,而是直接放在節點中,以下:對象

DECLARE @doc varchar(1000)
SET @doc ='
<ROOT>
<Customer CustomerID="VINET" ContactName="Paul Henriot">
   <Order>
     <OrderID>10248</OrderID>
     <CustomerID>VINET</CustomerID>
     <EmployeeID>5</EmployeeID>
     <OrderDate>1996-07-04T00:00:00</OrderDate>
   </Order>
</Customer>
</ROOT>'

此時要獲Order節點下的各項的值,能夠用下面方法:blog

DECLARE @hdoc int
DECLARE @doc varchar(1000)
SET @doc ='
<ROOT>
<Customer CustomerID="VINET" ContactName="Paul Henriot">
   <Order>
     <OrderID>10248</OrderID>
     <CustomerID>VINET</CustomerID>
     <EmployeeID>5</EmployeeID>
     <OrderDate>1996-07-04T00:00:00</OrderDate>
   </Order>
</Customer>
</ROOT>'

EXEC sp_xml_preparedocument @hdoc OUTPUT, @doc
SELECT *
FROM   OPENXML (@hdoc, '/ROOT/Customer/Order',1)
WITH (OrderID       int         'OrderID',
   CustomerID  varchar(10) 'CustomerID',
   EmployeeID   int    'EmployeeID',
   OrderDate      datetime         'OrderDate')

查詢結果以下: OrderID     CustomerID EmployeeID  OrderDate ----------- ---------- ----------- ----------------------- 10248       VINET      5           1996-07-04 00:00:00.000 能夠看出是取屬性值仍是取節點的文本的值區別在於WITH子句的第三個參數是否有@符號ci

相關文章
相關標籤/搜索