การแปลง XDocument เป็น XmlDocument และในทางกลับกัน


189

มันเป็นปัญหาง่ายๆที่ฉันมี ฉันใช้ XDocument เพื่อสร้างไฟล์ XML ฉันต้องการคืนค่าเป็นคลาส XmlDocument และฉันมีตัวแปร XmlDocument ซึ่งฉันต้องแปลงกลับเป็น XDocument เพื่อผนวกโหนดเพิ่มเติม

ดังนั้นวิธีที่มีประสิทธิภาพมากที่สุดในการแปลง XML ระหว่าง XDocument และ XmlDocument คืออะไร? (ไม่ใช้ที่เก็บข้อมูลชั่วคราวในไฟล์)

คำตอบ:


304

คุณสามารถใช้บิวด์อิน xDocument.CreateReader () และ XmlNodeReader เพื่อแปลงไปมา

การใส่สิ่งนั้นลงในวิธีการส่วนขยายเพื่อให้ทำงานได้ง่ายขึ้น

using System;
using System.Xml;
using System.Xml.Linq;

namespace MyTest
{
    internal class Program
    {
        private static void Main(string[] args)
        {

            var xmlDocument = new XmlDocument();
            xmlDocument.LoadXml("<Root><Child>Test</Child></Root>");

            var xDocument = xmlDocument.ToXDocument();
            var newXmlDocument = xDocument.ToXmlDocument();
            Console.ReadLine();
        }
    }

    public static class DocumentExtensions
    {
        public static XmlDocument ToXmlDocument(this XDocument xDocument)
        {
            var xmlDocument = new XmlDocument();
            using(var xmlReader = xDocument.CreateReader())
            {
                xmlDocument.Load(xmlReader);
            }
            return xmlDocument;
        }

        public static XDocument ToXDocument(this XmlDocument xmlDocument)
        {
            using (var nodeReader = new XmlNodeReader(xmlDocument))
            {
                nodeReader.MoveToContent();
                return XDocument.Load(nodeReader);
            }
        }
    }
}

แหล่งที่มา:


4
คุณไม่ต้องกังวลกับการกำจัดผู้อ่านที่สร้างขึ้นในวิธีการ ToXmlDocument?
CodeMonkey1313

5
เหตุใด ToXDocument () จึงมีการเรียกไปที่ MoveToContent () ดูเหมือนจะเป็นการข้ามเนื้อหาที่อยู่ด้านหน้าขององค์ประกอบเอกสารเช่นความคิดเห็นและคำแนะนำการประมวลผลที่ด้านบนของเอกสาร XML
redcalx

@locster การประกาศถูกจัดการแตกต่างกันระหว่างXmlDocument(เป็นคุณสมบัติ) และXDocument(เป็นโหนด) หากคุณต้องการรักษาการประกาศคุณจะต้องจัดการกับมันอย่างชัดเจน (ดูblogs.msdn.com/b/ericwhite/archive/2010/03/05/…หรือ @ Dmitry ของคำตอบstackoverflow.com/a/8894680/2688 )
bdukes

น่าเสียดายที่นี่ไม่สามารถใช้งานได้ใน Windows 10 UWP ฉันโพสต์โซลูชันของฉันสำหรับแพลตฟอร์มนั้นด้านล่างหากใครสนใจ
bc3tech

28

สำหรับฉันโซลูชันบรรทัดเดียวนี้ทำงานได้ดีมาก

XDocument y = XDocument.Parse(pXmldoc.OuterXml); // where pXmldoc is of type XMLDocument

21
อย่าใช้สิ่งนี้ - ในขณะที่มันทำงานได้อย่างถูกต้องมันไม่มีประสิทธิภาพมากเนื่องจากมันจะแปลงทรี XML ทั้งหมดเป็นสตริงเดี่ยวและแยกวิเคราะห์อีกครั้งหลังจากนั้น
Lucero

3
ดูโพสต์นี้สำหรับมาตรฐานของบล็อก
Bernard Vander Beken

7
using System.Xml;
using System.Xml.Linq;

   #region Extention Method
    public static XElement ToXElement(this XmlElement element)
    {
        return XElement.Parse(element.OuterXml);
    }

    public static XmlElement ToXmlElement(this XElement element)
    {
        var doc = new XmlDocument();
        doc.LoadXml(element.ToString());
        return doc.DocumentElement;            
    }
    #endregion

