XDocument หรือ XmlDocument


502

ตอนนี้ฉันกำลังเรียนรู้XmlDocumentแต่ฉันเพิ่งพบเจอXDocumentและเมื่อฉันพยายามค้นหาความแตกต่างหรือผลประโยชน์ของพวกเขาฉันไม่สามารถหาสิ่งที่มีประโยชน์ได้คุณช่วยบอกฉันหน่อยได้ไหมว่าทำไมคุณถึงใช้สิ่งอื่น


13
ฉันสงสัยว่าทำไมคนเอกสารใน Microsoft ไม่ได้ใส่บันทึกย่อหรือหมายเหตุใน MSDN เพื่อชี้แจงความแตกต่างหรือเมื่อใช้อะไร
Kamran Bigdely

1
ข้อมูลบางอย่างเกี่ยวกับ MSDN: msdn.microsoft.com/en-us/library/... และคำถามประสิทธิภาพการทำงาน: stackoverflow.com/questions/4383919/... ส่วนตัวฉันพบว่าทำงานกับ LINQ กับ XML ได้ง่ายขึ้น
nawfal

คำตอบ:


500

หากคุณใช้. NET เวอร์ชัน 3.0 หรือต่ำกว่าคุณต้องใช้XmlDocumentaka DOM API แบบคลาสสิก ในทำนองเดียวกันคุณจะพบว่ามี API อื่น ๆ ที่จะคาดหวังสิ่งนี้

หากคุณได้รับตัวเลือกอย่างไรก็ตามฉันขอแนะนำอย่างละเอียดให้ใช้XDocumentaka LINQ กับ XML มันมากง่ายต่อการสร้างเอกสารและดำเนินการให้ ตัวอย่างเช่นมันเป็นความแตกต่างระหว่าง:

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

Namespaces นั้นใช้งานได้ง่ายใน LINQ ถึง XML ซึ่งแตกต่างจาก XML API อื่น ๆ ที่ฉันเคยเห็น:

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

LINQ ไปยัง XML นั้นทำงานได้ดีกับ LINQ - รูปแบบการก่อสร้างช่วยให้คุณสามารถสร้างองค์ประกอบที่มีลำดับขององค์ประกอบย่อยได้อย่างง่ายดาย:

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

มันคือทั้งหมดที่ประกาศมากขึ้นซึ่งเหมาะกับสไตล์ LINQ ทั่วไป

ขณะนี้เป็นน็กล่าวถึงเหล่านี้เป็น APIs ในหน่วยความจำมากกว่าสตรีมมิ่งคน (แม้ว่าXStreamingElementการสนับสนุนการส่งออกขี้เกียจ) XmlReaderและXmlWriterเป็นวิธีปกติของการสตรีม XML ใน. NET แต่คุณสามารถผสม API ทั้งหมดได้ในระดับหนึ่ง ตัวอย่างเช่นคุณสามารถสตรีมเอกสารขนาดใหญ่ แต่ใช้ LINQ ไปยัง XML โดยการวางตำแหน่งXmlReaderที่จุดเริ่มต้นขององค์ประกอบอ่านXElementจากมันและประมวลผลแล้วย้ายไปยังองค์ประกอบต่อไป ฯลฯ มีโพสต์บล็อกต่าง ๆ เกี่ยวกับเทคนิคนี้นี่คือหนึ่งฉันได้พบกับการค้นหาอย่างรวดเร็ว


คุณบอกฉันได้ไหมว่าทำไมพวกเขาถึงแตกต่าง ฉันหมายถึงใช่ XDocument ดูเรียบร้อยดี แต่สำหรับความแตกต่างระดับ DOM พวกเขาทั้งสองไม่ใช่ xml มีรูปแบบที่แสดงทั้ง Microsoft X-DOM และ W3C Compliant DOM หรือไม่ ขอบคุณ
Tarik

