XDocument'i XmlDocument'e dönüştürme veya tersini yapma


189

Çok basit bir sorunum var. Bir XML dosyası oluşturmak için XDocument kullanın. Sonra bir XmlDocument sınıfı olarak geri dönmek istiyorum. Ve daha fazla düğüm eklemek için XDocument'e geri dönüştürmem gereken bir XmlDocument değişkeni var.

Peki, XML'i XDocument ve XmlDocument arasında dönüştürmek için en etkili yöntem nedir? (Dosyada geçici depolama alanı kullanmadan.)

Yanıtlar:


304

Dahili xDocument.CreateReader () ve bir XmlNodeReader'ı ileri geri dönüştürmek için kullanabilirsiniz.

Çalışmayı kolaylaştırmak için bunu bir Genişletme yöntemine koymak.

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

Kaynaklar:


4
ToXmlDocument yönteminde oluşturulan okuyucuyu elden çıkarma konusunda endişelenmenize gerek kalmaz mı?
CodeMonkey1313

5
ToXDocument () neden MoveToContent () çağrısı içeriyor? Bu, belge öğesinin önündeki herhangi bir içeriği, örneğin XML belgesinin üst kısmındaki yorum ve işleme talimatlarını atlayacağı gibi görünüyor.
redcalx

@locster, bildirimin XmlDocument(özellik olarak) ve XDocument(düğüm olarak ) arasında farklı işlenir . Beyanı korumak istiyorsanız, açık bir şekilde ele almanız gerekir (bkz. Blogs.msdn.com/b/ericwhite/archive/2010/03/05/… veya @ Dmitry'nin cevabı stackoverflow.com/a/8894680/2688 )
bdukes

Ne yazık ki bu Windows 10 UWP'de çalışmıyor. Eğer ilgilenen varsa, bu platform için çözümümü aşağıda paylaştım.
bc3tech

28

Benim için bu tek hat çözümü çok iyi çalışıyor

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

21
Bunu kullanmayın - bu doğru bir şekilde çalışmasına rağmen, tüm XML ağacını tek bir dizeye dönüştürdüğü ve daha sonra tekrar ayrıştırdığı için çok verimsizdir.
Lucero

3
Farklı yaklaşımların karşılaştırması için bu yazıyı görün blogs.msdn.microsoft.com/xmlteam/2009/03/31/…
Bernard Vander

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

Bu Uzantının kullanımı sadece böyle bir şey kullanılarak yapılır

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

13
Bunu kullanmayın - bu doğru bir şekilde çalışmasına rağmen, tüm XML ağacını tek bir dizeye dönüştürdüğü ve daha sonra tekrar ayrıştırdığı için çok verimsizdir.
Lucero

5

System.Xml.Linq.XDocument örneğini System.Xml.XmlDocument örneğine dönüştürmeniz gerekiyorsa, bu uzantı yöntemi sonuçta ortaya çıkan XmlDocument örneğindeki XML bildirimini kaybetmenize yardımcı olur :

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

Umarım yardımcı olur!


4

Bir XmlDocument için XmlReader'a bağlı bir XmlWriter'a XDocument yazmayı deneyebilirsiniz.

Kavramları düzgün bir şekilde anlarsam, doğrudan bir dönüşüm mümkün değildir (iç yapı XDocument ile farklı / basitleştirilmiştir). Ama sonra yanılıyor olabilirim ...



-1

Win 10 UWP uyumlu bir varyanta ihtiyacınız varsa:

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);
                }
            }
        }
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.