【问题标题】:Trouble serializing and deserializing multiple objects序列化和反序列化多个对象的问题
【发布时间】:2019-11-04 02:33:43
【问题描述】:

我目前正在使用XMLSerializer以了解它是如何工作的。我能够毫无问题地序列化、保存和反序列化单个对象。但是,当我尝试反序列化多个对象时遇到了问题。我收到此错误:Unhandled exception. System.InvalidOperationException: There is an error in XML document (10, 10). ---> System.Xml.XmlException: Unexpected XML declaration. The XML declaration must be the first node in the document, and no whitespace characters are allowed to appear before it.

我已经尝试过这种方法https://stackoverflow.com/a/16416636/8964654 在这里(我可能做错了)


 public static ICollection<T> DeserializeList<T>()
    {


      string filePath = @"TextFiles/Users.txt";
      XmlSerializer serializerTool = new XmlSerializer(typeof(User));
             List<T> list = new List<T>();


      using (FileStream fs = new FileStream (filePath, FileMode.Open)){

       while(fs.Position!=fs.Length)
       {
         //deserialize each object in the file
         var deserialized = (T)serializerTool.Deserialize(fs); 
         //add individual object to a list
         list.Add(deserialized);
        }
      }

    //return the list of objects
    return list;
}

没用

这是我的原始代码。我故意调用SaveUser方法两次来模拟方法在不同时间被调用两次

 [Serializable]
  public class User: ISerializable{

    public static void SaveUser(User user){
      string filePath = @"TextFiles/Users.txt";
      XmlSerializer serializerTool = new XmlSerializer(typeof(User));

      using(FileStream fs = new FileStream(filePath, FileMode.Append)){
        serializerTool.Serialize(fs, user);
        }
    }

    public static void PrintUser(){
      string filePath = @"TextFiles/Users.txt";
      XmlSerializer serializerTool = new XmlSerializer(typeof(User));

      using (FileStream fs = new FileStream (filePath, FileMode.Open)){
        User u1 = (User)serializerTool.Deserialize(fs);
        Console.WriteLine($"{u1.FirstName} {u1.LastName}, {u1.DOB.ToShortDateString()}");
        }
    }
}


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

    User user1 = new User(){
      FirstName = "Kim",
      LastName = "Styles",
      Address = "500 Penn street, Dallas, 46589",
      Username = "KimStyles@yahoo.com",
      Password ="Kim2019",
      DOB = (new DateTime(1990,10,01)),
      Id = 2
    };


     User user2 = new User(){
      FirstName = "Carlos",
      LastName = "Santana",
      Address = "500 Amigos street,San Jose, California, 46589",
      Username = "Carlos.Santana@yahoo.com",
      Password ="CarLosSan2019",
      DOB = (new DateTime(1990,10,01)),
      Id = 2
    };

   User.SaveUser(user1);
   User.SaveUser(user2);
   User.PrintUser();

        }
    }

下面是它如何保存 XML 数据


<?xml version="1.0"?>
<User xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <FirstName>Kim</FirstName>
  <LastName>Styles</LastName>
  <DOBProxy>Monday, 01 October 1990</DOBProxy>
  <Username>KimStyles@yahoo.com</Username>
  <Password>Kim2019</Password>
  <Address>500 Penn street, Dallas, 46589</Address>
  <Id>1</Id>
</User>
<?xml version="1.0"?>
<User xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <FirstName>Carlos</FirstName>
  <LastName>Santana</LastName>
  <DOBProxy>Monday, 01 October 1990</DOBProxy>
  <Username>Carlos.Santana@yahoo.com</Username>
  <Password>CarLosSan2019</Password>
  <Address>500 Amigos street,San Jose, California, 46589</Address>
  <Id>2</Id>
</User>

我希望能够检索每个用户的所有数据并打印详细信息。我怎样才能做到这一点?有更好的方法吗?

【问题讨论】:

    标签: c# xml serialization deserialization filestream


    【解决方案1】:

    您的 xml 有多个根元素,这对于有效的 xml 是不允许的。 如果您将其更改为格式,这应该可以工作。

    <?xml version="1.0"?>
    <Users>
       <user></user>
       <user></user>
    </Users>
    

    【讨论】:

    • 如何通过代码保持相同的根元素?
    • 您可以将 xml 保存为用户列表,而不是单个对象。 JQSOFT 的另一个答案有这种方法。
    【解决方案2】:

    我会这样解决这个问题:

    创建 User

    Serializable 类包含用户详细信息。

    [Serializable]
    public class User
    {
    
        public int ID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime DOB { get; set; }
    
        public override string ToString()
        {
            return $"{ID}, {FirstName}, {LastName}, {DOB.ToShortDateString()}";
        }
    }
    

    创建 Users

    另一个Serializable 类包含User 对象的列表并处理序列化和反序列化例程:

    [Serializable]
    public class Users  
    {
        public List<User> ThisUsers = new List<User>();
    
        public void Save(string filePath)
        {
            XmlSerializer xs = new XmlSerializer(typeof(Users));
    
            using (StreamWriter sr = new StreamWriter(filePath))
            {
                xs.Serialize(sr, this);
            }
        }
    
        public static Users Load(string filePath)
        {
            Users users;
            XmlSerializer xs = new XmlSerializer(typeof(Users));
            using (StreamReader sr = new StreamReader(filePath))
            {
                users = (Users)xs.Deserialize(sr);
            }
            return users;
        }
    }
    

    这样,您可以保证 XML 文件格式正确,管理用户列表(添加、删除、编辑)。

    保存(序列化)示例

    string filePath = @"TextFiles/Users.txt";
    Users users = new Users();
    for (int i = 1; i < 5; i++)
    {
        User u = new User
        {
            ID = i,
            FirstName = $"User {i}",
            LastName = $"Last Name {i}",
            DOB = DateTime.Now.AddYears(-30 + i)                    
        };
        users.ThisUsers.Add(u);
    }
    users.Save(filePath);
    

    加载(反序列化)示例:

    string filePath = @"TextFiles/Users.txt";
    Users users = Users.Load(filePath);
    users.ThisUsers.ForEach(a => Console.WriteLine(a.ToString()));
    
    //Or get a specific user by id:
    Console.WriteLine(users.ThisUsers.Where(b => b.ID == 3).FirstOrDefault()?.ToString());
    

    这是生成的 XML 文件的样子

    <?xml version="1.0" encoding="utf-8"?>
    <Users xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <ThisUsers>
        <User>
          <ID>1</ID>
          <FirstName>User 1</FirstName>
          <LastName>Last Name 1</LastName>
          <DOB>1990-11-04T08:16:09.1099698+03:00</DOB>
        </User>
        <User>
          <ID>2</ID>
          <FirstName>User 2</FirstName>
          <LastName>Last Name 2</LastName>
          <DOB>1991-11-04T08:16:09.1109688+03:00</DOB>
        </User>
        <User>
          <ID>3</ID>
          <FirstName>User 3</FirstName>
          <LastName>Last Name 3</LastName>
          <DOB>1992-11-04T08:16:09.1109688+03:00</DOB>
        </User>
        <User>
          <ID>4</ID>
          <FirstName>User 4</FirstName>
          <LastName>Last Name 4</LastName>
          <DOB>1993-11-04T08:16:09.1109688+03:00</DOB>
        </User>
      </ThisUsers>
    </Users>
    

    祝你好运。

    【讨论】:

      猜你喜欢
      • 2013-05-01
      • 1970-01-01
      • 2011-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-05
      • 2016-10-14
      • 2014-12-24
      相关资源
      最近更新 更多