এক্সএমএলে কোনও বস্তুকে সিরিয়ালাইজ করুন


292

আমার উত্তরাধিকার সূত্রে একটি সি # ক্লাস রয়েছে। আমি অবজেক্টটি সাফল্যের সাথে "বিল্ট" করেছি। তবে আমাকে এক্সএমএলে অবজেক্টটি সিরিয়ালাইজ করতে হবে। এটি করার কোন সহজ উপায় আছে?

দেখে মনে হচ্ছে সিরিয়ালাইজেশনের জন্য ক্লাস স্থাপন করা হয়েছে, তবে এক্সএমএল উপস্থাপনা কীভাবে পাবেন তা সম্পর্কে আমি নিশ্চিত নই। আমার শ্রেণির সংজ্ঞাটি এরকম দেখাচ্ছে:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.domain.com/test")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.domain.com/test", IsNullable = false)]
public partial class MyObject
{
  ...
}

আমি যা করতে ভেবেছিলাম তা এখানে, কিন্তু এটি কার্যকর হয় না:

MyObject o = new MyObject();
// Set o properties
string xml = o.ToString();

আমি কীভাবে এই বিষয়টির এক্সএমএল উপস্থাপনা পেতে পারি?



1
এটি অর্জনের জন্য আমি একটি সাধারণ গ্রন্থাগার তৈরি করেছি: github.com/aishwaryashiva/SaveXML
শিব

উত্তর:


509

এক্সএমএল সিরিয়ালাইজেশনের জন্য আপনাকে এক্সএমএলসিরাইজার ব্যবহার করতে হবে। নীচে একটি নমুনা স্নিপেট রয়েছে।

 XmlSerializer xsSubmit = new XmlSerializer(typeof(MyObject));
 var subReq = new MyObject();
 var xml = "";

 using(var sww = new StringWriter())
 {
     using(XmlWriter writer = XmlWriter.Create(sww))
     {
         xsSubmit.Serialize(writer, subReq);
         xml = sww.ToString(); // Your XML
     }
 }

10
লাইনটি ছাড়াই নিখুঁতভাবে কাজ করার জন্য বলে মনে হচ্ছেXmlWriter writer = XmlWriter.Create(sww);
পল হান্ট

15
সিরিয়ালাইজড অবজেক্টটি ফর্ম্যাট করতে হবে: এর XmlTextWriter writer = new XmlTextWriter(sww) { Formatting = Formatting.Indented };পরিবর্তেXmlWriter writer = XmlWriter.Create(sww);
টোনো নাম

4
যেহেতু XmlWriterencapsulates আপনার StringWriterউভয় নিষ্পত্তি করার প্রয়োজন নেই (প্রথমে ব্যবহারের রিন্ডন্ড্যান্ট হয়), তাই না? আমি ধরে নিচ্ছি যে XmlWriterএটি নিষ্পত্তি করার যত্ন নিয়েছে ...
টলেস

4
@ ট্যালসগুলি XmlWriterএনক্যাপসুলেট করছে না StringWriter, এটি আপনার পাস-ইন ব্যবহার করছে StringWriterএবং এটি নিষ্পত্তি করার কোনও প্রত্যাশা / দায়িত্ব নেই। আরও StringWriterবাইরে XmlWriterএর সুযোগ, আপনি কি এখনও চাইতে পারেন যখন এটি XmlWriterবিন্যস্ত, এটা জন্য দরিদ্র আচরণ কেমন হওয়া উচিৎ XmlWriterআপনার মীমাংসা করা StringWriter। একটি সাধারণ নিয়ম হিসাবে, আপনি যদি এমন কিছু ঘোষণা করেন যা নিষ্পত্তি করার প্রয়োজন হয় তবে তা নিষ্পত্তি করার জন্য আপনি দায়বদ্ধ। এবং এই নিয়মের অন্তর্নিহিত, যে কোনও কিছু আপনি নিজেকে ঘোষণা করবেন না এমনটি আপনার নিষ্পত্তি করা উচিত নয়। সুতরাং উভয় usings প্রয়োজনীয়।
আরকাইন 55