3
คุณหมายถึงอะไรโดย "แผนการ" และ "การแสดง" หมายความว่าอะไร? ใช่พวกเขาทั้งสองจัดการกับ XML มาตรฐาน แต่ LINQ ถึง XML เป็นเพียง nicer API สำหรับสิ่งส่วนใหญ่ เทคโนโลยีจำนวนมากที่อยู่เบื้องหลัง LINQ ไปยัง XML นั้นไม่พร้อมใช้งานก่อนหน้า NET 3.5
Jon Skeet

ฉันหมายความว่าแบบจำลองวัตถุเอกสารของพวกเขาแตกต่างกันอย่างไร
Tarik

6
พวกเขาทั้งสอง APIs สำหรับ XML เองดังนั้นในแง่นั้นพวกเขาไม่ต่างกันเลย ฉันสงสัยว่าทั้งสองมีข้อ จำกัด บางอย่าง (และมี LINQ หนึ่งไปยัง XML ซึ่งฉันรู้ แต่ไม่สามารถจำได้จากด้านบนของหัวของฉัน) แต่ในกรณีส่วนใหญ่คุณสามารถปฏิบัติต่อพวกเขาเป็นรูปแบบเดียวกันกับตัวแทนที่แตกต่างกันเล็กน้อย
Jon Skeet

1
@SensorSmith: นั่นไม่ครอบคลุมโบนัสอื่น ๆ ทั้งหมด แต่อย่างเช่นการแบนของลำดับอัตโนมัติการจัดการ DateTime ฯลฯ คุณสามารถเพิ่มวิธีการขยายสำหรับทุกอย่างด้วย แต่ทำไม reinvent LINQ ถึง XML เมื่อคุณสามารถใช้แทนได้หรือไม่
Jon Skeet

57

ผมประหลาดใจไม่มีคำตอบเพื่อให้ห่างไกลกล่าวถึงความจริงที่ว่าXmlDocumentให้ข้อมูลเส้นในขณะที่XDocumentไม่ (ผ่านIXmlLineInfoอินเตอร์เฟซ)

นี้อาจจะเป็นคุณลักษณะที่สำคัญในบางกรณี (ตัวอย่างเช่นถ้าคุณต้องการที่จะรายงานข้อผิดพลาดใน XML หรือติดตามการที่องค์ประกอบที่กำหนดไว้ในทั่วไป) และคุณควรที่จะตระหนักถึงเรื่องนี้ก่อนที่คุณจะมีความสุขเริ่มต้นที่จะดำเนินการโดยใช้XmlDocumentเพื่อในภายหลัง ค้นพบว่าคุณต้องเปลี่ยนทุกอย่าง


1
และฉันประหลาดใจที่ไม่มีใครสังเกตเห็นว่าคำสั่งของคุณเป็นจริงตรงกันข้าม XmlDocument DOES ให้ข้อมูลบรรทัดในขณะที่ XDocument ไม่มี
VVS

4
@VVS: คุณทำให้ฉันกังวลในขณะที่ฉันพิมพ์ผิดแย่มาก แต่หลังจากตรวจสอบอีกครั้งฉันยืนยันว่าXDocumentให้ข้อมูลบรรทัด ดูXDocument.Loadด้วยLoadOptions.SetLineInfoเป็นอาร์กิวเมนต์ที่สอง หากคุณรู้วิธีรับข้อมูลบรรทัดด้วยXmlDocumentฉันอยากรู้ ย้อนกลับไปเมื่อฉันเขียนคำตอบนี้ฉันไม่พบอะไรเลย คำตอบอื่น ๆ ดูเหมือนว่าจะยืนยัน: stackoverflow.com/a/33622102/253883
Julien Guertault

1
"และคุณควรตระหนักถึงสิ่งนี้ก่อนที่คุณจะเริ่มนำไปใช้อย่างมีความสุขโดยใช้ XmlDocument เพื่อค้นพบในภายหลังว่าคุณต้องเปลี่ยนแปลงทุกอย่าง" คาดเดาสิ่งที่ฉันเพิ่งทำ :)
Paul

36

