I currently playing with the XMLSerializer
to understand how it works. I am able to serialize, save and de-serialize a single object without problem. However I run into problems when I try to de-serialize multiple objects. I get this error : 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.
I've tried this approach https://stackoverflow.com/a/16416636/8964654 here (and I could be doing it wrong)
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;
}
it didn't work
This is my original code. I intentionally call the SaveUser
method twice to simulate the method being called twice at different times
[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();
}
}
below is how it saved XML data
<?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>
I want to be able to retrieve all the data and print details of each individual user. How can I do this? Is there a better approach?
Your xml has multiple root elements, this is not allowed for valid xml. If you change it to the format, this should work.
I'd solve this problem as follow:
Create the User class
A Serializable class contains a user details.
Create the Users class
Another Serializable class contains a list of
User
objects and handles both serialize and Deserialize routines:This way, you guarantee the XML file is formatted correctly, manage the users list (add, remove, edit).
Save (serialize) example
Load (Deserialize) example:
and here is how the generated XML file looks like
Good luck.