3
System.XML.Serialization ব্যবহার করে; System.IO ব্যবহার করে; System.XML ব্যবহার করে;
টিমোথি

122

আমি নীচের মত একটি রেফ ভেরিয়েবল ব্যবহার না করে একটি স্ট্রিং ফিরিয়ে দিতে আমার পরিবর্তন করেছি।

public static string Serialize<T>(this T value)
{
    if (value == null)
    {
        return string.Empty;
    }
    try
    {
        var xmlserializer = new XmlSerializer(typeof(T));
        var stringWriter = new StringWriter();
        using (var writer = XmlWriter.Create(stringWriter))
        {
            xmlserializer.Serialize(writer, value);
            return stringWriter.ToString();
        }
    }
    catch (Exception ex)
    {
        throw new Exception("An error occurred", ex);
    }
}

এর ব্যবহার এই রকম হবে:

var xmlString = obj.Serialize();

8
খুব সুন্দর সমাধান, আপনি যেভাবে এক্সটেনশন পদ্ধতি হিসাবে এটি প্রয়োগ করেছেন তা আমি পছন্দ করি
স্পাইরোস

57
আমি এখানে একটি পরামর্শ দিচ্ছি: চেষ্টাটি সরিয়ে দিন ... ব্লক ধরুন। এটি আপনাকে কোনও সুবিধা দেয় না এবং কেবল যে ত্রুটি নিক্ষেপ করা হচ্ছে তা কেবল বিস্মৃত করে।
জ্যামাইক্যাকগুলি

7
আপনারও কি স্ট্রিং রাইটারে ব্যবহারের দরকার নেই? যেমন: (var স্ট্রিং রাইটার = নতুন স্ট্রিং রাইটার ()) ব্যবহার করে
স্টিভেন কুইক

3
@ জ্যামাইকেস না! আপনি যখন Exceptionসেখানে কোনও নতুন নিক্ষেপ করবেন , আপনি "সিরিয়ালাইজ <>" পদ্ধতিটি দিয়ে স্ট্যাকট্রেস প্রসারিত করেছেন।
ব্যবহারকারী 11909

1
@ ইউজার 2190035 অবশ্যই যদি এটি এক্সটেনশন পদ্ধতিতে ভেঙে ফেলা হয় তবে স্ট্যাকের ট্রেসটি সেখানে শুরু হবে? "স্ট্যাক ট্রেস বাড়ানো" চেষ্টা করে কি অপ্রয়োজনীয় বলে মনে হচ্ছে?
লেআরআই

42

System.XML নেমস্পেসটি ব্যবহার করে একটি এক্সএমএল সেভ ফাংশন যুক্ত করতে নিম্নলিখিত ফাংশনটি যে কোনও বস্তুতে অনুলিপি করা যায়।

/// <summary>
/// Saves to an xml file
/// </summary>
/// <param name="FileName">File path of the new xml file</param>
public void Save(string FileName)
{
    using (var writer = new System.IO.StreamWriter(FileName))
    {
        var serializer = new XmlSerializer(this.GetType());
        serializer.Serialize(writer, this);
        writer.Flush();
    }
}

সংরক্ষিত ফাইল থেকে অবজেক্টটি তৈরি করতে, নিম্নলিখিত ফাংশনটি যুক্ত করুন এবং [অবজেক্টটাইপ] প্রতিস্থাপন করুন অবজেক্ট টাইপের সাথে তৈরি করতে।

/// <summary>
/// Load an object from an xml file
/// </summary>
/// <param name="FileName">Xml file name</param>
/// <returns>The object created from the xml file</returns>
public static [ObjectType] Load(string FileName)
{
    using (var stream = System.IO.File.OpenRead(FileName))
    {
        var serializer = new XmlSerializer(typeof([ObjectType]));
        return serializer.Deserialize(stream) as [ObjectType];
    }
}

