Converting XDocument to XmlDocument and vice versa
Asked Answered
U

6

202

It's a very simple problem that I have. I use XDocument to generate an XML file. I then want to return it as a XmlDocument class. And I have an XmlDocument variable which I need to convert back to XDocument to append more nodes.

So, what is the most efficient method to convert XML between XDocument and XmlDocument? (Without using any temporary storage in a file.)

Unclad answered 2/10, 2009 at 9:29 Comment(0)
T
330

You can use the built in xDocument.CreateReader() and an XmlNodeReader to convert back and forth.

Putting that into an Extension method to make it easier to work with.

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

Sources:

Touraine answered 2/10, 2009 at 11:57 Comment(4)
wouldn't you have to worry about disposing the reader that was created in the ToXmlDocument method?Bilestone
Why does ToXDocument() contain call to MoveToContent()? This looks liek it would skip over any content ahead of the document element, e.g. any comments and processing instructions at the top of the XML doc.Bodice
@locster the declaration is handled differently between XmlDocument (as a property) and XDocument (as a node). If you want to preserve the declaration, you'll need to handle it explicitly (see blogs.msdn.com/b/ericwhite/archive/2010/03/05/… or @Dmitry's answer https://mcmap.net/q/127178/-converting-xdocument-to-xmldocument-and-vice-versa)Consciencestricken
Unfortunately this doesn't work in Windows 10 UWP. I've posted my solution for that platform below if anybody's interested.Viv
S
31

For me this single line solution works very well

XDocument y = XDocument.Parse(pXmldoc.OuterXml); // where pXmldoc is of type XMLDocument
Suggestible answered 21/2, 2012 at 11:8 Comment(3)
Don't use this - while this does work correctly, it is very inefficient since it converts the whole XML tree to a single string and parses that again afterwards.Caffey
See this post for a benchmark of the different approaches blogs.msdn.microsoft.com/xmlteam/2009/03/31/…Aiaia
I'm working on a utility, not production code. Simple and easy is more important to me than performance.Dallis
D
10

If you need to convert the instance of System.Xml.Linq.XDocument into the instance of the System.Xml.XmlDocument this extension method will help you to do not lose the XML declaration in the resulting XmlDocument instance:

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

Hope that helps!

Danie answered 17/1, 2012 at 12:34 Comment(0)
I
4

You could try writing the XDocument to an XmlWriter piped to an XmlReader for an XmlDocument.

If I understand the concepts properly, a direct conversion is not possible (the internal structure is different / simplified with XDocument). But then, I might be wrong...

Inositol answered 2/10, 2009 at 9:37 Comment(0)
A
4

There is a discussion on http://blogs.msdn.com/marcelolr/archive/2009/03/13/fast-way-to-convert-xmldocument-into-xdocument.aspx

It seems that reading an XDocument via an XmlNodeReader is the fastest method. See the blog for more details.

Aquilegia answered 8/3, 2010 at 12:25 Comment(0)
V
0

If you need a Win 10 UWP compatible variant:

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);
                }
            }
        }
    }
Viv answered 18/8, 2015 at 14:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.