XDocument hoặc XmlDocument


502

Bây giờ tôi đang tìm hiểu XmlDocumentnhưng tôi vừa gặp phải XDocumentvà khi tôi cố gắng tìm kiếm sự khác biệt hoặc lợi ích của chúng, tôi không thể tìm thấy thứ gì hữu ích, bạn có thể vui lòng cho tôi biết lý do tại sao bạn sẽ sử dụng cái này không?


13
Tôi tự hỏi tại sao những người làm tài liệu trong Microsoft không đưa ra bất kỳ ghi chú hay nhận xét nào trong MSDN để làm rõ sự khác biệt của họ hoặc khi nào nên sử dụng cái gì.
Kamran Bigdely

1
Một số thông tin về msdn: msdn.microsoft.com/en-us/l Library / . Và một câu hỏi về hiệu suất: stackoverflow.com/questions/4383919/ . Cá nhân tôi thấy việc làm việc với LINQ to XML dễ dàng hơn.
nawfal

Câu trả lời:


500

Nếu bạn đang sử dụng .NET phiên bản 3.0 trở xuống, bạn phải sử dụng XmlDocumenthay còn gọi là API DOM cổ điển. Tương tự như vậy, bạn sẽ thấy có một số API khác sẽ mong đợi điều này.

Tuy nhiên, nếu bạn có được sự lựa chọn, tôi sẽ khuyên bạn nên sử dụng XDocumenthay còn gọi là LINQ to XML. Việc tạo tài liệu và xử lý chúng đơn giản hơn nhiều . Ví dụ: đó là sự khác biệt giữa:

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

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

Các không gian tên khá dễ làm việc trong LINQ to XML, không giống như bất kỳ API XML nào khác tôi từng thấy:

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

LINQ to XML cũng hoạt động thực sự tốt với LINQ - mô hình xây dựng của nó cho phép bạn xây dựng các phần tử với chuỗi các phần tử phụ thực sự dễ dàng:

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

Đó là tất cả nhiều tuyên bố hơn, phù hợp với phong cách LINQ chung.

Bây giờ như Brannon đã đề cập, đây là các API trong bộ nhớ thay vì phát trực tuyến (mặc dù XStreamingElementhỗ trợ đầu ra lười biếng). XmlReaderXmlWriterlà những cách truyền phát XML thông thường trong .NET, nhưng bạn có thể trộn tất cả các API ở một mức độ nào đó. Ví dụ: bạn có thể truyền phát một tài liệu lớn nhưng sử dụng LINQ sang XML bằng cách định vị XmlReaderphần đầu của một phần tử, đọc XElementtừ phần tử đó và xử lý nó, sau đó chuyển sang phần tử tiếp theo, v.v. Có nhiều bài đăng trên blog về kỹ thuật này, Đây là một cái tôi tìm thấy với một tìm kiếm nhanh .


Bạn có thể cho tôi biết tại sao họ khác nhau? Ý tôi là yeah XDocument trông khá gọn gàng nhưng đối với sự khác biệt về cấp độ DOM, cả hai đều không phải là xml, có sơ đồ nào hiển thị cả Microsoft X-DOM và W3C tuân thủ DOM không? Cảm ơn.
Tarik

3
Bạn có ý nghĩa gì bởi "chương trình" và ý nghĩa của "chương trình" là gì? Đúng, cả hai đều đối phó với XML tiêu chuẩn, nhưng LINQ to XML chỉ là một API đẹp hơn cho hầu hết mọi thứ. Rất nhiều công nghệ đằng sau LINQ to XML đơn giản là không có sẵn trước .NET 3.5.
Jon Skeet

Tôi có nghĩa là liệu mô hình đối tượng tài liệu của họ là khác nhau?
Tarik

6
Vâng, cả hai API đều cho chính XML, vì vậy theo nghĩa đó, chúng không khác nhau, không. Tôi nghi ngờ cả hai đều có một số hạn chế (và có một LINQ to XML mà tôi biết nhưng không thể nhớ ra khỏi đầu tôi) nhưng trong hầu hết các trường hợp, bạn chỉ có thể coi chúng là cùng một mô hình với các biểu diễn hơi khác nhau.
Jon Skeet

1
@SensorSmith: Tuy nhiên, điều đó không bao gồm tất cả các phần thưởng khác, như tự động làm phẳng các chuỗi, xử lý DateTime, v.v. Bạn có thể thêm các phương thức tiện ích mở rộng cho tất cả những điều đó, nhưng tại sao lại phát minh lại LINQ thành XML khi bạn chỉ có thể sử dụng nó?
Jon Skeet

57

Tôi ngạc nhiên không có câu trả lời nào cho đến nay đề cập đến thực tế là XmlDocumentkhông cung cấp thông tin dòng , trong khi XDocument (thông qua IXmlLineInfogiao diện).

