Frage

Bei der folgenden XML:

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

Und die folgende Klasse:

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

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

Ist es möglich, XmlSerializer zu verwenden, um die XML-Daten in eine List<User> deserialisieren? Wenn ja, welche Art von zusätzlichen Attributen werde ich verwenden müssen, oder welche zusätzlichen Parameter muss ich verwenden, um die XmlSerializer Instanz zu konstruieren?

Ein Array (User[]) wäre annehmbar, wenn auch etwas weniger bevorzugt.

War es hilfreich?

Lösung

Sie können encapsulate die Liste trivialer:

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

Andere Tipps

Wenn Sie die User Klasse mit dem XmlType schmücken die erforderliche Kapitalisierung entsprechen:

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

Dann wird die XmlRootAttribute auf dem XmlSerializer Ctor kann die gewünschte Wurzel liefern und direktes Ablesen in Liste erlauben <>:

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

Credit: basierend auf beantworten von YK1 .

Ja, es wird serialisiert und deserialisiert eine List <>. So stellen Sie sicher Sie verwenden [XmlArray] Attribut, wenn im Zweifel.

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

Dies funktioniert sowohl mit Serialize () und Deserialize ().

Ich glaube, ich habe einen besseren Weg gefunden. Sie müssen keine Attribute in Klassen setzen. Ich habe für die Serialisierung und Deserialisierung zwei Methoden hergestellt, die als Parameter generische Liste nehmen.

Werfen Sie einen Blick (es funktioniert für mich):

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

finden, für jede Liste Serialisierung können Sie wollen! Sie brauchen nicht jedes Mal, wenn die Liste Typen angeben.

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

Ja, es ist deserialisieren zur Liste <>. Keine Notwendigkeit, es in einem Array zu halten und wickeln / kapseln sie in einer Liste an.

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

    public UserHolder()
    {
    }

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

Deserialisieren Code,

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

Nicht sicher List , aber Arrays werden sicherlich tun können. Und ein wenig Magie macht es wirklich einfach wieder in eine Liste zu erhalten.

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

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

Wie wäre es

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

Nicht besonders schick, aber es sollte funktionieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top