将XDocument转换为XmlDocument和反向转换

202

我有一个非常简单的问题。我使用XDocument生成XML文件,然后希望将其作为XmlDocument类返回。同时,我还需要将一个XmlDocument变量转换回XDocument以附加更多节点。

那么,最有效的XML转换方法是什么?(不使用任何临时存储文件。)

6个回答

330
你可以使用内置的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(作为节点)处理声明的方式不同。如果要保留声明,您需要显式处理它(请参见http://blogs.msdn.com/b/ericwhite/archive/2010/03/05/convert-xdocument-to-xmldocument-and-convert-xmldocument-to-xdocument.aspx 或@Dmitry的答案https://dev59.com/HHI_5IYBdhLWcg3wJPhu#8894680) - bdukes
不幸的是,这在Windows 10 UWP中无法工作。如果有人感兴趣,我已经在下面发布了该平台的解决方案。 - bc3tech

31

对我来说,这个单行解决方案非常有效

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

23
不要使用这个 - 虽然这样可以正确工作,但它非常低效,因为它将整个XML树转换为一个字符串,然后再进行解析。 - Lucero
3
请参考此篇文章,了解不同方法的基准测试结果:https://blogs.msdn.microsoft.com/xmlteam/2009/03/31/converting-from-xmldocument-to-xdocument/ - Bernard Vander Beken
2
我正在开发一个实用工具,而不是生产代码。对我来说,简单易用比性能更重要。 - todji

8

如果您需要将System.Xml.Linq.XDocument实例转换为System.Xml.XmlDocument实例,此扩展方法将帮助您在生成的XmlDocument实例中不丢失XML声明

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的内部结构与XmlDocument不同/简化了)。但是,我的理解也可能有误...

4

0
如果您需要兼容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);
                }
            }
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接