web-dev-qa-db-ja.com

オブジェクトをXElementにシリアル化し、メモリ内で逆シリアル化します

オブジェクトをXMLにシリアル化したいのですが、ディスクに保存したくありません。 XElement変数に保持し(LINQで使用するため)、オブジェクトにデシリアライズして戻します。

これどうやってするの?

54
Arian

これらの2つの拡張メソッドを使用して、XElementとオブジェクト間でシリアル化と逆シリアル化を行うことができます。

public static XElement ToXElement<T>(this object obj)
{
    using (var memoryStream = new MemoryStream())
    {
        using (TextWriter streamWriter = new StreamWriter(memoryStream))
        {
            var xmlSerializer = new XmlSerializer(typeof(T));
            xmlSerializer.Serialize(streamWriter, obj);
            return XElement.Parse(Encoding.ASCII.GetString(memoryStream.ToArray()));
        }
    }
}

public static T FromXElement<T>(this XElement xElement)
{
        var xmlSerializer = new XmlSerializer(typeof(T));
        return (T)xmlSerializer.Deserialize(xElement.CreateReader());
}

[〜#〜] usage [〜#〜]

XElement element = myClass.ToXElement<MyClass>();
var newMyClass = element.FromXElement<MyClass>();
95
Abdul Munim

XMLSerialization を使用できます

XMLシリアル化は、オブジェクトのパブリックプロパティおよびフィールドを、ストレージまたはトランスポートのためにシリアル形式(この場合はXML)に変換するプロセスです。 デシリアライゼーションは、XML出力から元の状態のオブジェクトを再作成します。シリアル化は、オブジェクトの状態をストリームまたはバッファーに保存する方法と考えることができます。たとえば、ASP.NETはXmlSerializerクラスを使用してXML Webサービスメッセージをエンコードします

および XDocumentRepresents an XML documentこれを達成するために

   using System;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;


namespace ConsoleApplication5
{
  public class Person
  {
    public int Age { get; set; }
    public string Name { get; set; }
  }

  class Program
  {
    static void Main(string[] args)
    {

      XmlSerializer xs = new XmlSerializer(typeof(Person));

      Person p = new Person();
      p.Age = 35;
      p.Name = "Arnold";

      Console.WriteLine("\n Before serializing...\n");
      Console.WriteLine(string.Format("Age = {0} Name = {1}", p.Age,p.Name));

      XDocument d = new XDocument();
      using (XmlWriter xw = d.CreateWriter())
        xs.Serialize(xw, p);

      // you can use LINQ on Elm now

      XElement Elm = d.Root;

      Console.WriteLine("\n From XElement...\n");

      Elm.Elements().All(e => { Console.WriteLine(string.Format("element name {0} , element value {1}", e.Name, e.Value)); return true; });

      //deserialize back to object
      Person pDeserialized = xs.Deserialize((d.CreateReader())) as Person;

      Console.WriteLine("\n After deserializing...\n");
      Console.WriteLine(string.Format("Age = {0} Name = {1}", p.Age, p.Name));

      Console.ReadLine();

    }
  }


}

これが出力です enter image description here

25
Surjit Samra

(後期回答)

シリアライズ:

var doc = new XDocument();
var xmlSerializer = new XmlSerializer(typeof(MyClass));
using (var writer = doc.CreateWriter())
{
    xmlSerializer.Serialize(writer, obj);
}
// now you can use `doc`(XDocument) or `doc.Root` (XElement)

逆シリアル化:

MyClass obj; 
using(var reader = doc.CreateReader())
{
    obj = (MyClass)xmlSerializer.Deserialize(reader);
}
12
Eren Ersönmez

コード分​​析の問題のないToXelement、Abdul Munimと同じ答えですが、CAの問題を修正しました(CA1004を除く、これはこの場合解決できず、設計によるものです)

    public static XElement ToXElement<T>(this object value)
    {
        MemoryStream memoryStream = null;
        try
        {
            memoryStream = new MemoryStream();
            using (TextWriter streamWriter = new StreamWriter(memoryStream))
            {
                memoryStream = null;
                var xmlSerializer = new XmlSerializer(typeof(T));
                xmlSerializer.Serialize(streamWriter, value);
                return XElement.Parse(Encoding.ASCII.GetString(memoryStream.ToArray()));
            }
        }
        finally
        {
            if (memoryStream != null)
            {
                memoryStream.Dispose();
            }
        }
    }
0
Martijn