Share via


Trabajar con el tipo de datos xml en aplicaciones cliente de Visual Studio

Esta característica se quitará en una versión futura de Microsoft SQL Server. Evite utilizar esta característica en nuevos trabajos de desarrollo y tenga previsto modificar las aplicaciones que actualmente la utilizan.

El tipo de datos xml permite almacenar fragmentos de XML, como una instancia XML que carece de un elemento de nivel superior y documentos XML válidos en una base de datos de SQL Server. Debido a esta característica de diseño, las instancias del tipo de datos xml deben asignarse en Visual Studio 2005 a una matriz de System.Xml.XmlNode en lugar de devolverse como System.Xml.XmlDocument. No se admite XML fragmentado.

Al trabajar directamente con la matriz de XmlNode incluida en el valor de instancia del tipo de datos xml, observará alguna diferencia entre el funcionamiento de las propiedades del miembro InnerXml y OuterXml, especialmente cuando la instancia de tipo de datos xml forma un documento XML válido, por ejemplo, cuando tiene un solo elemento de nivel superior.

Por ejemplo, suponga que dispone de las siguientes líneas de código que inician una nueva instancia de un extremo de SQL Server (MyServer.sql_endpoint) como un proxy Web que tiene un método Web (GetSomeXml) que devuelve un valor de instancia de fila de tipo de datos 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;

El valor de fila de tipo de datos xml devuelto contiene los siguientes datos:

<root><child/><child/></root>

Si las propiedades de InnerXml y de OuterXml para nodeArr[0] se asignan a un par de variables de cadena (xmlJustChildren y xmlWithRoot), tal y como se muestra en el código anterior, el valor de nodeArr[0].InnerXml sólo incluye los nodos que contiene el elemento actual (los dos elementos <child/> pero no el propio elemento <root>) y nodeArr[0].OuterXml funciona como estaba previsto: todos los nodos se incluyen en la matriz de XmlNodes (los elementos de <child/> y también el elemento de <root>).

Tenga en cuenta que este comportamiento difiere del habitual si trabaja con más frecuencia con XmlDocument porque esta clase implementa las propiedades de InnerXml y de OuterXml de forma distinta. Para las instancias de XmlDocument, la instancia del documento actúa como elemento contenedor para todos los XmlNodes del documento. Esto incluye el nodo raíz de nivel superior y todos los DTD o esquemas insertados de que disponga en un documento. Por lo tanto, el contenido de XmlDocument.InnerXml es el mismo que el de XmlDocument.OuterXml.

Debido a los detalles específicos de estas implementaciones, el uso de System.Xml.XmlDocumentFragment es una buena alternativa para trabajar con instancias de tipo de datos SQL Serverxml en aplicaciones cliente que trabajan con el servicio web XML nativo Los programadores estarán más familiarizados con la clase XmlDocumentFragment, ya que están más acostumbrados a utilizar XmlDocument, y XmlDocumentFragment acepta una matriz de XmlNode sin ningún problema.

Las siguientes secciones proporcionan ejemplos de código e información general sobre cómo utilizar XmlDocumentFragment para que funcione con los valores de instancia de tipo de datos SQL Serverxml en las aplicaciones cliente.

Procesar la salida mediante XmlDocumentFragment

Las siguientes líneas de código muestran cómo colocar una matriz de XmlNode en XmlDocumentFragment y, seguidamente, seleccionar los nodos del fragmento mediante una expresión 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);
}

Crear una entrada con una cadena mediante XmlDocumentFragment

El siguiente ejemplo muestra cómo crear una matriz de entrada de XmlNode mediante una asignación de cadenas a la propiedad InnerXml de 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;

Crear una entrada con un archivo mediante XmlDocumentFragment

La clase XmlDocumentFragment está más limitada que la clase XmlDocument en cuanto al modo de llenar una instancia se refiere. El siguiente ejemplo muestra cómo llenar una instancia de XmlDocumentFragment de un archivo mediante 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;