Share via


Utilizzo del tipo di dati XML nelle applicazioni client di Visual Studio

Questa caratteristica verrà rimossa a partire da una delle prossime versioni di Microsoft SQL Server. Evitare di utilizzare questa caratteristica in un nuovo progetto di sviluppo e prevedere interventi di modifica nelle applicazioni in cui è attualmente implementata.

Il tipo di dati xml consente di archiviare frammenti XML, ad esempio un'istanza XML che non contiene un singolo elemento di livello superiore, e documenti XML validi in un database di SQL Server. È pertanto necessario che in Visual Studio 2005 le istanze del tipo di dati xml siano mappate a una matrice di System.Xml.XmlNode anziché essere restituite come System.Xml.XmlDocument. In questo modo, i frammenti XML non sono supportati.

Se si utilizza direttamente la matrice di XmlNode contenuta nel valore dell'istanza del tipo di dati xml, si noterà che le proprietà del membro InnerXml e del membro OuterXml funzionano in modo diverso, specialmente nel caso in cui l'istanza del tipo di dati xml compone un documento XML valido, ad esempio un singolo elemento di livello principale.

Si supponga, ad esempio, di utilizzare le righe di codice seguenti per inizializzare una nuova istanza di un endpoint SQL Server (MyServer.sql_endpoint) come un proxy Web per cui è disponibile un metodo Web (GetSomeXml) che restituisce un valore dell'istanza della riga del tipo di dati 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;

La riga del tipo di dati xml restituita include i dati seguenti:

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

Se le proprietà InnerXml e OuterXml di nodeArr[0] vengono quindi assegnate a una coppia di variabili stringa (xmlJustChildren e xmlWithRoot), come illustrato nel codice precedente, il valore di nodeArr[0].InnerXml include solo i nodi contenuti nell'elemento corrente (entrambi gli elementi <child/> ma non l'elemento <root>), e nodeArr[0].OuterXml funziona nel modo previsto ovvero include tutti i nodi nella matrice di XmlNodes (gli elementi <child/> e inoltre l'elemento <root>).

Si noti che questo comportamento è diverso da quello che in genere si verifica quando si utilizza più frequentemente XmlDocument, perché questa classe implementa in modo diverso le proprietà InnerXml e OuterXml. Per le istanze di XmlDocument, l'istanza del documento funge da wrapper per tutti gli elementi XmlNodes nel documento, inclusi il nodo radice di primo livello e le definizioni DTD o gli schemi eventualmente presenti nel documento. Il contenuto di XmlDocument.InnerXml è pertanto uguale a quello di XmlDocument.OuterXml.

In base alle indicazioni di implementazione precedenti, System.Xml.XmlDocumentFragment rappresenta una valida alternativa per l'utilizzo di istanze di tipi di dati xml di SQL Server nelle applicazioni client che si avvalgono di un servizio Web XML nativo. La classe XmlDocumentFragment è nota agli sviluppatori cha hanno familiarità con XmlDocument eaccetta una matrice di XmlNode senza alcun problema.

Nelle sezioni seguenti vengono illustrati alcuni esempi di codice e viene fornita una panoramica dell'utilizzo della classe XmlDocumentFragment con istanze del tipo di dati SQL Serverxml nelle applicazioni client.

Elaborazione di output tramite XmlDocumentFragment

Nel codice seguente vengono illustrati l'inserimento di una matrice di XmlNode in un frammento XmlDocumentFragment e quindi la selezione dei nodi dal frammento tramite un'espressione 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);
}

Creazione di input con una stringa tramite XmlDocumentFragment

Nel codice seguente viene illustrata la creazione di una matrice di input di XmlNode tramite l'assegnazione di una stringa alla proprietà InnerXml di 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;

Creazione di input da un file tramite XmlDocumentFragment

La classe XmlDocumentFragment presenta maggiori limitazioni rispetto alla classe XmlDocument per quanto riguarda il popolamento di un'istanza. Nell'esempio seguente viene illustrato il popolamento di un'istanza di XmlDocumentFragment da un file tramite 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;