LINQ to XML im Vergleich zu DOM

In diesem Artikel werden einige der wichtigsten Unterschiede zwischen LINQ to XML und der derzeit verbreitetsten XML-Programmier-API, dem W3C-Dokumentobjektmodell (DOM), beschrieben.

Neue Möglichkeiten zum Konstruieren von XML-Strukturen

Im W3C-DOM erstellen Sie eine XML-Struktur von unten nach oben. Das bedeutet, Sie erstellen ein Dokument, Sie erstellen Elemente, und anschließend fügen Sie die Elemente dem Dokument hinzu.

Das folgende Beispiel zeigt eine typische Herangehensweise an das Erstellen einer XML-Struktur mit der Microsoft-Implementierung des 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)

Diese Codierungsart blendet die Struktur der XML-Struktur aus. LINQ to XML unterstützt auch einen alternativen Ansatz, funktionale Konstruktion, der die Struktur besser zeigt. Dieser Ansatz kann mit den XElement und XAttribute Konstruktoren durchgeführt werden. In Visual Basic können sie auch mit XML-Literalen ausgeführt werden. In diesem Beispiel wird die Konstruktion derselben XML-Struktur mithilfe der funktionalen Konstruktion veranschaulicht:

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>

Die Codeeinzüge verdeutlichen den Aufbau des der XML-Struktur zugrunde liegenden XML-Codes. Die Visual Basic-Version verwendet XML-Literale.

Weitere Informationen finden Sie unter XML-Strukturen.

Direktes Arbeiten mit XML-Elementen

Beim Programmieren mit XML liegt Ihr Hauptaugenmerk in der Regel auf XML-Elementen und vielleicht auch auf Attributen. In LINQ to XML können Sie direkt mit XML-Elementen und Attributen arbeiten. So können Sie z. B. Folgendes tun:

  • Sie können XML-Elemente ohne jegliche Verwendung eines Dokumentobjekts erstellen. Dies vereinfacht beim Arbeiten mit Fragmenten von XML-Strukturen die Programmierung.
  • Sie können T:System.Xml.Linq.XElement-Objekte direkt aus einer XML-Datei laden.
  • Sie können T:System.Xml.Linq.XElement-Objekte in eine Datei oder einen Stream serialisieren.

Vergleichen Sie dies mit dem W3C-DOM, bei dem das XML-Dokument als logischer Container für die XML-Struktur verwendet wird. Im DOM müssen die XML-Knoten einschließlich der Elemente und Attribute im Kontext eines XML-Dokuments erstellt werden. Das folgende Codefragment erstellt ein Namenselement im 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)

Wenn Sie ein Element in mehreren Dokumenten verwenden möchten, müssen Sie die Knoten dokumentübergreifend importieren. LINQ to XML vermeidet diese Komplexitätsebene.

Bei der Verwendung von LINQ to XML müssen Sie die XDocument-Klasse nur dann verwenden, wenn Sie der Stammebene des Dokuments einen Kommentar oder eine Verarbeitungsanweisung hinzufügen möchten.

Vereinfachte Handhabung von Namen und Namespaces

Die Handhabung von Namen, Namespaces und Namespacepräfixen ist im Allgemeinen ein komplexer Teil der XML-Programmierung. LINQ to XML vereinfacht Namen und Namespaces, weil der Umgang mit Namespacepräfixen nicht zwingend erforderlich ist. Das heißt aber nicht, dass Sie die Namespacepräfixe nicht mehr selbst steuern können. Wenn Sie sich aber dafür entscheiden, sich nicht mehr explizit um die Steuerung der Namespacepräfixe kümmern zu wollen, weist LINQ to XML bei der Serialisierung, wo erforderlich, entsprechende Namespacepräfixe zu oder greift für die Serialisierung auf die Standardnamespaces zurück. Wenn Standardnamespaces verwendet werden, gibt es im resultierenden Dokument keine Namespacepräfixe. Weitere Informationen finden Sie unter Übersicht über Namespaces.