writer.Flush()একটি usingব্লকের মধ্যে অপ্রয়োজনীয় - writerএর Dispose()পদ্ধতিটি এটি আপনার জন্য প্রবাহিত করবে।
বাজাজা

6
আমার অভিজ্ঞতা এটি সত্য নয়। বৃহত্তর ডেটা সহ, ব্যবহারের বিবৃতিটি বাফারটি সাফ করার আগে স্ট্রিমটিকে নিষ্পত্তি করবে। আমি 100% স্পষ্টভাবে ফ্লাশ কল করার পরামর্শ দিচ্ছি।
বেন গ্রিপকা

6
Writer.Flush () নিরর্থক নয়, এটি সেখানে থাকা আবশ্যক। ফ্লাশ ব্যতীত, এটি ঘটতে পারে যে তথ্যের অংশটি এখনও স্ট্রিমাইটার বাফারে রয়েছে এবং ফাইলটি নিষ্পত্তি হয়ে যায় এবং কিছু ডেটা অনুপস্থিত থাকে।
টমাস কুবেস

আমি আপনার কোডটি খুব পছন্দ করি: সংক্ষিপ্ত এবং ঝরঝরে। আমার সমস্যাটি বিভিন্ন ক্লাসে বার বার ফাংশনগুলি অনুলিপি করার সাথে: এটি কোডটি নকল নয়? অন্য উত্তরগুলি টেমপ্লেট এক্সটেনশন পদ্ধতিগুলির সাথে জেনেরিক লাইব্রেরিটির পরামর্শ দেয় যে আমি আলিঙ্গন করব। আপনি কি মনে করেন?
মাইকেল জি

33

সম্প্রসারণ শ্রেণি:

using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace MyProj.Extensions
{
    public static class XmlExtension
    {
        public static string Serialize<T>(this T value)
        {
            if (value == null) return string.Empty;

            var xmlSerializer = new XmlSerializer(typeof(T));

            using (var stringWriter = new StringWriter())
            {
                using (var xmlWriter = XmlWriter.Create(stringWriter,new XmlWriterSettings{Indent = true}))
                {
                    xmlSerializer.Serialize(xmlWriter, value);
                    return stringWriter.ToString();
                }    
            }
        }
    }
}

ব্যবহার:

Foo foo = new Foo{MyProperty="I have been serialized"};

string xml = foo.Serialize();

আপনি যে ফাইলটি এটিতে ব্যবহার করতে চান তাতে আপনার এক্সটেনশন পদ্ধতিটি ধারণ করে এমন নেমস্পেসটি কেবল উল্লেখ করুন এবং এটি কাজ করবে (আমার উদাহরণে এটি হবে: using MyProj.Extensions; :)

নোট করুন যে আপনি যদি এক্সটেনশন পদ্ধতিটি কেবলমাত্র একটি নির্দিষ্ট শ্রেণীর (যেমন,। Foo) নির্দিষ্ট করতে চান তবে আপনি এক্সটেনশন পদ্ধতিতে Tযুক্তিটি প্রতিস্থাপন করতে পারেন , যেমন।

public static string Serialize(this Foo value){...}


31

আপনি কোনও বস্তু থেকে ক্রমিক এক্সএমএল পেতে নীচের মতো ফাংশনটি ব্যবহার করতে পারেন।

public static bool Serialize<T>(T value, ref string serializeXml)
{
    if (value == null)
    {
        return false;
    }
    try
    {
        XmlSerializer xmlserializer = new XmlSerializer(typeof(T));
        StringWriter stringWriter = new StringWriter();
        XmlWriter writer = XmlWriter.Create(stringWriter);

        xmlserializer.Serialize(writer, value);

        serializeXml = stringWriter.ToString();

        writer.Close();
        return true;
    }
    catch (Exception ex)
    {
        return false;
    }
}

আপনি ক্লায়েন্টের কাছ থেকে এটি কল করতে পারেন।


21

