sp_xml_preparedocument (Transact-SQL)

讀取以輸入提供的 XML 文字、使用 MSXML 剖析器 (Msxmlsql.dll) 剖析文字,以及以隨時可取用的狀態來提供已剖析的文件。這份已剖析的文件是以樹狀表示 XML 文件中的不同節點:元素、屬性、文字、註解等等。

sp_xml_preparedocument 傳回一個控制代碼,可用來存取 XML 文件的新建內部表示法。這個控制代碼在工作階段持續時間或直到執行 sp_xml_removedocument 而使控制代碼失效之前都有效。

[!附註]

已剖析的文件是儲存在 SQL Server 的內部快取中。MSXML 剖析器會使用 SQL Server 可用總記憶體的八分之一。若要避免記憶體用完,請執行 sp_xml_removedocument 來釋放記憶體。

[!附註]

基於回溯相容性,即使將屬性中的 CR (char(13)) 和 LF (char(10)) 字元實體化,sp_xml_preparedocument 仍會摺疊這些字元。

[!附註]

sp_xml_preparedocument 叫用的 XML 剖析器可以剖析內部 DTD 和實體宣告。因為惡意建構的 DTD 和實體宣告可用來執行阻斷服務攻擊,所以強烈建議使用者不要將來自不受信任之來源的 XML 文件直接傳遞至 sp_xml_preparedocument

為了減輕遞迴實體擴充的攻擊,sp_xml_preparedocument 對於在文件最上層的單一實體之下可以擴充的實體數目限制為 10,000。這項限制並不適用於字元或數值實體。此限制允許儲存含有多個實體參考的文件,但是會妨止超過 10,000 個擴充之鏈結中的實體進行遞迴擴充。

[!附註]

sp_xml_preparedocument 限制同時開啟元素的數目不得超過 256 個。

主題連結圖示Transact-SQL 語法慣例

語法

sp_xml_preparedocument
hdoc 
OUTPUT
[ , xmltext ]
[ , xpath_namespaces ] 

引數

  • hdoc
    這是新建文件的控制代碼。hdoc 是一個整數

  • [ xmltext ]
    這是原始 XML 文件集。MSXML 剖析器剖析這份 XML 文件集。xmltext 是文字參數:char、nchar、varchar、nvarchar、text、ntext 或 xml。預設值是 NULL,在這個情況下,會建立空白 XML 文件的內部表示法。

    [!附註]

    sp_xml_preparedocument 只能處理文字或不具類型的 XML。若要作為輸入使用之執行個體值是具類型的 XML,請先將它轉換為新的不具類型的 XML 執行個體,或轉換為字串,然後以輸入形式傳遞該值。如需詳細資訊,請參閱<比較不具類型的 XML 與具類型的 XML>。

  • [ xpath_namespaces ]
    指定使用於 OPENXML 中之資料列和資料行 XPath 運算式中的命名空間宣告。xpath_namespaces 是文字參數:char、nchar、varchar、nvarchar、text、ntext 或 xml。

    預設值是 <root xmlns:mp="urn:schemas-microsoft-com:xml-metaprop">。xpath_namespaces 利用格式正確的 XML 文件,提供 OPENXML 中的 XPath 運算式中使用之前置詞的命名空間 URI。xpath_namespaces 宣告必須用來參考命名空間 urn:schemas-microsoft-com:xml-metaprop 的前置詞;它提供有關已剖析之 XML 元素的中繼資料。雖然您可以使用這個技巧來重新定義中繼屬性命名空間的命名空間前置詞,但不會失去這個命名空間。前置詞 mpurn:schemas-microsoft-com:xml-metaprop 仍然有效,即使 xpath_namespaces 不包含這類宣告也是如此。

傳回碼值

0 (成功) 或 >0 (失敗)

權限

需要 public 角色中的成員資格。

範例

A. 準備格式正確之 XML 文件的內部表示法

下列範例會傳回以輸入形式提供之 XML 文件新建內部表示法的控制代碼。在呼叫 sp_xml_preparedocument 時,使用預設命名空間前置詞對應。

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>'
--Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @hdoc OUTPUT, @doc
-- Remove the internal representation.
exec sp_xml_removedocument @hdoc

B. 準備具有 DTD 的格式正確之 XML 文件的內部表示法

下列範例會傳回以輸入形式提供之 XML 文件新建內部表示法的控制代碼。預存程序會針對以文件中包含的 DTD 來驗證載入的文件。在呼叫 sp_xml_preparedocument 時,使用預設命名空間前置詞對應。

DECLARE @hdoc int
DECLARE @doc varchar(2000)
SET @doc = '
<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE root 
[<!ELEMENT root (Customers)*>
<!ELEMENT Customers EMPTY>
<!ATTLIST Customers CustomerID CDATA #IMPLIED ContactName CDATA #IMPLIED>]>
<root>
<Customers CustomerID="ALFKI" ContactName="Maria Anders"/>
</root>'

EXEC sp_xml_preparedocument @hdoc OUTPUT, @doc

C. 指定命名空間 URI

下列範例會傳回以輸入形式提供之 XML 文件新建內部表示法的控制代碼。sp_xml_preparedocument 的呼叫保留中繼屬性命名空間對應的 mp 前置詞,並將 xyz 對應前置詞加入至命名空間 urn:MyNamespace。

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>'
--Create an internal representation of the XML document.
EXEC sp_xml_preparedocument @hdoc OUTPUT, @doc, '<ROOT xmlns:xyz="urn:MyNamespace"/>'