Ein anderes Problem mit dem DOM besteht darin, dass es keine Änderung des Namens eines Knotens zulässt. Stattdessen müssen Sie einen neuen Knoten erstellen und alle untergeordneten Knoten kopieren, sodass die ursprüngliche Knotenidentität verloren geht. LINQ to XML vermeidet dieses Problem, indem es Ihnen ermöglicht wird, für einen Knoten die XName-Eigenschaft festzulegen.

Unterstützung statischer Methoden für das Laden von XML

In LINQ to XML können Sie zum Laden von XML anstelle von Instanzmethoden statische Methoden verwenden. Dadurch vereinfacht sich das Laden und das Analysieren. Weitere Informationen finden Sie unter Vorgehensweise: Laden von XML aus einer Datei.

Entfernung der Unterstützung für DTD-Konstrukte

LINQ to XML vereinfacht die XML-Programmierung zusätzlich, indem die Unterstützung für Entitäten und Entitätsverweise entfernt wird. Die Verwaltung von Entitäten ist komplex und wird selten verwendet. Durch das Entfernen dieser Unterstützung wird die Leistung verbessert und die Programmierung vereinfacht. Beim Auffüllen einer LINQ to XML-Struktur werden alle DTD-Entitäten erweitert.

Unterstützung für Fragmente

LINQ to XML stellt keine Entsprechung für die XmlDocumentFragment Klasse bereit. In vielen Fällen kann das XmlDocumentFragment Konzept jedoch durch das Ergebnis einer Abfrage behandelt werden, die als IEnumerable<T> von XNode, oder IEnumerable<T> von XElement eingegeben wurde.

Unterstützung für XPathNavigator

LINQ to XML bietet über die Erweiterungsmethoden im System.Xml.XPath-Namespace Unterstützung für XPathNavigator. Weitere Informationen finden Sie unter System.Xml.XPath.Extensions.

Unterstützung für Leerraum und Einzüge

LINQ to XML handhabt Leerzeichen einfacher als das DOM.

Ein gängiges Szenario ist das Einlesen von eingerücktem XML-Code, das Erstellen einer XML-Struktur im Arbeitsspeicher ohne Textknoten mit Leerraum (d. h. ohne Beibehaltung von Leerraum), das Anwenden einiger Vorgänge auf den XML-Code und das anschließende Speichern des XML-Codes mit Einrückung. Wenn Sie den XML-Code mit Formatierung serialisieren, bleibt nur signifikanter Leerraum in der XML-Struktur erhalten. Dies ist das Standardverhalten von LINQ to XML.

Aber auch dieses Szenario ist häufig anzutreffen: XML-Code, der bereits absichtlich mit Einzügen versehen wurde, wird gelesen und geändert. Sie möchten nicht, dass diese Einzüge irgendwie geändert werden. In LINQ to XML können Sie dies wie folgt tun:

  • Beibehalten von Leerraum beim Laden oder Analysieren des XML-Codes.
  • Deaktivieren der Formatierung beim Serialisieren des XML-Codes.

LINQ to XML speichert Leerraum als XText-Knoten und nicht als speziellen Whitespace-Knotentyp, wie dies im DOM der Fall ist.

Unterstützung für Anmerkungen

LINQ to XML-Elemente unterstützen einen erweiterbaren Satz von Anmerkungen. Dies ist hilfreich, wenn verschiedene Informationen zu einem Element nachverfolgt werden sollen, z.B. Schemainformationen, die Information, ob das Element an eine Benutzeroberfläche gebunden ist, oder andere anwendungsspezifische Informationen. Weitere Informationen finden Sie unter Anmerkungen zu LINQ to XML.

Unterstützung für Schemainformationen

LINQ to XML bietet über die Erweiterungsmethoden im System.Xml.Schema-Namespace Unterstützung für die XSD-Validierung. Sie können prüfen, ob sich eine XML-Struktur nach einer XSD richtet. Sie können die XML-Struktur mit dem Post-Schema-Validierungs-Infoset (PSVI) auffüllen. Weitere Informationen finden Sie unter Vorgehensweise: Überprüfen mithilfe von XSD und Extensions.

Siehe auch