কোনও বস্তুকে সিরিয়ালাইজ করতে, করুন:

 using (StreamWriter myWriter = new StreamWriter(path, false))
 {
     XmlSerializer mySerializer = new XmlSerializer(typeof(your_object_type));
     mySerializer.Serialize(myWriter, objectToSerialize);
 }

এটিও মনে রাখবেন যে এক্সএমএলসিরালাইজার কাজ করার জন্য আপনার প্যারামিটারলেস কনস্ট্রাক্টর দরকার।


2
এটি আমাকে বাদাম চালাচ্ছিল। কেন এটি সর্বদা ফাঁকা ছিল তা আমি বুঝতে পারি না। তখন বুঝতে পারলাম আপনার উত্তরটি পড়ার পরে আমার কাছে কোনও কনস্ট্রাক্টর নেই যার কোনও পরামিতি নেই। ধন্যবাদ.
অ্যান্ডি

19

আমি বেন গ্রিপকার অনুলিপি দিয়ে শুরু করব:

public void Save(string FileName)
{
    using (var writer = new System.IO.StreamWriter(FileName))
    {
        var serializer = new XmlSerializer(this.GetType());
        serializer.Serialize(writer, this);
        writer.Flush();
    }
}

আমি এই কোডটি আগে ব্যবহার করেছি। কিন্তু বাস্তবতা দেখায় যে এই সমাধানটি কিছুটা সমস্যাযুক্ত। সাধারণত বেশিরভাগ প্রোগ্রামার সেভ করে সেটিং সেট করে সিরিয়ালাইজ করে এবং লোডে সেটিংসকে ডিসরিয়ালাইজ করে। এটি একটি আশাবাদী দৃশ্য। সিরিয়ালাইজেশন ব্যর্থ হয়ে গেলে কোনও কারণে, ফাইলটি আংশিকভাবে লিখিত হয়, এক্সএমএল ফাইলটি সম্পূর্ণ হয় না এবং এটি অবৈধ। ফলস্বরূপ এক্সএমএল deserialization কাজ করে না এবং আপনার অ্যাপ্লিকেশন শুরুতে ক্রাশ হতে পারে। যদি ফাইলটি বিশাল না হয় MemoryStreamতবে আমি প্রথমে প্রবাহটি ফাইলটিতে লেখার জন্য প্রথমে সিরিয়ালাইজ করার পরামর্শ দিই । কিছু জটিল কাস্টম সিরিয়ালাইজেশন থাকলে এই কেসটি বিশেষত গুরুত্বপূর্ণ। আপনি সব ক্ষেত্রে পরীক্ষা করতে পারবেন না।

public void Save(string fileName)
{
    //first serialize the object to memory stream,
    //in case of exception, the original file is not corrupted
    using (MemoryStream ms = new MemoryStream())
    {
        var writer = new System.IO.StreamWriter(ms);    
        var serializer = new XmlSerializer(this.GetType());
        serializer.Serialize(writer, this);
        writer.Flush();

        //if the serialization succeed, rewrite the file.
        File.WriteAllBytes(fileName, ms.ToArray());
    }
}

রিয়েল ওয়ার্ল্ডের দৃশ্যে deserialization দুর্নীতিযুক্ত সিরিয়ালাইজেশন ফাইলের সাথে গণনা করা উচিত, এটি কখনও কখনও ঘটে। বেন গ্রিপকা সরবরাহিত লোড ফাংশনটি ভাল।

public static [ObjectType] Load(string fileName)
{
    using (var stream = System.IO.File.OpenRead(fileName))
    {
        var serializer = new XmlSerializer(typeof([ObjectType]));
        return serializer.Deserialize(stream) as [ObjectType];        
    }    
}

এবং এটি কিছু পুনরুদ্ধারের দৃশ্যে আবৃত হতে পারে। এটি সেটিংস ফাইল বা অন্য ফাইলগুলির জন্য উপযুক্ত যা সমস্যা হলে মুছে ফেলা যায়।

