Chuyển đổi XDocument sang XmlDocument và ngược lại


189

Đó là một vấn đề rất đơn giản mà tôi có. Tôi sử dụng XDocument để tạo tệp XML. Sau đó tôi muốn trả lại nó dưới dạng một lớp XmlDocument. Và tôi có một biến XmlDocument mà tôi cần chuyển đổi trở lại XDocument để nối thêm các nút.

Vậy, phương pháp hiệu quả nhất để chuyển đổi XML giữa XDocument và XmlDocument là gì? (Không sử dụng bất kỳ lưu trữ tạm thời nào trong một tệp.)

Câu trả lời:


304

Bạn có thể sử dụng xDocument.CreateReader () và XmlNodeReader tích hợp để chuyển đổi qua lại.

Đưa nó vào một phương thức mở rộng để làm việc dễ dàng hơn.

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

Nguồn:


4
bạn có phải lo lắng về việc loại bỏ trình đọc đã được tạo trong phương thức ToXmlDocument không?
CodeMonkey1313

5
Tại sao ToXDocument () chứa lệnh gọi MoveToContent ()? Điều này có vẻ như nó sẽ bỏ qua bất kỳ nội dung nào trước phần tử tài liệu, ví dụ như bất kỳ nhận xét và hướng dẫn xử lý nào ở đầu tài liệu XML.
redcalx

@locster khai báo được xử lý khác nhau giữa XmlDocument(như một thuộc tính) và XDocument(như một nút). Nếu bạn muốn giữ lại phần khai báo, bạn sẽ cần xử lý nó một cách rõ ràng (xem blog.msdn.com/b/ericwhite/archive/2010/03/05/ Thẻ hoặc câu trả lời của @ Dmitry stackoverflow.com/a/8894680/2688 )
bdukes

Thật không may, điều này không hoạt động trong Windows 10 UWP. Tôi đã đăng giải pháp của mình cho nền tảng đó bên dưới nếu có ai quan tâm.
bc3tech

28

Đối với tôi giải pháp dòng đơn này hoạt động rất tốt

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

21
Không sử dụng cái này - trong khi cái này hoạt động chính xác, nó rất kém hiệu quả vì nó chuyển đổi toàn bộ cây XML thành một chuỗi và phân tích cú pháp một lần nữa sau đó.
Lucero

3
Xem bài đăng này cho một chuẩn mực của sự khác nhau tiếp cận blogs.msdn.microsoft.com/xmlteam/2009/03/31/...
Bernard Vander Beken

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

Việc sử dụng phần mở rộng này được thực hiện đơn giản hơn bằng cách sử dụng một cái gì đó như thế này

System.Xml.XmlElement systemXml = (new XElement("nothing")).ToXmlElement();
System.Xml.Linq.XElement linqXml = systemXml.ToXElement();

13
Không sử dụng cái này - trong khi cái này hoạt động chính xác, nó rất kém hiệu quả vì nó chuyển đổi toàn bộ cây XML thành một chuỗi và phân tích cú pháp một lần nữa sau đó.
Lucero

5

Nếu bạn cần chuyển đổi thể hiện của System.Xml.Linq.XDocument thành thể hiện của System.Xml.XmlDocument, phương thức mở rộng này sẽ giúp bạn không bị mất khai báo XML trong trường hợp XmlDocument kết quả:

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

Mong rằng sẽ giúp!


4

Bạn có thể thử viết XDocument vào XmlWriter được chuyển sang XmlReader cho XmlDocument.

Nếu tôi hiểu đúng các khái niệm, không thể chuyển đổi trực tiếp (cấu trúc bên trong khác / đơn giản hóa với XDocument). Nhưng sau đó, tôi có thể sai ...



-1

Nếu bạn cần một biến thể tương thích 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);
                }
            }
        }
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.