Share via


Trabalhando com o tipo de dados xml em aplicativos cliente do Visual Studio

Esse recurso será removido em uma versão futura do Microsoft SQL Server. Evite usar esse recurso em desenvolvimentos novos e planeje modificar os aplicativos que atualmente o utilizam.

O tipo de dados xml permite armazenar fragmentos XML, como uma instância XML sem um único elemento de nível superior, e documentos XML válidos em um banco de dados do SQL Server. Devido a essa característica de design, as instâncias do tipo de dados xml devem ser mapeadas no Visual Studio 2005 para uma matriz de System.Xml.XmlNode, em vez de serem retornadas como System.Xml.XmlDocument. Não há suporte para XML fragmentado.

Ao trabalhar diretamente com a matriz de XmlNode contida pelo valor da instância do tipo de dados xml, você observará diferenças entre as maneiras como as propriedades de membro InnerXml e OuterXml funcionam, especialmente no caso em que a instância do tipo de dados xml forma um documento XML válido, como se tivesse um único elemento de nível superior.

Por exemplo, suponha que você tivesse as seguintes linhas de código que iniciam uma nova instância de um ponto de extremidade do SQL Server (MyServer.sql_endpoint) como um proxy da Web com um método Web (GetSomeXml) que retorna um valor da instância da linha do tipo de dados 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;

O valor da linha do tipo de dados xml retornado então tem os seguintes dados:

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

Se as propriedades InnerXml e OuterXml para nodeArr[0] forem então atribuídas para um par de variáveis de cadeia de caracteres (xmlJustChildren e xmlWithRoot), como mostra o código anterior, o valor de nodeArr[0].InnerXml incluirá apenas os nós que estão contidos no elemento atual (os dois elementos <child/>, mas não o próprio elemento <root>), e nodeArr[0].OuterXml funcionará da forma esperada: incluindo todos os nós na matriz de XmlNodes (os elementos <child/> e também o elemento <root>).

Observe que esse comportamento é diferente do que normalmente seria observado se você trabalhasse com mais freqüência com XmlDocument, pois esta classe implementa as propriedades InnerXml e OuterXml de forma diferente. Para instâncias XmlDocument, a instância de documento atua como elementos wrapper para todos os XmlNodes no documento. Isto inclui o nó raiz de nível superior e todos os esquemas ou DTDs embutidos que pode haver no documento. Assim, o conteúdo de XmlDocument.InnerXml é igual a XmlDocument.OuterXml.

Devido a essas particularidades de implementação, o uso de System.Xml.XmlDocumentFragment é uma boa alternativa para o trabalho com instâncias do tipo de dados xml do SQL Server em aplicativos cliente que trabalham com XML Web Services Nativos. A classe XmlDocumentFragment será mais familiar para os desenvolvedores que estão acostumados com o uso de XmlDocument, e XmlDocumentFragment aceitará uma matriz de XmlNode sem problemas.

As seções a seguir fornecem códigos e uma visão geral de como usar o XmlDocumentFragment para trabalhar com valores da instância do tipo de dados xml do SQL Server em aplicativos cliente.

Processando a saída usando XmlDocumentFragment

As linhas de código a seguir mostram como colocar uma matriz de XmlNode em um XmlDocumentFragment e depois selecionar nós do fragmento usando uma expressão 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);
}

Criando a entrada com uma cadeia de caracteres usando XmlDocumentFragment

Segue uma demonstração de como criar uma matriz de entrada de XmlNode usando uma atribuição de cadeia de caracteres para a propriedade 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;

Criando a entrada a partir de um arquivo usando XmlDocumentFragment

A classe XmlDocumentFragment é mais limitada que a classe XmlDocument, quando se trata de como preencher uma instância. O exemplo a seguir mostra como preencher uma instância XmlDocumentFragment a partir de um arquivo usando 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;