public static [ObjectType] LoadWithRecovery(string fileName)
{
    try
    {
        return Load(fileName);
    }
    catch(Excetion)
    {
        File.Delete(fileName); //delete corrupted settings file
        return GetFactorySettings();
    }
}

কোনও ফাইলকে মেমরি স্ট্রিম লেখার সময় প্রক্রিয়াটি বাধাগ্রস্থ হওয়া কি সম্ভব নয়, উদাহরণস্বরূপ কোনও পাওয়ার শাটডাউন দ্বারা?
জন স্মিথ

1
হ্যা এটা সম্ভব. আপনি কোনও অস্থায়ী ফাইলে সেটিংস লিখে এড়াতে পারেন এবং তারপরে মূলটি প্রতিস্থাপন করতে পারেন।
টমাস কুবেস

18

উপরে বর্ণিত সমস্ত উত্তর সঠিক। এটি কেবল সহজতম সংস্করণ:

private string Serialize(Object o)
{
    using (var writer = new StringWriter())
    {
        new XmlSerializer(o.GetType()).Serialize(writer, o);
        return writer.ToString();
    }
}

9

এটি ToStringক্লাসের পদ্ধতিটি কল করার চেয়ে কিছুটা জটিল , তবে বেশি নয়।

এখানে কোনও সাধারণ ড্রপ-ইন ফাংশন আপনি যে কোনও ধরণের অবজেক্টকে সিরিয়ালাইজ করতে ব্যবহার করতে পারেন। এটি সিরিয়ালযুক্ত এক্সএমএল বিষয়বস্তুযুক্ত একটি স্ট্রিং প্রদান করে:

public string SerializeObject(object obj)
{
    System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
    System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());
    using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) {
        serializer.Serialize(ms, obj);
        ms.Position = 0;
        xmlDoc.Load(ms);
        return xmlDoc.InnerXml;
    }
}


4
    string FilePath = ConfigurationReader.FileLocation;   //Getting path value from web.config            
    XmlSerializer serializer = new XmlSerializer(typeof(Devices)); //typeof(object)
            MemoryStream memStream = new MemoryStream();
            serializer.Serialize(memStream, lstDevices);//lstdevices : I take result as a list.
            FileStream file = new FileStream(folderName + "\\Data.xml", FileMode.Create, FileAccess.ReadWrite); //foldername:Specify the path to store the xml file
            memStream.WriteTo(file);
            file.Close();

আপনি পছন্দসই স্থানে এক্সএমএল ফাইল হিসাবে ফলাফল তৈরি এবং সঞ্চয় করতে পারেন।


4

আমার কাজের কোড রিটার্নস UTF8 XML খালি নামস্থান সক্ষম করুন।

// override StringWriter
public class Utf8StringWriter : StringWriter
{
    public override Encoding Encoding => Encoding.UTF8;
}

private string GenerateXmlResponse(Object obj)
{    
    Type t = obj.GetType();

    var xml = "";

    using (StringWriter sww = new Utf8StringWriter())
    {
        using (XmlWriter writer = XmlWriter.Create(sww))
        {
            var ns = new XmlSerializerNamespaces();
            // add empty namespace
            ns.Add("", "");
            XmlSerializer xsSubmit = new XmlSerializer(t);
            xsSubmit.Serialize(writer, obj, ns);
            xml = sww.ToString(); // Your XML
        }
    }
    return xml;
}

উদাহরণ প্রতিক্রিয়া ইয়ানডেক্স এপি পেমেন্ট অ্যাভিসো ইউআরএল প্রদান করে:

<?xml version="1.0" encoding="utf-8"?><paymentAvisoResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" performedDatetime="2017-09-01T16:22:08.9747654+07:00" code="0" shopId="54321" invoiceId="12345" orderSumAmount="10643" />

4

আমার কাছে সিএমএল ব্যবহার করে কোনও বস্তুটি এক্সএমএলকে সিরিয়ালাইজ করার সহজ উপায় রয়েছে, এটি দুর্দান্ত কাজ করে এবং এটি অত্যন্ত পুনরায় ব্যবহারযোগ্য। আমি জানি এটি একটি পুরানো থ্রেড, তবে আমি এটি পোস্ট করতে চেয়েছিলাম কারণ কেউ এটিকে তাদের পক্ষে সহায়ক হতে পারে।

