将 XDocument 转换为 XmlDocument,反之亦然

Posted

技术标签:

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

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

那么,在 XDocument 和 XmlDocument 之间转换 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);
            
        
    

来源:

http://msdn.microsoft.com/en-us/library/bb356384.aspx http://geekswithblogs.net/aspringer/archive/2009/07/01/xdocument-extension.aspx

【讨论】:

您不必担心处理在 ToXmlDocument 方法中创建的阅读器吗? 为什么 ToXDocument() 包含对 MoveToContent() 的调用?这看起来很可能会跳过文档元素之前的任何内容,例如XML 文档顶部的任何 cmets 和处理指令。 @locster 声明在XmlDocument(作为属性)和XDocument(作为节点)之间的处理方式不同。如果您想保留声明,则需要明确处理它(参见blogs.msdn.com/b/ericwhite/archive/2010/03/05/… 或@Dmi​​try 的回答***.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);
                
            
        
    

【讨论】:

以上是关于将 XDocument 转换为 XmlDocument,反之亦然的主要内容,如果未能解决你的问题,请参考以下文章

如何将 XElement 转换为 XDocument

将 XPath 与 XDocument 一起使用时忽略 CData

XDocument 不会解析 html 实体(例如 ),但 XmlDocument 会

有没有办法将默认命名空间设置为从 XDocument 查询?

将 XmlNode 转换为 XNode?

将 HTML 5 文档类型添加到 XDocument (.NET)