【问题标题】:Converting XDocument to XmlDocument and vice versa将 XDocument 转换为 XmlDocument,反之亦然
【发布时间】:2010-12-03 06:35:25
【问题描述】:

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

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

【问题讨论】:

    标签: c# xml linq-to-xml


    【解决方案1】:

    您可以使用内置的 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);
                }
            }
        }
    }
    

    来源:

    【讨论】:

    • 您不必担心处理在 ToXmlDocument 方法中创建的阅读器吗?
    • 为什么 ToXDocument() 包含对 MoveToContent() 的调用?这看起来很可能会跳过文档元素之前的任何内容,例如XML 文档顶部的任何 cmets 和处理指令。
    • @locster 声明在XmlDocument(作为属性)和XDocument(作为节点)之间的处理方式不同。如果您想保留声明,则需要明确处理它(参见blogs.msdn.com/b/ericwhite/archive/2010/03/05/… 或@Dmi​​try 的回答stackoverflow.com/a/8894680/2688
    • 不幸的是,这在 Windows 10 UWP 中不起作用。如果有人感兴趣,我已经在下面发布了该平台的解决方案。
    【解决方案2】:

    对我来说,这个单行解决方案效果很好

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

    【讨论】:

    • 不要使用它——虽然它可以正常工作,但效率非常低,因为它将整个 XML 树转换为单个字符串,然后再对其进行解析。
    • 查看这篇文章了解不同方法的基准blogs.msdn.microsoft.com/xmlteam/2009/03/31/…
    • 我正在开发一个实用程序,而不是生产代码。对我来说,简单易用比性能更重要。
    【解决方案3】:

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

    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 的 XmlWriter 以获得 XmlDocument。

      如果我正确理解这些概念,则无法进行直接转换(内部结构与 XDocument 不同/简化)。但是,我可能错了……

      【讨论】:

        【解决方案5】:

        http://blogs.msdn.com/marcelolr/archive/2009/03/13/fast-way-to-convert-xmldocument-into-xdocument.aspx有讨论

        似乎通过 XmlNodeReader 读取 XDocument 是最快的方法。有关更多详细信息,请参阅博客。

        【讨论】:

          【解决方案6】:

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

          【讨论】:

            猜你喜欢
            • 2011-10-08
            • 2013-03-15
            • 2019-09-19
            • 2013-12-29
            • 2011-09-22
            • 2012-05-14
            • 2020-03-01
            • 2011-09-03
            相关资源
            最近更新 更多