การใช้งานส่วนขยายนี้ทำได้ง่ายกว่าการใช้สิ่งนี้

System.Xml.XmlElement systemXml = (new XElement("nothing")).ToXmlElement();
System.Xml.Linq.XElement linqXml = systemXml.ToXElement();

13
อย่าใช้สิ่งนี้ - ในขณะที่มันทำงานได้อย่างถูกต้องมันไม่มีประสิทธิภาพมากเนื่องจากมันจะแปลงทรี XML ทั้งหมดเป็นสตริงเดี่ยวและแยกวิเคราะห์อีกครั้งหลังจากนั้น
Lucero

5

หากคุณต้องการแปลงอินสแตนซ์ของ System.Xml.Linq.XDocument เป็นอินสแตนซ์ของ System.Xml.XmlDocument วิธีการขยายนี้จะช่วยให้คุณไม่สูญเสียการประกาศ XMLในอินสแตนซ์ XmlDocument ที่เป็นผลลัพธ์:

using System.Xml; 
using System.Xml.Linq;

namespace www.dimaka.com
{ 
    internal static class LinqHelper 
    { 
        public static XmlDocument ToXmlDocument(this XDocument xDocument) 
        { 
            var xmlDocument = new XmlDocument(); 
            using (var reader = xDocument.CreateReader()) 
            { 
                xmlDocument.Load(reader); 
            }

            var xDeclaration = xDocument.Declaration; 
            if (xDeclaration != null) 
            { 
                var xmlDeclaration = xmlDocument.CreateXmlDeclaration( 
                    xDeclaration.Version, 
                    xDeclaration.Encoding, 
                    xDeclaration.Standalone);

                xmlDocument.InsertBefore(xmlDeclaration, xmlDocument.FirstChild); 
            }

            return xmlDocument; 
        } 
    } 
}

หวังว่าจะช่วย!


4

คุณสามารถลองเขียน XDocument ไปยัง XmlWriter ไปป์ที่ XmlReader สำหรับ XmlDocument

ถ้าฉันเข้าใจแนวคิดอย่างถูกต้องจะไม่สามารถทำการแปลงโดยตรงได้ (โครงสร้างภายในนั้นแตกต่าง / ทำให้เข้าใจได้ง่ายขึ้นด้วย XDocument) แต่แล้วฉันอาจผิด ...



-1

หากคุณต้องการตัวแปรที่เข้ากันได้กับ Win 10 UWP:

using DomXmlDocument = Windows.Data.Xml.Dom.XmlDocument;

    public static class DocumentExtensions
    {
        public static XmlDocument ToXmlDocument(this XDocument xDocument)
        {
            var xmlDocument = new XmlDocument();
            using (var xmlReader = xDocument.CreateReader())
            {
                xmlDocument.Load(xmlReader);
            }
            return xmlDocument;
        }

        public static DomXmlDocument ToDomXmlDocument(this XDocument xDocument)
        {
            var xmlDocument = new DomXmlDocument();
            using (var xmlReader = xDocument.CreateReader())
            {
                xmlDocument.LoadXml(xmlReader.ReadOuterXml());
            }
            return xmlDocument;
        }

        public static XDocument ToXDocument(this XmlDocument xmlDocument)
        {
            using (var memStream = new MemoryStream())
            {
                using (var w = XmlWriter.Create(memStream))
                {
                    xmlDocument.WriteContentTo(w);
                }
                memStream.Seek(0, SeekOrigin.Begin);
                using (var r = XmlReader.Create(memStream))
                {
                    return XDocument.Load(r);
                }
            }
        }

        public static XDocument ToXDocument(this DomXmlDocument xmlDocument)
        {
            using (var memStream = new MemoryStream())
            {
                using (var w = XmlWriter.Create(memStream))
                {
                    w.WriteRaw(xmlDocument.GetXml());
                }
                memStream.Seek(0, SeekOrigin.Begin);
                using (var r = XmlReader.Create(memStream))
                {
                    return XDocument.Load(r);
                }
            }
        }
    }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.