XML- কে তালিকা <টি> তে ডিসেরায়ালাইজ করা সম্ভব?


155

নিম্নলিখিত এক্সএমএল দেওয়া:

<?xml version="1.0"?>
<user_list>
   <user>
      <id>1</id>
      <name>Joe</name>
   </user>
   <user>
      <id>2</id>
      <name>John</name>
   </user>
</user_list>

এবং নিম্নলিখিত শ্রেণি:

public class User {
   [XmlElement("id")]
   public Int32 Id { get; set; }

   [XmlElement("name")]
   public String Name { get; set; }
}

XmlSerializerXML কে একটিতে ডিসরিয়ালাইজ করতে ব্যবহার করা কি সম্ভব List<User>? যদি তা হয় তবে আমার কী ধরণের অতিরিক্ত গুণাবলী ব্যবহার করতে হবে, বা XmlSerializerউদাহরণটি তৈরি করতে আমার আরও অতিরিক্ত পরামিতি ব্যবহার করতে হবে ?

একটি অ্যারে ( User[]) গ্রহণযোগ্য হবে, যদি কিছুটা কম পছন্দ হয়।

উত্তর:


137

আপনি তুচ্ছভাবে তালিকাটি encapsulate করতে পারেন :

using System;
using System.Collections.Generic;
using System.Xml.Serialization;

[XmlRoot("user_list")]
public class UserList
{
    public UserList() {Items = new List<User>();}
    [XmlElement("user")]
    public List<User> Items {get;set;}
}
public class User
{
    [XmlElement("id")]
    public Int32 Id { get; set; }

    [XmlElement("name")]
    public String Name { get; set; }
}

static class Program
{
    static void Main()
    {
        XmlSerializer ser= new XmlSerializer(typeof(UserList));
        UserList list = new UserList();
        list.Items.Add(new User { Id = 1, Name = "abc"});
        list.Items.Add(new User { Id = 2, Name = "def"});
        list.Items.Add(new User { Id = 3, Name = "ghi"});
        ser.Serialize(Console.Out, list);
    }
}

5
অতিরিক্ত স্তরের উপাদান এড়ানোর জন্য [এক্সএমএলিমেন্ট ("ব্যবহারকারী")] এর সাথে সুন্দর সমাধান। এটি দেখে, আমি নিশ্চিতভাবে ভেবেছিলাম যে এটি একটি <ব্যবহারকারী> বা <আইটেম> নোড (যদি আপনার কাছে এক্সএমএলিমেন্ট বৈশিষ্ট্য না থাকে) নির্গত হত, এবং তারপরে <ব্যবহারকারী> নোড যুক্ত করা হবে। তবে আমি এটি চেষ্টা করেছিলাম এবং এটি হয়নি, সুতরাং প্রশ্নটি যা চেয়েছিল তা হ্রাস করে।
জন ক্রাগ

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

কেন এটি সঠিক উত্তর হিসাবে চিহ্নিত করা হয়েছে তা আমি জানি না। এর মধ্যে তালিকাটি মোড়ানোর জন্য একটি শ্রেণি যুক্ত করা অন্তর্ভুক্ত। প্রশ্নটি এড়াতে চাইছে তা অবশ্যই ছিল।
DDRider62

1
@ ডিডিআর্ডার 62 প্রশ্নটি "মোড়ানো ছাড়া" বলে না। বেশিরভাগ লোকেরা বেশ বাস্তববাদী এবং কেবল তথ্য বের করতে চান। এই উত্তরটি আপনাকে .Itemsসদস্যের মাধ্যমে তা করতে দেয় ।
মার্ক Gravell

50

যদি আপনি প্রয়োজনীয় মূলধনের সাথে মেলে Userশ্রেণীর সাথে XmlTypeসাজান:

[XmlType("user")]
public class User
{
   ...
}

তারপর XmlRootAttributeউপর XmlSerializerctor আকাঙ্ক্ষিত রুট এবং তালিকা <> মধ্যে সরাসরি পড়ার অনুমতি দিতে পারেন:

    // e.g. my test to create a file
    using (var writer = new FileStream("users.xml", FileMode.Create))
    {
        XmlSerializer ser = new XmlSerializer(typeof(List<User>),  
            new XmlRootAttribute("user_list"));
        List<User> list = new List<User>();
        list.Add(new User { Id = 1, Name = "Joe" });
        list.Add(new User { Id = 2, Name = "John" });
        list.Add(new User { Id = 3, Name = "June" });
        ser.Serialize(writer, list);
    }

...

    // read file
    List<User> users;
    using (var reader = new StreamReader("users.xml"))
    {
        XmlSerializer deserializer = new XmlSerializer(typeof(List<User>),  
            new XmlRootAttribute("user_list"));
        users = (List<User>)deserializer.Deserialize(reader);
    }

ক্রেডিট: উপর ভিত্তি করে উত্তর থেকে YK1


11
আমার দৃষ্টিতে এটি পরিষ্কারভাবে প্রশ্নের উত্তর। প্রশ্নটি <T> তালিকাতে deserialization সম্পর্কে ছিল। সম্ভবত একটি ব্যতীত অন্য সমস্ত সমাধানগুলির মধ্যে তালিকাটি অন্তর্ভুক্ত করার জন্য একটি মোড়ানো শ্রেণীর অন্তর্ভুক্ত রয়েছে যা অবশ্যই পোস্ট করা প্রশ্ন ছিল না এবং প্রশ্নের লেখক কী এড়াতে চাইছেন বলে মনে হয়।
DDRider62

