Condividi tramite


LINQ to XML e DOM

Questo articolo descrive alcune differenze principali tra LINQ to XML e l'API di programmazione XML predominante corrente, il DOM (Document Object Model) W3C.

Nuovi modi per costruire alberi XML

Nel DOM W3C si compila un albero XML dal basso verso l'alto; ovvero si crea un documento, si creano elementi e quindi si aggiungono gli elementi al documento.

L'esempio seguente, ad esempio, usa un modo tipico per creare un albero XML usando 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 nasconde la struttura dell'albero XML. LINQ to XML supporta anche un approccio alternativo, la costruzione funzionale, che mostra meglio la struttura. Questo approccio può essere realizzato con i costruttori XElement e XAttribute. In Visual Basic è anche possibile usare valori letterali XML. In questo esempio viene illustrata la costruzione dello stesso albero XML utilizzando la costruzione funzionale:

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")
            )
        )
    );
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>

Si noti che il rientro del codice per creare l'albero XML mostra la struttura dell'XML sottostante. La versione di Visual Basic utilizza valori letterali XML.

Per altre informazioni, vedere Alberi XML.

Usare direttamente gli elementi XML

Quando si programma con XML, l'attenzione principale è in genere sugli elementi XML e forse sugli attributi. In LINQ to XML è possibile usare direttamente elementi e attributi XML. È ad esempio possibile eseguire le seguenti operazioni:

  • Creare elementi XML senza utilizzare un oggetto documento. Ciò semplifica la programmazione quando è necessario lavorare con frammenti di alberi XML.
  • Caricare T:System.Xml.Linq.XElement gli oggetti direttamente da un file XML.
  • Serializzazione di T:System.Xml.Linq.XElement oggetti in un file o in un flusso.

Confrontarlo con il DOM W3C, in cui 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. Ecco un frammento di codice 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 vuole usare un elemento in più documenti, è necessario importare i nodi tra documenti. LINQ to XML evita questo livello di complessità.

Quando si usa LINQ to XML, usare la XDocument classe solo se si desidera aggiungere un commento o un'istruzione di elaborazione a livello radice del documento.

Gestione semplificata di nomi e namespace

La gestione di nomi, spazi dei nomi e prefissi dello spazio dei nomi è in genere una parte complessa della programmazione XML. LINQ to XML semplifica i nomi e gli spazi dei nomi eliminando la necessità di gestire i prefissi dello spazio dei nomi. Se si desidera controllare i prefissi dello spazio dei nomi, è possibile. Tuttavia, se si decide di non controllare in modo esplicito i prefissi dello spazio dei nomi, LINQ to XML assegnerà prefissi dello spazio dei nomi durante la serializzazione se sono necessari o serializzerà usando gli spazi dei nomi predefiniti in caso contrario. Se vengono usati namespace predefiniti, nel documento risultante non saranno presenti prefissi di namespace. Per ulteriori informazioni, vedere Panoramica dei namespace.

Un altro problema con il 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. LINQ to XML evita questo problema consentendo di impostare la XName proprietà in un nodo.

Supporto del metodo statico per il caricamento di XML

LINQ to XML consente di caricare XML usando metodi statici, anziché metodi di istanza. Ciò semplifica il caricamento e l'analisi. Per altre informazioni, vedere Come caricare xml da un file.

Rimozione del supporto per i costrutti DTD

LINQ to XML semplifica ulteriormente la programmazione XML rimuovendo il supporto per le entità e i riferimenti alle entità. La gestione delle entità è complessa e viene usata raramente. La rimozione del loro supporto aumenta le prestazioni e semplifica l'interfaccia di programmazione. Quando viene popolato un albero LINQ to XML, tutte le entità DTD vengono espanse.

Supporto per frammenti

LINQ to XML non fornisce un equivalente per la XmlDocumentFragment classe . In molti casi, tuttavia, il XmlDocumentFragment concetto può essere gestito dal risultato di una query digitata come IEnumerable<T> di XNode, o IEnumerable<T> di XElement.

Supporto per XPathNavigator

LINQ to XML fornisce supporto per XPathNavigator tramite metodi di estensione nello spazio dei nomi System.Xml.XPath. Per altre informazioni, vedere System.Xml.XPath.Extensions.

Supporto per spazi bianchi e indentazione

LINQ to XML gestisce più semplicemente lo spazio vuoto rispetto al DOM.

Uno scenario comune consiste nel leggere XML con rientro, creare un albero XML in memoria senza nodi di testo contenenti spazi bianchi, ovvero senza conservarli, eseguire alcune operazioni sull'XML e quindi salvare l'XML con rientro. Quando si serializza il codice XML con la formattazione, viene mantenuto solo uno spazio vuoto significativo nell'albero XML. Si tratta del comportamento predefinito per LINQ to XML.

Un altro scenario comune consiste nel leggere e modificare il documento XML che è già stato intenzionalmente indentato. È possibile che non si voglia modificare questo rientro in alcun modo. In LINQ to XML è possibile eseguire questa operazione:

  • Mantenere lo spazio vuoto quando si carica o si analizza il codice XML.
  • Disabilitazione della formattazione quando si serializza il codice XML.

LINQ to XML archivia lo spazio vuoto come XText nodo, invece di avere un tipo di nodo specializzato Whitespace , come fa il DOM.

Supporto per le annotazioni

Gli elementi LINQ to XML supportano un set estendibile di annotazioni. Ciò è utile per tenere traccia di informazioni varie su un elemento, ad esempio informazioni sullo schema, informazioni sul fatto che l'elemento sia associato a un'interfaccia utente o qualsiasi altro tipo di informazioni specifiche dell'applicazione. Per maggiori informazioni, vedere le annotazioni LINQ to XML.

Supporto per le informazioni sullo schema

LINQ to XML fornisce supporto per la convalida XSD tramite 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 l'infoset post-schema-validation (PSVI). Per altre informazioni, vedere Come convalidare tramite XSD e Extensions.

Vedere anche