এখানে আমি পদ্ধতিটি কল করি:

var objectToSerialize = new MyObject();
var xmlString = objectToSerialize.ToXmlString();

এখানে ক্লাসটি কাজ করে:

দ্রষ্টব্য: যেহেতু এগুলি এক্সটেনশন পদ্ধতি তাই এগুলি একটি স্ট্যাটিক শ্রেণিতে থাকা দরকার।

using System.IO;
using System.Xml.Serialization;

public static class XmlTools
{
    public static string ToXmlString<T>(this T input)
    {
        using (var writer = new StringWriter())
        {
            input.ToXml(writer);
            return writer.ToString();
        }
    }

    private static void ToXml<T>(this T objectToSerialize, StringWriter writer)
    {
        new XmlSerializer(typeof(T)).Serialize(writer, objectToSerialize);
    }
}

4

উপরের সমাধানগুলির উপর ভিত্তি করে, এখানে একটি এক্সটেনশান ক্লাস আসবে যা আপনি কোনও বস্তুকে সিরিয়ালাইজ করতে এবং ডিজিট্রাইজ করতে ব্যবহার করতে পারেন। অন্য কোনও এক্সএমএল বৈশিষ্ট্য আপনার উপর নির্ভর করে।

কেবল এটির মতো ব্যবহার করুন:

        string s = new MyObject().Serialize(); // to serialize into a string
        MyObject b = s.Deserialize<MyObject>();// deserialize from a string



internal static class Extensions
{
    public static T Deserialize<T>(this string value)
    {
        var xmlSerializer = new XmlSerializer(typeof(T));

        return (T)xmlSerializer.Deserialize(new StringReader(value));
    }

    public static string Serialize<T>(this T value)
    {
        if (value == null)
            return string.Empty;

        var xmlSerializer = new XmlSerializer(typeof(T));

        using (var stringWriter = new StringWriter())
        {
            using (var xmlWriter = XmlWriter.Create(stringWriter, new XmlWriterSettings { Indent = true }))
            {
                xmlSerializer.Serialize(xmlWriter, value);
                return stringWriter.ToString();
            }
        }
    }
}

2

অথবা আপনি এই পদ্ধতিটি আপনার অবজেক্টে যুক্ত করতে পারেন:

    public void Save(string filename)
    {
        var ser = new XmlSerializer(this.GetType());
        using (var stream = new FileStream(filename, FileMode.Create))
            ser.Serialize(stream, this);
    }

1

এখানে একটি প্রাথমিক কোড যা সি # অবজেক্টগুলিকে এক্সএমএল করে ক্রমিকায়িত করতে সহায়তা করবে:

using System;

public class clsPerson
{
  public  string FirstName;
  public  string MI;
  public  string LastName;
}

class class1
{ 
   static void Main(string[] args)
   {
      clsPerson p=new clsPerson();
      p.FirstName = "Jeff";
      p.MI = "A";
      p.LastName = "Price";
      System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(p.GetType());
      x.Serialize(Console.Out, p);
      Console.WriteLine();
      Console.ReadLine();
   }
}    

6

0
public string ObjectToXML(object input)
{
    try
    {
        var stringwriter = new System.IO.StringWriter();
        var serializer = new XmlSerializer(input.GetType());
        serializer.Serialize(stringwriter, input);
        return stringwriter.ToString();
    }
    catch (Exception ex)
    {
        if (ex.InnerException != null)
            ex = ex.InnerException;

        return "Could not convert: " + ex.Message;
    }
}

//Usage
var res = ObjectToXML(obj)

আপনার নিম্নলিখিত ক্লাস ব্যবহার করা প্রয়োজন:

using System.IO;
using System.Xml;
using System.Xml.Serialization;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.