XDocument oder XmlDocument

502

Ich lerne jetzt, XmlDocumentaber ich bin gerade auf etwas gestoßen, XDocumentund wenn ich versuche, den Unterschied oder die Vorteile von ihnen zu suchen, kann ich nichts Nützliches finden. Können Sie mir bitte sagen, warum Sie eines über das andere verwenden würden?

Tarik
quelle
13
Ich frage mich, warum die Dokumentationsmitarbeiter in Microsoft keine Notizen oder Bemerkungen in MSDN eingefügt haben, um ihre Unterschiede zu klären oder wann was zu verwenden ist.
Kamran Bigdely
1
Einige Informationen zu msdn: msdn.microsoft.com/en-us/library/… . Und eine Leistungsfrage: stackoverflow.com/questions/4383919/… . Persönlich habe ich es einfacher gefunden, mit LINQ to XML zu arbeiten.
Nawfal

Antworten:

500

Wenn Sie .NET - Version 3.0 oder niedriger verwenden, Sie haben zu verwenden , XmlDocumentauch bekannt als den klassischen DOM - API. Ebenso werden Sie feststellen, dass es einige andere APIs gibt, die dies erwarten.

Wenn Sie jedoch die Wahl haben, würde ich die Verwendung von XDocumentaka LINQ to XML empfehlen . Es ist viel einfacher, Dokumente zu erstellen und zu verarbeiten. Zum Beispiel ist es der Unterschied zwischen:

XmlDocument doc = new XmlDocument();
XmlElement root = doc.CreateElement("root");
root.SetAttribute("name", "value");
XmlElement child = doc.CreateElement("child");
child.InnerText = "text node";
root.AppendChild(child);
doc.AppendChild(root);

und

XDocument doc = new XDocument(
    new XElement("root",
                 new XAttribute("name", "value"),
                 new XElement("child", "text node")));

Namespaces sind in LINQ to XML ziemlich einfach zu bearbeiten, im Gegensatz zu jeder anderen XML-API, die ich jemals gesehen habe:

XNamespace ns = "http://somewhere.com";
XElement element = new XElement(ns + "elementName");
// etc

LINQ to XML funktioniert auch sehr gut mit LINQ - sein Konstruktionsmodell ermöglicht es Ihnen, Elemente mit Sequenzen von Unterelementen ganz einfach zu erstellen:

