在 Visual Studio 用戶端應用程式中使用 xml 資料類型
未來的 Microsoft SQL Server 版本將移除這項功能。請避免在新的開發工作中使用這項功能,並規劃修改目前使用這項功能的應用程式。
xml 資料類型,可讓您將 XML 片段 (例如,遺漏單一最上層元素的 XML 執行個體) 和有效的 XML 文件儲存在 SQL Server 資料庫中。因為這項設計特性,xml 資料類型執行個體在 Visual Studio 2005 中必須對應到 System.Xml.XmlNode 的陣列,而不是以 System.Xml.XmlDocument 傳回。以上不支援片段式 XML。
直接使用 xml 資料類型執行個體值所包含的 XmlNode 陣列時,您會發現 InnerXml 和 OuterXml 成員屬性在運作方式上的差異,尤其當 xml 資料類型執行個體形成有效的 XML 文件時,例如它含有單一最上層元素。
例如,假設您有下列幾行程式碼,它們會以 Web Proxy 來起始 SQL Server 結束點 (MyServer.sql_endpoint) 的新執行個體,這個 Web Proxy 有一個會傳回 xml 資料類型資料列執行個體值的 Web 方法 (GetSomeXml):
MyServer.sql_endpoint proxy = new MyServer.sql_endpoint();
proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;
SqlXmlDt = proxy.MyServerdboGetSomeXml();
System.Xml.XmlNode[] nodeArr = SqlXmlDt.Any;
string xmlJustChildren = nodeArr[0].InnerXml;
string xmlWithRoot = nodeArr[0].OuterXml;
則傳回的 xml 資料類型資料列值,將含有下列資料:
<root><child/><child/></root>
如果 nodeArr[0] 的 InnerXml 和 OuterXml 屬性指定給一對字串變數 (xmlJustChildren 和 xmlWithRoot),如上面的程式碼所示,則 nodeArr[0].InnerXml 的值只會包含目前元素內的節點 (兩個 <child/> 元素,但不含 <root> 元素本身),而 nodeArr[0].OuterXml 則可如預期運作:包含 XmlNodes 陣列的所有節點 (<child/> 元素和 <root> 元素)。
請注意,如果您更常使用 XmlDocument,則上述行為會與您平常所看到的不同,因為該類別實作 InnerXml 和 OuterXml 屬性的方式與此不同。若為 XmlDocument 執行個體,則文件執行個體扮演文件中所有 XmlNodes 之包裝函式元素的角色,這包括最上層根節點和文件中的任何內嵌 DTD 或結構描述。因此,XmlDocument.InnerXml 的內容與 XmlDocument.OuterXml 一樣。
由於這些實作的特性,在使用原生 XML Web 服務的用戶端應用程式中,可以考慮改用 System.Xml.XmlDocumentFragment 來搭配 SQL Serverxml 資料類型執行個體,這是一個理想的替代方法。習慣使用 XmlDocument 的開發人員,會比較熟悉 XmlDocumentFragment 類別,而且 XmlDocumentFragment 可接受 XmlNode 陣列,不會發生問題。
以下各節提供程式碼,以及如何在用戶端應用程式中使用 XmlDocumentFragment 搭配 SQL Serverxml 資料類型執行個體值的概觀。
使用 XmlDocumentFragment 處理輸出
下列幾行程式碼顯示如何將 XmlNode 的陣列放入 XmlDocumentFragment,然後使用 XPath 運算式,從片段中選取節點。
System.Xml.XmlDocumentFragment fragOut = SqlXmlDt.Any[0].OwnerDocument.CreateDocumentFragment();
// Loop over your XmlNode array and populate your XmlDocumentFragment.
foreach (System.Xml.XmlNode xmlnode in SqlXmlDt.Any)
{
fragOut.AppendChild(xmlnode);
}
// Loop over your XPath expression/selection for results.
foreach (System.Xml.XmlNode xmlpath in fragOut.SelectNodes("//bar"))
{
System.Console.WriteLine(xmlpath.OuterXml);
}
使用 XmlDocumentFragment 建立含有字串的輸入
以下示範如何使用 XmlDocumentFragment 之 InnerXml 屬性的字串指派,來建立 XmlNode 的輸入陣列。
// Create an owning XmlDocument
System.Xml.XmlDocument xmldoc = new System.Xml.XmlDocument();
// Create your XmlDocumentFragment.
System.Xml.XmlDocumentFragment fragIn = xmldoc.CreateDocumentFragment();
// Fill the XmlDocumentFragment with a string.
fragIn.InnerXml =
" <a>" +
" <b>inputvalue</b>" +
" </a>" +
" topstuff" +
" <b/>";
// Create an XmlNode array (should never require more than one element).
System.Xml.XmlNode[] xmlnodes = new System.Xml.XmlNode[1];
// Put the XmlDocumentFragment in the array and fill your XmlDt
xmlnodes[0] = (System.Xml.XmlNode) fragIn;
SqlXmlDt.Any = xmlnodes;
使用 XmlDocumentFragment 從檔案建立輸入
在如何擴展執行個體方面,XmlDocumentFragment 類別比 XmlDocument 類別受到更多限制。下列範例顯示如何使用 System.Xml.XmlReader,從檔案擴展 XmlDocumentFragment 執行個體。
// Create an owning XmlDocument.
System.Xml.XmlDocument xmldoc = new System.Xml.XmlDocument();
// Create your XmlDocumentFragment.
System.Xml.XmlDocumentFragment fragIn = xmldoc.CreateDocumentFragment();
// Build an XmlReader from the file.
System.Xml.XmlReaderSettings rs = new System.Xml.XmlReaderSettings();
rs.ConformanceLevel = System.Xml.ConformanceLevel.Fragment;
System.Xml.XmlReader reader = System.Xml.XmlReader.Create("c:\\file.xml", rs);
// Populate the fragment with the nodes from the XmlReader.
System.Xml.XmlNode child;
while (null != (child = xmldoc.ReadNode(reader)))
fragIn.AppendChild(child);
// Create your XmlNode array (should never require more than one element)
System.Xml.XmlNode[] xmlnodes = new System.Xml.XmlNode[1];
// Put the XmlDocumentFragment in the array and fill our XmlDt.
xmlnodes[0] = (System.Xml.XmlNode) fragIn;
SqlXmlDt.Any = xmlnodes;