将XDocument转换为XmlDocument,反之亦然


189

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

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

Answers:


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

5
为什么ToXDocument()包含对MoveToContent()的调用?看起来它很可能会跳过文档元素之前的所有内容,例如XML文档顶部的所有注释和处理指令。
redcalx 2012年

@locster在XmlDocument(作为属性)和XDocument(作为节点)之间对声明的处理不同。如果要保留声明,则需要显式处理它(请参阅blogs.msdn.com/b/ericwhite/archive/2010/03/05/…或@Dmi​​try的答案stackoverflow.com/a/8894680/2688
bdukes

不幸的是,这在Windows 10 UWP中不起作用。如果有人感兴趣,我已经在下面发布了该平台的解决方案。
bc3tech


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 2014年

5

如果您需要将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写入通过XmlReader传递给XmlDocument的XmlWriter。

如果我正确理解这些概念,则无法进行直接转换(内部结构与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);
                }
            }
        }
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.