Đây có thể là một tính năng quan trọng trong một số trường hợp (ví dụ: nếu bạn muốn báo cáo lỗi trong XML hoặc theo dõi các phần tử được xác định chung) và bạn nên biết điều này trước khi bạn vui vẻ bắt đầu sử dụng XmlDocument, để sau này khám phá bạn phải thay đổi tất cả.


1
Và tôi ngạc nhiên không ai nhận thấy rằng tuyên bố của bạn là hoàn toàn ngược lại. XmlDocument DOES cung cấp thông tin dòng trong khi XDocument không.
VVS

4
@VVS: bạn đã khiến tôi lo lắng một lúc rằng tôi đã mắc một lỗi đánh máy khủng khiếp, nhưng sau khi kiểm tra lại, tôi xác nhận rằng XDocumentnó cung cấp thông tin dòng. Xem XDocument.Load với LoadOptions.SetLineInfotư cách là đối số thứ hai. Nếu bạn biết một cách để có được thông tin dòng với XmlDocumenttôi tò mò; trở lại khi tôi viết câu trả lời này, tôi không thể tìm thấy bất kỳ. Câu trả lời khác này dường như xác nhận: stackoverflow.com/a/33622102/253883
Julien Guertault 31/12/17

1
"và tốt hơn hết là bạn nên biết điều này trước khi bạn vui vẻ bắt đầu thực hiện bằng XmlDocument, để sau này phát hiện ra bạn phải thay đổi tất cả." Đoán xem tôi vừa làm gì :)
Paul

36

XmlDocumentlà tuyệt vời cho các nhà phát triển đã quen thuộc với mô hình đối tượng XML DOM. Nó đã xuất hiện được một thời gian và ít nhiều tương ứng với tiêu chuẩn W3C. Nó hỗ trợ điều hướng thủ công cũng như XPathlựa chọn nút.

XDocumentcấp quyền cho tính năng LINQ to XML trong .NET 3.5. Nó làm cho việc sử dụng nhiều IEnumerable<>và có thể dễ dàng hơn để làm việc với C # thẳng.

Cả hai mô hình tài liệu đều yêu cầu bạn tải toàn bộ tài liệu vào bộ nhớ (không giống như XmlReaderví dụ).


3
Tôi nghĩ bạn có nghĩa là "và có thể dễ dàng hơn để làm việc với VB.net thẳng". Bởi vì VB hỗ trợ tạo trực tiếp các phần tử trong đó C # vẫn yêu cầu mã.
Brain2000

24

XDocumentlà từ API LINQ sang XML và XmlDocumentlà API kiểu DOM tiêu chuẩn cho XML. Nếu bạn biết rõ về DOM và không muốn học LINQ sang XML, hãy đi cùng XmlDocument. Nếu bạn chưa quen với cả hai, hãy xem trang này so sánh hai trang đó và chọn trang nào bạn thích có vẻ ngoài đẹp hơn.

Tôi mới bắt đầu sử dụng LINQ to XML và tôi thích cách bạn tạo một tài liệu XML bằng cách sử dụng chức năng xây dựng. Nó thật sự rất tuyệt. DOM là so sánh vụng về.


23

Như đã đề cập ở những nơi khác, chắc chắn, Linq to Xml giúp cho việc tạo và thay đổi các tài liệu xml trở nên dễ dàng hơn XmlDocumentXNamespace ns + "elementName"cú pháp giúp đọc dễ chịu khi xử lý các không gian tên.

Một điều đáng nói cho xslxpath thể lưu ý là vẫn có thể thực hiện các xpath 1.0biểu thức tùy ý trên Linq 2 Xml XNodesbằng cách bao gồm:

using System.Xml.XPath;

và sau đó chúng ta có thể điều hướng và dự án dữ liệu bằng cách sử dụng xpathcác phương thức mở rộng này:

Chẳng hạn, đưa ra tài liệu 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>

Chúng tôi có thể đánh giá:

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

14

Ngoài ra, lưu ý rằng XDocumentđược hỗ trợ trong Xbox 360 và Windows Phone OS 7.0. Nếu bạn nhắm mục tiêu chúng, phát triển cho XDocumenthoặc di chuyển từ XmlDocument.


-8

Tôi tin rằng điều đó XDocumentlàm cho nhiều cuộc gọi tạo đối tượng hơn. Tôi nghi ngờ rằng khi bạn xử lý nhiều tài liệu XML, XMLDocumentsẽ nhanh hơn.

Một nơi điều này xảy ra là trong việc quản lý dữ liệu quét. Nhiều công cụ quét xuất dữ liệu của họ bằng XML (vì lý do rõ ràng). Nếu bạn phải xử lý nhiều tệp quét này, tôi nghĩ bạn sẽ có hiệu suất tốt hơn XMLDocument.


11
Tôi nghĩ bạn nên gửi lại bình luận của bạn với số liệu vào lần tới, vì tôi tin rằng bạn có thể sai. Xem blog.msdn.com/b/codejunkie/archive/2008/10/08/ từ
mike
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.