Работа с типом данных xml в клиентских приложениях Visual Studio
Тип данных xml в SQL Server 2005 позволяет хранить в базе данных SQL Server фрагменты XML-документов, например экземпляры XML, в которых нет единого корневого элемента, а также допустимые XML-документы. Из-за этих архитектурных особенностей экземпляры типа данных xml в Visual Studio 2005 должны сопоставляться с массивом элементов System.Xml.XmlNode, а не возвращаться как объект класса System.Xml.XmlDocument. Этот класс не поддерживает работу с фрагментами XML.
При работе напрямую с массивом объектов XmlNode, хранящихся в значении типа данных xml, обнаружатся различия между работой свойств класса InnerXml и OuterXml, особенно когда экземпляр типа данных xml образует допустимый XML-документ, то есть у него есть единый корневой элемент.
Предположим, что имеются следующие строки кода, который создает новый экземпляр конечной точки SQL Server 2005 (MyServer.sql_endpoint) как веб-прокси с веб-методом (GetSomeXml), возвращающим строку с экземпляром типа данных xml.
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>
Если свойства InnerXml
и OuterXml
массива nodeArr[0]
затем присваиваются паре строковых переменных (xmlJustChildren
и xmlWithRoot
), как в приведенном коде, окажется, что значение nodeArr[0].InnerXml
будет содержать только узлы внутри текущего элемента (оба элемента <child/>
, но не сам элемент <root>
), а nodeArr[0].OuterXml
будет работать, как ожидалось: он будет содержать все узлы из массива XmlNodes
(элементы <child/>
и элемент <root>
).
Обратите внимание на то, что это поведение отличается от более привычного поведения XmlDocument, так как этот класс реализует свойства InnerXml и OuterXml по-другому. В экземплярах XmlDocument экземпляр документа играет роль упаковщика для всех элементов XmlNodes документа. Сюда входят и корневой узел, и все встроенные определения DTD или схемы, которые могут быть включены в документ. Поэтому содержимое XmlDocument.InnerXml не отличается от содержимого XmlDocument.OuterXml.
Из-за этих особенностей реализации использование класса System.Xml.XmlDocumentFragment — хорошая альтернатива для работы с экземплярами типа данных xml SQL Server в клиентских приложениях, использующих веб-службы со встроенной поддержкой XML сервера SQL Server 2005. Класс XmlDocumentFragment будет более знаком разработчикам, работавшим только с XmlDocument, и XmlDocumentFragment принимает массив элементов типа XmlNode без каких-либо проблем.
В следующих разделах приведен код и обзор использования класса XmlDocumentFragment для работы со значениями SQL Server типа xml в клиентских приложениях.
Обработка вывода с помощью класса 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
Следующий код демонстрирует, как построить массив элементов XmlNode
для ввода, присваивая строку свойству InnerXml
объекта XmlDocumentFragment
.
// 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. Следующий пример показывает, как наполнить экземпляр класса XmlDocumentFragment
из файла с помощью System.Xml.XmlReader
.
// 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;
См. также
Другие ресурсы
Запрос XQuery к типу данных xml
Написание клиентских приложений