// Customers is a List<Customer>
XElement customersElement = new XElement("customers",
    customers.Select(c => new XElement("customer",
        new XAttribute("name", c.Name),
        new XAttribute("lastSeen", c.LastOrder)
        new XElement("address",
            new XAttribute("town", c.Town),
            new XAttribute("firstline", c.Address1),
            // etc
    ));

Es ist alles viel deklarativer, was zum allgemeinen LINQ-Stil passt.

Wie Brannon bereits erwähnt hat, handelt es sich hierbei eher um In-Memory-APIs als um Streaming-APIs (obwohl dies XStreamingElementeine verzögerte Ausgabe unterstützt). XmlReaderund XmlWritersind die normalen Methoden zum Streamen von XML in .NET, aber Sie können alle APIs bis zu einem gewissen Grad mischen. Sie können beispielsweise ein großes Dokument streamen, aber LINQ to XML verwenden, indem Sie ein XmlReaderam Anfang eines Elements positionieren, ein Element daraus lesen XElementund verarbeiten und dann zum nächsten Element usw. übergehen. Es gibt verschiedene Blog-Beiträge zu dieser Technik. Hier ist eine, die ich mit einer schnellen Suche gefunden habe .

Jon Skeet
quelle
Können Sie mir sagen, warum sie unterschiedlich sind? Ich meine ja, XDocument sieht ziemlich ordentlich aus, aber was den Unterschied auf DOM-Ebene betrifft, gibt es nicht beide XML-Dateien. Gibt es ein Schema, das sowohl Microsoft X-DOM- als auch W3C-kompatibles DOM anzeigt? Vielen Dank.
Tarik
3
Was meinst du mit "Schema" und was meinst du mit "Shows"? Ja, beide beschäftigen sich mit Standard-XML, aber LINQ to XML ist für die meisten Dinge nur eine schönere API. Ein Großteil der Technologie hinter LINQ to XML war vor .NET 3.5 einfach nicht verfügbar.
Jon Skeet
Ich meine, ob ihre Dokumentobjektmodelle unterschiedlich sind?
Tarik
6
Nun, sie sind beide APIs für XML selbst, also sind sie in diesem Sinne nicht unterschiedlich, nein. Ich vermute, dass beide einige Einschränkungen haben (und es gibt eine LINQ to XML-Version, die ich kenne, an die ich mich aber nicht erinnern kann), aber in den meisten Fällen können Sie sie einfach als dasselbe Modell mit leicht unterschiedlichen Darstellungen behandeln.
Jon Skeet
1
@SensorSmith: Das deckt jedoch nicht alle anderen Boni ab, wie das automatische Reduzieren von Sequenzen, die Behandlung von DateTime usw. Sie könnten auch Erweiterungsmethoden für all das hinzufügen, aber warum sollten Sie LINQ in XML neu erfinden, wenn Sie es stattdessen einfach verwenden können?
Jon Skeet
57

Ich bin überrascht, dass in keiner der bisherigen Antworten die Tatsache erwähnt wird, dass XmlDocumentkeine Zeileninformationen bereitgestellt werden , während dies der XDocumentFall ist (über die IXmlLineInfoSchnittstelle).

Dies kann in einigen Fällen eine wichtige Funktion sein (z. B. wenn Sie Fehler in einer XML-Datei melden oder verfolgen möchten, wo Elemente im Allgemeinen definiert sind), und Sie sollten sich dessen besser bewusst sein, bevor Sie mit der Implementierung beginnen XmlDocument, um sie später zu implementieren Entdecken Sie, dass Sie alles ändern müssen.

Julien Guertault
quelle
1
Und ich bin überrascht, dass niemand bemerkt hat, dass Ihre Aussage umgekehrt wahr ist. XmlDocument liefert die Zeileninformationen, XDocument nicht.
VVS
4
@VVS: Sie haben mir für einen Moment Sorgen gemacht, dass ich einen schrecklichen Tippfehler gemacht habe, aber nach doppelter Überprüfung bestätige ich, dass XDocumentdies Leitungsinformationen liefert. Siehe XDocument.Load with LoadOptions.SetLineInfoals zweites Argument. Wenn Sie einen Weg kennen, um Leitungsinformationen zu erhalten, XmlDocumentbin ich neugierig; Als ich diese Antwort schrieb, konnte ich keine finden. Diese andere Antwort scheint zu bestätigen: stackoverflow.com/a/33622102/253883
Julien Guertault
1
"Und Sie sollten sich dessen besser bewusst sein, bevor Sie mit der Implementierung von XmlDocument beginnen, um später festzustellen, dass Sie alles ändern müssen."
Paul
36

XmlDocumentist ideal für Entwickler, die mit dem XML-DOM-Objektmodell vertraut sind. Es gibt es schon eine Weile und es entspricht mehr oder weniger einem W3C-Standard. Es unterstützt die manuelle Navigation sowie die XPathKnotenauswahl.

XDocumentAktiviert die LINQ to XML-Funktion in .NET 3.5. Es ist stark beansprucht IEnumerable<>und kann in geradem C # einfacher zu bearbeiten sein.

Bei beiden Dokumentmodellen müssen Sie das gesamte Dokument in den Speicher laden (anders XmlReaderals beispielsweise).

Brannon
quelle
3
Ich denke, Sie meinten "und es kann einfacher sein, mit Straight VB.net zu arbeiten". Weil VB die direkte Erstellung von Elementen unterstützt, für die C # noch Code benötigt.
Brain2000
24

XDocumentist von der LINQ to XML-API und XmlDocumentist die Standard-DOM-API für XML. Wenn Sie DOM gut kennen und LINQ to XML nicht lernen möchten, fahren Sie mit fort XmlDocument. Wenn Sie beide noch nicht kennen, lesen Sie diese Seite , auf der die beiden verglichen werden, und wählen Sie die aus, die Ihnen besser gefällt.

Ich habe gerade angefangen, LINQ to XML zu verwenden, und ich mag die Art und Weise, wie Sie ein XML-Dokument mithilfe einer funktionalen Konstruktion erstellen. Es ist sehr schön. DOM ist im Vergleich klobig.

Daniel Chambers
quelle
23

Wie bereits an anderer Stelle erwähnt, macht Linq to Xml das Erstellen und Ändern von XML-Dokumenten zweifellos zum Kinderspiel XmlDocument, und die XNamespace ns + "elementName"Syntax sorgt für angenehmes Lesen beim Umgang mit Namespaces.

Eine Sache wert für die Erwähnung xslund xpathsterben Harten zu beachten ist , dass es möglich ist, nach wie vor willkürlich auszuführen xpath 1.0Ausdrücke auf Linq 2 Xml , XNodesindem:

using System.Xml.XPath;

und dann können wir mithilfe xpathdieser Erweiterungsmethoden navigieren und Daten projizieren :

Zum Beispiel angesichts des XML-Dokuments:

<xml>
    <foo>
        <baz id="1">10</baz>
        <bar id="2" special="1">baa baa</bar>
        <baz id="3">20</baz>
        <bar id="4" />
        <bar id="5" />
    </foo>
    <foo id="123">Text 1<moo />Text 2
    </foo>
</xml>

Wir können bewerten:

var node = xele.XPathSelectElement("/xml/foo[@id='123']");
var nodes = xele.XPathSelectElements(
"//moo/ancestor::xml/descendant::baz[@id='1']/following-sibling::bar[not(@special='1')]");
var sum = xele.XPathEvaluate("sum(//foo[not(moo)]/baz)");
StuartLC
quelle
14

Beachten Sie außerdem, dass XDocumentdies in Xbox 360 und Windows Phone OS 7.0 unterstützt wird. Wenn Sie auf sie abzielen, entwickeln Sie für XDocumentoder migrieren Sie von XmlDocument.

w0land
quelle
-8

Ich glaube, das XDocumentmacht viel mehr Aufrufe zur Objekterstellung. Ich vermute, dass, wenn Sie viele XML-Dokumente verarbeiten, XMLDocumentdies schneller sein wird.

Ein Ort, an dem dies geschieht, ist die Verwaltung von Scandaten. Viele Scan-Tools geben ihre Daten aus offensichtlichen Gründen in XML aus. Wenn Sie viele dieser Scandateien verarbeiten müssen, haben Sie meiner Meinung nach eine bessere Leistung XMLDocument.

Brian
quelle
11
Ich denke, Sie sollten Ihren Kommentar beim nächsten Mal mit Zahlen untermauern, da ich glaube, dass Sie sich irren könnten. Siehe blogs.msdn.com/b/codejunkie/archive/2008/10/08/…
Mike