XmlDocumentเหมาะสำหรับนักพัฒนาที่คุ้นเคยกับโมเดลวัตถุ XML DOM มันผ่านไประยะหนึ่งแล้วและมากหรือน้อยนั้นสอดคล้องกับมาตรฐาน W3C รองรับการนำทางด้วยตนเองเช่นเดียวกับการXPathเลือกโหนด

XDocumentเปิดใช้งานฟีเจอร์ LINQ ไปยัง XML ใน. NET 3.5 มันทำให้การใช้งานหนักIEnumerable<>และสามารถทำงานกับ C # ได้โดยตรง

เอกสารทั้งสองรุ่นกำหนดให้คุณโหลดเอกสารทั้งหมดลงในหน่วยความจำ (ไม่เหมือนกับXmlReaderตัวอย่าง)


3
ฉันคิดว่าคุณหมายถึง "และสามารถทำงานกับ VB.net ได้โดยตรง" เนื่องจาก VB รองรับการสร้างองค์ประกอบโดยตรงที่ C # ยังคงต้องการรหัส
Brain2000

24

XDocumentมาจาก LINQ ถึง XML API และXmlDocumentเป็นAPI ของ DOM-style มาตรฐานสำหรับ XML ถ้าคุณรู้ว่า DOM ดีและไม่ต้องการที่จะเรียนรู้ LINQ กับ XML XmlDocumentไปกับ หากคุณยังใหม่กับทั้งคู่ลองดูหน้านี้เพื่อเปรียบเทียบทั้งสองและเลือกอันที่คุณชอบดูดีกว่า

ฉันเพิ่งเริ่มใช้ LINQ กับ XML และฉันชอบวิธีที่คุณสร้างเอกสาร XML โดยใช้โครงสร้างการทำงาน มันดีมาก. DOM เป็น clunky ในการเปรียบเทียบ


23

ตามที่กล่าวไว้ที่อื่นไม่ต้องสงสัย Linq เป็น Xml ทำให้การสร้างและการเปลี่ยนแปลงของเอกสาร xml เป็นเรื่องง่ายเมื่อเทียบกับXmlDocumentและXNamespace ns + "elementName"ไวยากรณ์ทำให้การอ่านที่น่าพอใจเมื่อจัดการกับเนมสเปซ

สิ่งหนึ่งที่ควรค่าแก่การกล่าวถึงxslและxpathตายอย่างมากที่ควรทราบก็คือมันเป็นไปได้ที่จะยังคงสามารถใช้งานxpath 1.0นิพจน์โดยพลการบน Linq 2 Xml XNodesโดยรวมถึง:

using System.Xml.XPath;

จากนั้นเราสามารถนำทางและฉายข้อมูลโดยใช้xpathวิธีการต่อไปนี้:

ตัวอย่างเช่นกำหนดเอกสาร 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>

เราสามารถประเมิน:

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

นอกจากนี้โปรดทราบว่าXDocumentได้รับการสนับสนุนใน Xbox 360 และ Windows Phone OS 7.0 หากคุณกำหนดเป้าหมายพวกเขาพัฒนาหรือโยกย้ายจากXDocumentXmlDocument


-8

ฉันเชื่อว่ามันXDocumentทำให้เกิดการสร้างวัตถุมากขึ้น ฉันสงสัยว่าเมื่อคุณจัดการเอกสาร XML จำนวนมากXMLDocumentจะเร็วขึ้น

ที่เดียวที่เกิดขึ้นคือการจัดการข้อมูลสแกน เครื่องมือสแกนจำนวนมากแสดงผลข้อมูลในรูปแบบ XML (ด้วยเหตุผลที่ชัดเจน) XMLDocumentหากคุณมีการประมวลผลจำนวนมากของไฟล์ที่สแกนเหล่านี้ผมคิดว่าคุณจะมีประสิทธิภาพที่ดีขึ้นด้วย


11
ฉันคิดว่าคุณควรจะแสดงความคิดเห็นด้วยตัวเลขในครั้งต่อไปเนื่องจากฉันเชื่อว่าคุณอาจผิด ดูblogs.msdn.com/b/codejunkie/archive/2008/10/08/…
ไมค์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.