Differenze tra LINQ to XML e DOM
Contenuto della sezione vengono descritte alcune delle differenze principali tra LINQ to XML e l'API di programmazione XML attualmente più diffusa, ovvero DOM (Document Object Model) W3C.
Nuove modalità di creazione degli alberi XML
In W3C DOM un albero XML viene compilata dal basso verso l'alto, ossia si crea un documento, si creano gli elementi e quindi si aggiungono gli elementi al documento.
Ad esempio, di seguito viene illustrata la creazione di un tipico albero XML tramite l'implementazione Microsoft di DOM, XmlDocument:
XmlDocument doc = new XmlDocument();
XmlElement name = doc.CreateElement("Name");
name.InnerText = "Patrick Hines";
XmlElement phone1 = doc.CreateElement("Phone");
phone1.SetAttribute("Type", "Home");
phone1.InnerText = "206-555-0144";
XmlElement phone2 = doc.CreateElement("Phone");
phone2.SetAttribute("Type", "Work");
phone2.InnerText = "425-555-0145";
XmlElement street1 = doc.CreateElement("Street1");
street1.InnerText = "123 Main St";
XmlElement city = doc.CreateElement("City");
city.InnerText = "Mercer Island";
XmlElement state = doc.CreateElement("State");
state.InnerText = "WA";
XmlElement postal = doc.CreateElement("Postal");
postal.InnerText = "68042";
XmlElement address = doc.CreateElement("Address");
address.AppendChild(street1);
address.AppendChild(city);
address.AppendChild(state);
address.AppendChild(postal);
XmlElement contact = doc.CreateElement("Contact");
contact.AppendChild(name);
contact.AppendChild(phone1);
contact.AppendChild(phone2);
contact.AppendChild(address);
XmlElement contacts = doc.CreateElement("Contacts");
contacts.AppendChild(contact);
doc.AppendChild(contacts);
Dim doc As XmlDocument = New XmlDocument()
Dim name As XmlElement = doc.CreateElement("Name")
name.InnerText = "Patrick Hines"
Dim phone1 As XmlElement = doc.CreateElement("Phone")
phone1.SetAttribute("Type", "Home")
phone1.InnerText = "206-555-0144"
Dim phone2 As XmlElement = doc.CreateElement("Phone")
phone2.SetAttribute("Type", "Work")
phone2.InnerText = "425-555-0145"
Dim street1 As XmlElement = doc.CreateElement("Street1")
street1.InnerText = "123 Main St"
Dim city As XmlElement = doc.CreateElement("City")
city.InnerText = "Mercer Island"
Dim state As XmlElement = doc.CreateElement("State")
state.InnerText = "WA"
Dim postal As XmlElement = doc.CreateElement("Postal")
postal.InnerText = "68042"
Dim address As XmlElement = doc.CreateElement("Address")
address.AppendChild(street1)
address.AppendChild(city)
address.AppendChild(state)
address.AppendChild(postal)
Dim contact As XmlElement = doc.CreateElement("Contact")
contact.AppendChild(name)
contact.AppendChild(phone1)
contact.AppendChild(phone2)
contact.AppendChild(address)
Dim contacts As XmlElement = doc.CreateElement("Contacts")
contacts.AppendChild(contact)
doc.AppendChild(contacts)
Console.WriteLine(doc.OuterXml)
Questo stile di codifica non fornisce molte informazioni visive sulla struttura dell'albero XML. Oltre a questo approccio di creazione di un albero, LINQ to XML supporta un approccio alternativo, la costruzione funzionale. Nella costruzione funzionale vengono usati i costruttori XElement e XAttribute per compilare un albero XML.
Di seguito è illustrata la creazione dello stesso albero XML tramite la costruzione funzionale di LINQ to XML:
XElement contacts =
new XElement("Contacts",
new XElement("Contact",
new XElement("Name", "Patrick Hines"),
new XElement("Phone", "206-555-0144",
new XAttribute("Type", "Home")),
new XElement("phone", "425-555-0145",
new XAttribute("Type", "Work")),
new XElement("Address",
new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
)
)
);
Si noti che il rientro del codice per costruire la struttura ad albero XML illustra la struttura dell'XML sottostante.
In Visual Basic il codice per costruire l'albero XML è ancora più semplice, in quanto prevede l'uso di valori letterali XML:
Dim contacts = _
<Contacts>
<Contact>
<Name>Patrick Hines</Name>
<Phone Type="Home">206-555-0144</Phone>
<Phone Type="Work">425-555-0145</Phone>
<Address>
<Street1>123 Main St</Street1>
<City>Mercer Island</City>
<State>WA</State>
<Postal>68042</Postal>
</Address>
</Contact>
</Contacts>
Se si desidera creare un albero XML da un documento XML esistente, è possibile aprire il documento XML in un editor, copiare il codice XML negli Appunti, aprire un modulo Visual Basic in Visual Studio e incollare direttamente l'XML nell'editor di codice Visual Basic.
Per altre informazioni, vedere Creazione di alberi XML.
Utilizzo diretto di elementi XML
Quando si programma con XML, l'obiettivo principale riguarda in genere gli elementi XML e talvolta gli attributi. In LINQ to XML è possibile usare direttamente gli elementi e gli attributi XML. Ad esempio, è possibile eseguire quanto le operazioni seguenti:
Creare elementi XML senza usare affatto un oggetto documento. In questo modo la programmazione risulta semplificata quando è necessario usare frammenti di alberi XML.
Caricare oggetti T:System.Xml.Linq.XElement direttamente da un file XML.
Serializzare oggetti T:System.Xml.Linq.XElement a un file o un flusso.
Al contrario, in W3C DOM il documento XML viene usato come contenitore logico per l'albero XML. In DOM i nodi XML, inclusi elementi e attributi, devono essere creati nel contesto di un documento XML. Di seguito è riportato un frammento del codice usato per creare un elemento name in DOM:
XmlDocument doc = new XmlDocument();
XmlElement name = doc.CreateElement("Name");
name.InnerText = "Patrick Hines";
doc.AppendChild(name);
Dim doc As XmlDocument = New XmlDocument()
Dim name As XmlElement = doc.CreateElement("Name")
name.InnerText = "Patrick Hines"
doc.AppendChild(name)
Se si desidera usare un elemento in più documenti, è necessario importare i nodi tra documenti. In LINQ to XML questo livello di complessità viene evitato.
Con LINQ to XML la classe XDocument viene usata solo se si desidera aggiungere un commento o un'istruzione di elaborazione al livello radice del documento.
Gestione semplificata di nomi e spazi dei nomi
La gestione di nomi, spazi dei nomi e prefissi di spazio dei nomi è in genere un aspetto complesso della programmazione XML. In LINQ to XML nomi e spazi dei nomi sono semplificati grazie all'eliminazione del requisito di gestire i prefissi di spazio dei nomi. Se si desidera, è possibile controllare i prefissi di spazio dei nomi. Se tuttavia si decide di non controllare in modo esplicito tali prefissi, durante la serializzazione LINQ to XML assegnerà i prefissi di spazio dei nomi se sono necessari oppure eseguirà la serializzazione usando spazi dei nomi predefiniti, se non sono necessari. Se vengono usati gli spazi dei nomi predefiniti, il documento risultante non conterrà prefissi di spazio dei nomi. Per altre informazioni, vedere Utilizzo degli spazi dei nomi XML.
Un altro problema di DOM è che non consente di modificare il nome di un nodo. È invece necessario creare un nuovo nodo e copiarvi tutti i nodi figlio, perdendo l'identità del nodo originale. In LINQ to XML questo problema viene evitato grazie alla possibilità di impostare la proprietà XName su un nodo.
Supporto dei metodi statici per il caricamento di XML
LINQ to XML consente di caricare XML usando metodi statici, anziché metodi di istanza, semplificando le operazioni di caricamento e analisi. Per altre informazioni, vedere Procedura: caricare XML da un file.
Rimozione del supporto per i costrutti DTD
In LINQ to XML la programmazione XML risulta ulteriormente semplificata tramite la rimozione del supporto per entità e riferimenti di entità. La gestione delle entità è complessa e viene usata raramente. Rimuovendone il supporto è possibile riscontrare un aumento delle prestazioni e un'interfaccia di programmazione semplificata. Quando un albero LINQ to XML viene popolato, tutte le entità DTD vengono espanse.
Supporto per i frammenti
In LINQ to XML non sono disponibili equivalenti per la classe XmlDocumentFragment. In molti casi, tuttavia, il concetto di XmlDocumentFragment può essere gestito dal risultato di una query digitato come IEnumerabledi XNode o IEnumerabledi XElement.
Supporto per XPathNavigator
LINQ to XML supporta XPathNavigator tramite i metodi di estensione nello spazio dei nomi System.Xml.XPath. Per altre informazioni, vedere Extensions.
Supporto per lo spazio vuoto e il rientro
In LINQ to XML lo spazio vuoto viene gestito più agevolmente rispetto a DOM.
In uno scenario comune viene letto il codice XML rientrato, viene creata una struttura ad albero XML in memoria senza nodi di testo di tipo spazio vuoto (ossia senza conservare lo spazio vuoto), vengono eseguite alcune operazioni su XML e quindi l'XML viene salvato senza rientro. Quando si serializza l'XML con la formattazione, nell'albero XML viene conservato solo lo spazio vuoto significativo. Questo è il comportamento predefinito per LINQ to XML.
In un altro scenario comune viene letto e modificato codice XML che è già stato intenzionalmente rientrato. È possibile che si desideri non modificare questo rientro in alcun modo. In LINQ to XML è possibile ottenere questo risultato conservando lo spazio vuoto durante il caricamento o l'analisi XML e disabilitando la formattazione durante la serializzazione XML.
In LINQ to XML lo spazio vuoto viene archiviato come nodo XText, anziché con un nodo Whitespace speciale, come invece avviene in DOM.
Supporto per le annotazioni
Gli elementi LINQ to XML supportano un set estensibile di annotazioni. Questa funzione è utile per tenere traccia di varie informazioni su un elemento, ad esempio informazioni sullo schema, informazioni che indicano se l'elemento è associato a un'interfaccia utente o altri tipi di informazioni specifiche dell'applicazione. Per altre informazioni, vedere Annotazioni in LINQ to XML.
Supporto per le informazioni sullo schema
In LINQ to XML è disponibile il supporto per la convalida XSD tramite i metodi di estensione nello spazio dei nomi System.Xml.Schema. È possibile verificare che un albero XML sia conforme a un XSD. È possibile popolare l'albero XML con le informazioni sulla convalida post-schema. Per altre informazioni, vedere Procedura: eseguire la convalida tramite XSD (LINQ to XML). e Extensions.