Teraz się uczę, XmlDocument
ale właśnie natknąłem się na to, XDocument
a kiedy próbuję znaleźć różnicę lub korzyści z nich, nie mogę znaleźć czegoś przydatnego, czy mógłbyś mi powiedzieć, dlaczego używałbyś jednego nad drugim?
Teraz się uczę, XmlDocument
ale właśnie natknąłem się na to, XDocument
a kiedy próbuję znaleźć różnicę lub korzyści z nich, nie mogę znaleźć czegoś przydatnego, czy mógłbyś mi powiedzieć, dlaczego używałbyś jednego nad drugim?
Odpowiedzi:
Jeśli używasz .NET w wersji 3.0 lub obniżyć, to muszą korzystać XmlDocument
aka klasycznej DOM API. Przekonasz się również, że istnieją inne interfejsy API, które będą tego oczekiwać.
Jeśli jednak dostaniesz wybór, zdecydowanie polecam użycie XDocument
aka LINQ to XML. Tworzenie dokumentów i ich przetwarzanie jest znacznie prostsze. Na przykład jest to różnica między:
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);
i
XDocument doc = new XDocument(
new XElement("root",
new XAttribute("name", "value"),
new XElement("child", "text node")));
Przestrzenie nazw są dość łatwe w obsłudze w LINQ to XML, w przeciwieństwie do innych API XML, jakie kiedykolwiek widziałem:
XNamespace ns = "http://somewhere.com";
XElement element = new XElement(ns + "elementName");
// etc
LINQ to XML działa również bardzo dobrze z LINQ - jego model konstrukcyjny pozwala bardzo łatwo budować elementy z sekwencjami podelementów:
// 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
));
Wszystko jest o wiele bardziej deklaratywne, co pasuje do ogólnego stylu LINQ.
Teraz, jak wspomniał Brannon, są to interfejsy API w pamięci, a nie strumieniowe (chociaż XStreamingElement
obsługuje leniwe wyjście). XmlReader
i XmlWriter
są normalnymi sposobami przesyłania strumieniowego XML w .NET, ale do pewnego stopnia możesz mieszać wszystkie interfejsy API. Na przykład możesz przesyłać strumieniowo duży dokument, ale używać LINQ do XML, umieszczając XmlReader
na początku elementu, czytając XElement
z niego i przetwarzając go, a następnie przechodząc do następnego elementu itp. Istnieją różne posty na blogu o tej technice, oto jeden, który znalazłem dzięki szybkiemu wyszukiwaniu .
Dziwi mnie, że żadna z dotychczasowych odpowiedzi nie wspomina o tym, że XmlDocument
nie podaje żadnych informacji o wierszu , a XDocument
robi to (przez IXmlLineInfo
interfejs).
Może to być krytyczna funkcja w niektórych przypadkach (na przykład, jeśli chcesz zgłosić błędy w pliku XML lub śledzić, gdzie elementy są ogólnie zdefiniowane) i lepiej być tego świadomym, zanim z przyjemnością zaczniesz wdrażać XmlDocument
, aby później odkryj, że musisz to wszystko zmienić.
XDocument
zawiera informacje o wierszu. Zobacz XDocument.Load ze LoadOptions.SetLineInfo
jako drugi argument. Jeśli znasz sposób na uzyskanie informacji o linii XmlDocument
, jestem ciekawy; kiedy pisałem tę odpowiedź, nie mogłem jej znaleźć. Ta druga odpowiedź wydaje się potwierdzać: stackoverflow.com/a/33622102/253883
XmlDocument
jest świetny dla programistów znających model obiektowy XML DOM. Jest już od jakiegoś czasu i mniej więcej odpowiada standardowi W3C. Obsługuje ręczną nawigację, a także XPath
wybór węzła.
XDocument
zasila funkcję LINQ to XML w .NET 3.5. To sprawia, że jest intensywnie używany IEnumerable<>
i może być łatwiej pracować z prostym C #.
Oba modele dokumentów wymagają załadowania całego dokumentu do pamięci (w przeciwieństwie XmlReader
do na przykład).
XDocument
pochodzi z interfejsu API LINQ to XML i XmlDocument
jest standardowym interfejsem API typu DOM dla XML. Jeśli dobrze znasz DOM i nie chcesz uczyć się LINQ na XML, idź z XmlDocument
. Jeśli jesteś nowy w obu przypadkach, sprawdź tę stronę, która porównuje oba, i wybierz, który Ci się bardziej podoba.
Właśnie zacząłem używać LINQ na XML i uwielbiam sposób, w jaki tworzysz dokument XML przy użyciu funkcjonalnej konstrukcji. To naprawdę miłe. DOM jest nieporadny w porównaniu.
Jak wspomniano w innym miejscu, niewątpliwie Linq do Xml sprawia, że tworzenie i modyfikowanie dokumentów xml jest dziecinnie proste w porównaniu z XmlDocument
, a XNamespace ns + "elementName"
składnia zapewnia przyjemne czytanie w przypadku przestrzeni nazw.
Jedną z rzeczy, o których warto wspomnieć xsl
i których xpath
należy pamiętać, jest to, że nadal można wykonywać dowolne xpath 1.0
wyrażenia na Linq 2 Xml XNodes
, włączając:
using System.Xml.XPath;
a następnie możemy nawigować i wyświetlać dane za xpath
pomocą następujących metod rozszerzenia:
Na przykład biorąc pod uwagę dokument Xml:
<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>
Możemy ocenić:
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)");
Uważam, że to XDocument
powoduje znacznie więcej wywołań tworzenia obiektów. Podejrzewam, że gdy będziesz przetwarzać wiele dokumentów XML, XMLDocument
będzie to szybsze.
Jednym z takich przypadków jest zarządzanie skanowanymi danymi. Wiele narzędzi skanujących wysyła swoje dane w formacie XML (z oczywistych powodów). Jeśli musisz przetworzyć wiele z tych plików skanowania, myślę, że będziesz mieć lepszą wydajność XMLDocument
.