Konversi XDocument ke XmlDocument dan sebaliknya

189

Ini masalah yang sangat sederhana yang saya miliki. Saya menggunakan XDocument untuk menghasilkan file XML. Saya kemudian ingin mengembalikannya sebagai kelas XmlDocument. Dan saya punya variabel XmlDocument yang perlu saya konversi kembali ke XDocument untuk menambahkan lebih banyak node.

Jadi, apa metode paling efisien untuk mengonversi XML antara XDocument dan XmlDocument? (Tanpa menggunakan penyimpanan sementara dalam file.)

Wim sepuluh Brink
sumber

Jawaban:

304

Anda dapat menggunakan xDocument.CreateReader () dan XmlNodeReader bawaan untuk mengonversi bolak-balik.

Masukkan itu ke dalam metode Extension untuk membuatnya lebih mudah untuk dikerjakan.

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

Sumber:

Mark Coleman
sumber
4
Anda tidak perlu khawatir membuang pembaca yang dibuat dalam metode ToXmlDocument?
CodeMonkey1313
5
Mengapa ToXDocument () berisi panggilan ke MoveToContent ()? Ini terlihat seperti itu akan melewati konten apa pun di depan elemen dokumen, misalnya komentar dan instruksi pemrosesan di bagian atas dokumen XML.
redcalx
@locster deklarasi ditangani secara berbeda antara XmlDocument(sebagai properti) dan XDocument(sebagai simpul). Jika Anda ingin mempertahankan deklarasi, Anda harus menanganinya secara eksplisit (lihat blogs.msdn.com/b/ericwhite/archive/2010/03/05/… atau @ Dmitry's jawaban stackoverflow.com/a/8894680/2688 )
bdukes
Sayangnya ini tidak berfungsi di Windows 10 UWP. Saya telah memposting solusi saya untuk platform di bawah ini jika ada yang tertarik.
bc3tech
28

Bagi saya solusi jalur tunggal ini bekerja dengan sangat baik

XDocument y = XDocument.Parse(pXmldoc.OuterXml); // where pXmldoc is of type XMLDocument
Abhi
sumber
21
Jangan gunakan ini - walaupun ini bekerja dengan benar, ini sangat tidak efisien karena mengubah seluruh pohon XML menjadi satu string dan mem-parsing itu lagi sesudahnya.
Lucero
3
Lihat posting ini untuk tolok ukur dari berbagai pendekatan blogs.msdn.microsoft.com/xmlteam/2009/03/31/…
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

Penggunaan Ekstensi ini dilakukan dengan hanya menggunakan sesuatu seperti ini

System.Xml.XmlElement systemXml = (new XElement("nothing")).ToXmlElement();
System.Xml.Linq.XElement linqXml = systemXml.ToXElement();
Robert Harvey
sumber
13
Jangan gunakan ini - walaupun ini bekerja dengan benar, ini sangat tidak efisien karena mengubah seluruh pohon XML menjadi satu string dan mem-parsing itu lagi sesudahnya.
Lucero
5

Jika Anda perlu mengonversi instance dari System.Xml.Linq.XDocument menjadi instance dari System.Xml.XmlDocument, metode ekstensi ini akan membantu Anda untuk tidak kehilangan deklarasi XML dalam instance XmlDocument yang dihasilkan:

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

Semoga itu bisa membantu!

Dmitry Pavlov
sumber
4

Anda bisa mencoba menulis XDocument ke XmlWriter yang disalurkan ke XmlReader untuk XmlDocument.

Jika saya memahami konsep-konsep dengan benar, konversi langsung tidak dimungkinkan (struktur internal berbeda / disederhanakan dengan XDocument). Tapi kemudian, saya mungkin salah ...

Daren Thomas
sumber
-1

Jika Anda memerlukan varian yang kompatibel dengan 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);
                }
            }
        }
    }
bc3tech
sumber