1
এই পদ্ধতির সাথে, XmlSerializerগুরুতর মেমরি ফুটো এড়াতে অবশ্যই স্ট্যাটিক্যালি ক্যাশেড এবং পুনঃব্যবহার করা আবশ্যক, বিবরণের জন্য স্ট্রিমরিডার এবং এক্সএমএলসিরাইজার ব্যবহার করে মেমরি লিক দেখুন।
dbc

16

হ্যাঁ, এটি সিরিয়ালাইজ করবে এবং একটি তালিকা <> কে deserialize করবে। সন্দেহ থাকলে আপনি [XMLArray] বৈশিষ্ট্যটি ব্যবহার করেছেন তা নিশ্চিত করুন।

[Serializable]
public class A
{
    [XmlArray]
    public List<string> strings;
}

এটি সিরিয়ালাইজ () এবং ডিসরিয়ালাইজ () উভয়ের সাথেই কাজ করে।


16

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

একবার দেখুন (এটি আমার পক্ষে কাজ করে):

private void SerializeParams<T>(XDocument doc, List<T> paramList)
    {
        System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(paramList.GetType());

        System.Xml.XmlWriter writer = doc.CreateWriter();

        serializer.Serialize(writer, paramList);

        writer.Close();           
    }

private List<T> DeserializeParams<T>(XDocument doc)
    {
        System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(List<T>));

        System.Xml.XmlReader reader = doc.CreateReader();

        List<T> result = (List<T>)serializer.Deserialize(reader);
        reader.Close();

        return result;
    }

সুতরাং আপনি যা চান তালিকা ক্রমিকায়িত করতে পারেন! আপনার প্রত্যেকবার তালিকার ধরণ নির্দিষ্ট করার দরকার নেই।

        List<AssemblyBO> list = new List<AssemblyBO>();
        list.Add(new AssemblyBO());
        list.Add(new AssemblyBO() { DisplayName = "Try", Identifier = "243242" });
        XDocument doc = new XDocument();
        SerializeParams<T>(doc, list);
        List<AssemblyBO> newList = DeserializeParams<AssemblyBO>(doc);

3
আসলে প্রশ্নের উত্তর দেওয়ার জন্য ধন্যবাদ। আমি যুক্ত করব যে List<MyClass>নথির জন্য উপাদানটির নাম দেওয়া উচিত ArrayOfMyClass
সর্বাধিক তোরো

8

হ্যাঁ, এটি <> তালিকাতে ডিসেরায়ালাইজ করে। এটিকে অ্যারেতে রাখার দরকার নেই এবং এটিকে একটি তালিকায় মোড়ানো / আবশ্যক।

public class UserHolder
{
    private List<User> users = null;

    public UserHolder()
    {
    }

    [XmlElement("user")]
    public List<User> Users
    {
        get { return users; }
        set { users = value; }
    }
}

কোডটি ডিসেরায়ালাইজিং,

XmlSerializer xs = new XmlSerializer(typeof(UserHolder));
UserHolder uh = (UserHolder)xs.Deserialize(new StringReader(str));

5

<T> তালিকা সম্পর্কে নিশ্চিত না তবে অ্যারে অবশ্যই সক্ষম-সক্ষম। এবং সামান্য কিছু ম্যাজিক এটি আবার একটি তালিকার কাছে পাওয়া সত্যিই সহজ করে তোলে।

public class UserHolder {
   [XmlElement("list")]
   public User[] Users { get; set; }

   [XmlIgnore]
   public List<User> UserList { get { return new List<User>(Users); } }
}

2
"ধারক" শ্রেণি না করে কি সম্ভব?
ড্যানিয়েল শেফার

@ ড্যানিয়েল, এএফাইক, নং আপনাকে কিছু কংক্রিট অবজেক্টের ধরণের সিরিয়ালাইজ করতে হবে এবং ডিজিটালাইজ করতে হবে। আমি বিশ্বাস করি না যে এক্সএমএল সিরিয়ালাইজেশন সিরিয়ালাইজেশনের সূচনা হিসাবে স্থানীয়ভাবে সংগ্রহের ক্লাসগুলিকে সমর্থন করে। আমি যদিও 100% জানি না।
জারেডপাড়

[XMLElement ("তালিকা")] এর পরিবর্তে [XMLArray ("তালিকা")] হওয়া উচিত।
ডেসিরিয়ালাইজেশনটি কেবলমাত্র

2

কেমন

XmlSerializer xs = new XmlSerializer(typeof(user[]));
using (Stream ins = File.Open(@"c:\some.xml", FileMode.Open))
foreach (user o in (user[])xs.Deserialize(ins))
   userList.Add(o);    

বিশেষত অভিনব নয় তবে এটি কাজ করা উচিত।


2
স্ট্যাকওভারফ্লোতে স্বাগতম! পোস্টের নির্ভুলতার উন্নতির জন্য একটি নমুনা কোডের জন্য একটি সংক্ষিপ্ত বিবরণ প্রদান করা সর্বদা ভাল :)
পিকরোফো সফ্টওয়্যার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.