XDocumentをXmlDocumentに、またはその逆に変換する


189

それは私が持っている非常に単純な問題です。XDocumentを使用してXMLファイルを生成します。次に、それをXmlDocumentクラスとして返します。さらに、ノードを追加するためにXDocumentに変換して戻す必要があるXmlDocument変数があります。

では、XDocumentとXmlDocumentの間でXMLを変換する最も効率的な方法は何ですか?(ファイル内の一時ストレージを使用しない場合。)

回答:


304

組み込みのxDocument.CreateReader()とXmlNodeReaderを使用して、前後に変換できます。

これをExtensionメソッドに入れて、操作を簡単にします。

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(ノードとして)の間で異なる方法で処理されます。宣言を保持したい場合は、明示的に処理する必要があります(blogs.msdn.com/b/ericwhite/archive/2010/03/05/…または@Dmitryの回答stackoverflow.com/a/8894680/2688を参照)
bdukes 2015

残念ながら、これはWindows 10 UWPでは機能しません。誰かが興味を持っている場合は、そのプラットフォームの解決策を以下に掲載しました。
bc3tech 2015

28

私にとって、この単一行のソリューションは非常にうまく機能します

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

21
これは使用しないでください。これは正しく機能しますが、XMLツリー全体を単一の文字列に変換し、後で再度解析するため、非常に非効率的です。
Lucero、2014年

3
さまざまなアプローチのベンチマークについては、この投稿を参照してくださいblogs.msdn.microsoft.com/xmlteam/2009/03/31/…–
Bernard Vander

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ツリー全体を単一の文字列に変換し、後で再度解析するため、非常に非効率的です。
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

XmlDocumentのXmlReaderにパイプされたXmlWriterにXDocumentを書き込むこともできます。

概念を適切に理解している場合、直接変換することはできません(内部構造が異なります/ 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);
                }
            }
        }
    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.