Reading and writing an existing xml file c# 3.0 / .net3.5 - c#

I have a xml-file which I want to read. How can I do it? I would not load whole xml file at runtime
(XmlDocument _xd = XmlDocument.Load(path))
I want to do it with Readers, but I can not achieve with it.
At the same time I want to add nodes to this xml-file with writers. How do these work with XDocument or at c# 3.5.
Kind Regards.

I think this is useful.
Here's an example:
using System;
using System.Xml;
namespace ReadXml1
{
class Class1
{
static void Main(string[] args)
{
// Create an isntance of XmlTextReader and call Read method to read the file
XmlTextReader textReader = new XmlTextReader("C:\\books.xml");
textReader.Read();
// If the node has value
while (textReader.Read())
{
// Move to fist element
textReader.MoveToElement();
Console.WriteLine("XmlTextReader Properties Test");
Console.WriteLine("===================");
// Read this element's properties and display them on console
Console.WriteLine("Name:" + textReader.Name);
Console.WriteLine("Base URI:" + textReader.BaseURI);
Console.WriteLine("Local Name:" + textReader.LocalName);
Console.WriteLine("Attribute Count:" + textReader.AttributeCount.ToString());
Console.WriteLine("Depth:" + textReader.Depth.ToString());
Console.WriteLine("Line Number:" + textReader.LineNumber.ToString());
Console.WriteLine("Node Type:" + textReader.NodeType.ToString());
Console.WriteLine("Attribute Count:" + textReader.Value.ToString());
}
}
}
}
And here's an example for XMLWriters:
using System.Xml;
class Program
{
class Employee
{
int _id;
string _firstName;
string _lastName;
int _salary;
public Employee(int id, string firstName, string lastName, int salary)
{
this._id = id;
this._firstName = firstName;
this._lastName = lastName;
this._salary = salary;
}
public int Id { get { return _id; } }
public string FirstName { get { return _firstName; } }
public string LastName { get { return _lastName; } }
public int Salary { get { return _salary; } }
}
static void Main()
{
Employee[] employees = new Employee[4];
employees[0] = new Employee(1, "David", "Smith", 10000);
employees[1] = new Employee(3, "Mark", "Drinkwater", 30000);
employees[2] = new Employee(4, "Norah", "Miller", 20000);
employees[3] = new Employee(12, "Cecil", "Walker", 120000);
using (XmlWriter writer = XmlWriter.Create("employees.xml"))
{
writer.WriteStartDocument();
writer.WriteStartElement("Employees");
foreach (Employee employee in employees)
{
writer.WriteStartElement("Employee");
writer.WriteElementString("ID", employee.Id.ToString());
writer.WriteElementString("FirstName", employee.FirstName);
writer.WriteElementString("LastName", employee.LastName);
writer.WriteElementString("Salary", employee.Salary.ToString());
writer.WriteEndElement();
}
writer.WriteEndElement();
writer.WriteEndDocument();
}
}
}

Here is an example of loading xml file with XDocument, adding a child node and saving it to the use :
// Load XML file :
XDocument xdoc = XDocument.Load(path);
// Parse XML :
//XDocument xdoc = XDocument.Parse("<YourRootElement><ChildElement>Child 1</ChildElement></YourRootElement>");
// Add Child Node to loaded xml :
xdoc.Element("YourRootElement").Add(
new XElement("ChildElement", "Child 2"));
// Save XML to file :
xdoc.Save(path);
EDIT : Use XDocument.Parse method to load XML from memory.

Didn't you consider also using LINQ? Like this (just pseudo-like, you would have to look it up on the web, but just to have an idea).
XDocument xmlDoc = //load or parse with XDocument.Load(..) or XDocument.Parse(...)
List<MyObject> myObj = (from myObject in xmlDoc.Descendants("myObjectTag")
select new MyObject
{
Name = (string)myObject.Attribute("name"),
...
}
).toList<MyObject>();
Voilà, here's a blog post I just found by quickly googling: * click *

Related

how to save/load data to n xml file

i'm trying to load and save my data in my datagrid to an xml file using Singleton Design.
i have created
public class DataProvider
{
private static DataProvider singletonInstance = new DataProvider();
private ObservablePerson Person;
/// <summary>
/// Private constructor
/// </summary>
private DataProvider()
{
}
public static DataProvider GetInstance()
{
if (singletonInstance == null)
singletonInstance = new DataProvider();
return singletonInstance;
}
public bool SaveToXml(List<Person> PersonsList)
{
return false;
}
public List<Person> LoadFromX()
{
return new List<Person>() { new Person() { name= "jhon" } };
}
}
}
and this is the object i want to save
[Serializable]
public class ObservablePerson : ObservableObject
{
private string _name;
public string name
{
get
{
return _name;
}
set
{
_name= value;
NotifyPropertyChanged();}
and i also created a view model form from person.
what should i do to save those data in my datagrid in a xml file .
thanks.
Read an XML file using XmlTextReader and call Read method to read its node one by one until the end of file.
using System;
using System.Xml;
namespace ReadXml1 {
class Class1 {
static void Main(string[] args) {
// Create an isntance of XmlTextReader and call Read method to read the file
XmlTextReader textReader = new XmlTextReader("C:\\books.xml");
textReader.Read();
// If the node has value
while (textReader.Read()) {
// Move to fist element
textReader.MoveToElement();
Console.WriteLine("XmlTextReader Properties Test");
Console.WriteLine("===================");
// Read this element's properties and display them on console
Console.WriteLine("Name:" + textReader.Name);
Console.WriteLine("Base URI:" + textReader.BaseURI);
Console.WriteLine("Local Name:" + textReader.LocalName);
Console.WriteLine("Attribute Count:" + textReader.AttributeCount.ToString());
Console.WriteLine("Depth:" + textReader.Depth.ToString());
Console.WriteLine("Line Number:" + textReader.LineNumber.ToString());
Console.WriteLine("Node Type:" + textReader.NodeType.ToString());
Console.WriteLine("Attribute Count:" + textReader.Value.ToString());
}
}
}
}
and for creating and save to XML file:
using System;
using System.Xml;
namespace ReadingXML2 {
class Class1 {
static void Main(string[] args) {
// Create a new file in C:\\ dir
XmlTextWriter textWriter = new XmlTextWriter("C:\\myXmFile.xml", null);
// Opens the document
textWriter.WriteStartDocument();
// Write comments
textWriter.WriteComment("First Comment XmlTextWriter Sample Example");
textWriter.WriteComment("myXmlFile.xml in root dir");
// Write first element
textWriter.WriteStartElement("Student");
textWriter.WriteStartElement("r", "RECORD", "urn:record");
// Write next element
textWriter.WriteStartElement("Name", "");
textWriter.WriteString("Student");
textWriter.WriteEndElement();
// Write one more element
textWriter.WriteStartElement("Address", "");
textWriter.WriteString("Colony");
textWriter.WriteEndElement();
// WriteChars
char[] ch = new char[3];
ch[0] = 'a';
ch[1] = 'r';
ch[2] = 'c';
textWriter.WriteStartElement("Char");
textWriter.WriteChars(ch, 0, ch.Length);
textWriter.WriteEndElement();
// Ends the document.
textWriter.WriteEndDocument();
// close writer
textWriter.Close();
}
}
}
Let's use Xml and Xml.Serialization:
using System.Xml;
using System.Xml.Serialization;
On your singleton, implements
public static List<T> LoadFromXml<T>(string path, string fileName)
{
var xmlSerializer = new XmlSerializer(typeof(List<T>));
var xmlText = File.ReadAllText(Path.Combine(path, fileName));
return (List<T>)xmlSerializer.Deserialize(new StringReader(xmlText));
}
public static bool SaveToXml<T>(List<T> list, string path, string fileName)
{
var xmlText = Serialize<T>(list);
try
{
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
File.WriteAllText(Path.Combine(path, fileName), xmlText);
return true;
}
catch(Exception e)
{
return false;
}
}
private static string Serialize<T>(List<T> list)
{
if (list == null || !list.Any())
return string.Empty;
var xmlSerializer = new XmlSerializer(typeof(List<T>));
using (var stringWriter = new StringWriter())
{
using (var xmlWriter = XmlWriter.Create(stringWriter, new XmlWriterSettings { Indent = true }))
{
xmlSerializer.Serialize(xmlWriter, list);
return stringWriter.ToString();
}
}
}
Using generic T, we can use the same methods to save other types of records
To call:
var person1 = new Person()
{
name = "jhon",
};
var person2 = new Person()
{
name = "another jhon",
};
var personList = new List<Person>();
personList.Add(person1);
personList.Add(person2);
var pathXml = #"C:\testes\xml";
var fileName = "persons.xml";
var dataProvider = DataProvider.GetInstance();
var itsSaved = dataProvider.SaveToXml<Person>(personList, pathXml, fileName);
var persons = dataProvider.LoadFromXml<Person>(pathXml, fileName);

How to create an object after deserialization in c# in xml

I am trying to create an object after deserialization however I do not want to serialize that object.
Here is an example:
public class Visit : INotifyPropertyChanged
{
private int id;
private int serialNumber;
private DateTime dateOfVisit;
private VisitTime visitTime;
private VisitType visitType;
private int price;
private VisitStatus visitStatus;
private PaymentMethod paymentMethod;
private String cause;
private String recommendation;
private Prescription prescription;
private Patient patient;
[NonSerialized]
private Doctor doctor;
private Room room;
// more code below...
}
I do not want to serialize the doctor, I have the doctors in completely different xml file. I am serializing doctorID property fine. After deserialization of the properties that I have serialized I want to create a new instance of a Doctor class and assign it to doctor field in Visit class. How can I do that correctly?
Here is the xml that I am serializing:
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfVisit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Visit>
<Id>1</Id>
<SerialNumber>1</SerialNumber>
<VisitTime>
<StartTime>2021-05-02T09:00:00</StartTime>
<EndTime>2021-05-02T10:00:00</EndTime>
</VisitTime>
<DateOfVisitString>1. Jan 00:00 AM</DateOfVisitString>
<DateOfVisit>0001-01-01T00:00:00</DateOfVisit>
<VisitType>examination</VisitType>
<VisitTypeString>Pregled</VisitTypeString>
<Price>10</Price>
<PriceString>10$</PriceString>
<VisitStatus>forthcoming</VisitStatus>
<VisitStatusString>Predstojeći</VisitStatusString>
<DoctorName>Janko Radovic</DoctorName>
<DoctorId>12123131</DoctorId>
<PaymentMethod>digitalWallet</PaymentMethod>
</Visit>
</ArrayOfVisit>
I tried using onDeserializing() and onDeserialized() methods but I get a null pointer exception when data is binded to View with DoctorName property. It just says doctor is null.
[System.Xml.Serialization.XmlIgnore]
public Doctor Doctor
{
get
{
return doctor;
}
set
{
doctor = value;
OnPropertyChanged("Doctor");
OnPropertyChanged("DoctorName");
OnPropertyChanged("DoctorId");
}
}
public String DoctorName
{
get
{
return doctor.Name + " " + doctor.Surname;
}
set
{
}
}
public String DoctorId
{
get
{
return doctor.Id;
}
set
{
}
}
[OnDeserialized()]
internal void OnDeserializedMethod(StreamingContext context)
{
DoctorService doctorService = new DoctorService();
doctor = doctorService.getDoctorById(DoctorId);
}
Here is how I serialize and deserialize:
public void SerializeObject<T>(T serializableObject, string fileName)
{
if (serializableObject == null) { return; }
XmlSerializer serializer = new XmlSerializer(serializableObject.GetType());
try
{
var temp = AppDomain.CurrentDomain.BaseDirectory;
temp = Path.Combine(temp.Substring(0, temp.Length - 10), "Storage\\");
fileName = Path.Combine(temp, fileName);
StreamWriter w = new StreamWriter(fileName);
serializer.Serialize(w, serializableObject);
w.Close();
}
catch (Exception e)
{
//Log exception here
}
}
public T DeSerializeObject<T>(string fileName)
{
var temp = AppDomain.CurrentDomain.BaseDirectory;
temp = Path.Combine(temp.Substring(0, temp.Length - 10), "Storage\\");
fileName = Path.Combine(temp, fileName);
if (string.IsNullOrEmpty(fileName)) { return default(T); }
T objectOut = default(T);
try
{
Type outType = typeof(T);
XmlSerializer serializer = new XmlSerializer(outType);
StreamReader r = new StreamReader(fileName);
objectOut = (T)serializer.Deserialize(r);
r.Close();
}
catch (Exception e)
{
//Log exception here
}
return objectOut;
}
Any suggestion how I can do this? Just serialize the id and then by using that id to create a Doctor object in Visit class? Thank you!
So according to mm8 who suggested a thing that worked out this is how it should be done.
XMLSerializer works with get and set properties of a model class. So when serializing a particular class object the way serialization works is that it uses get method of that property to serialize. To deserialize it uses set method to again set the fields of that class object that was serialized.
If you do not want to serialize a particular field of a class you should just set [System.Xml.Serialization.XmlIgnore] above your property. I only wanted to serialize an id of an Doctor class and I did it by making a property:
public String DoctorId
{
get
{
return doctor.Id;
}
set
{
DoctorService doctorService = new DoctorService();
doctor = doctorService.getDoctorById(value);
}
}
When deserializing a set method is called value is equal to serialized doctor's id. Then a service is used which finds the doctor from some other repository and it sets the doctor field in the Visit class.

xml string to Object mapping does not happen

I have a stored procedure that sends a response as an xml string
So I've create a class and want to map the response of this store procedure to an Object of some type
This is my class and it's proprieties.
The Populate method is where i want to do my xml to object mapping.
[XmlRoot("SiteItem")]
public class SiteItem : BaseEntity<SiteItem>
{
[XmlElement("IdSiteItem")]
public int IdSiteItem { get; set; }
[XmlElement("ItemName")]
public string ItemName{ get; set; }
public override SiteItem Populate(DataRow entity)
{
var column = entity["Column1"].ToString();
XmlSerializer serialize = new XmlSerializer(typeof(SiteItem));
string result = column.Replace("<Root>", "");
result = result.Replace("</Root>", "");
result = result.Replace("</SiteItem>", "");
result = result.Replace("/>", ">");
result = result.Replace(">", "/>|");
System.Collections.Generic.List<string> siteItems = result.Split('|').ToList();
siteItems.RemoveAll(item => string.IsNullOrEmpty(item));
foreach (var item in siteItems)
{
using (StringReader stream = new System.IO.StringReader(item))
{
SiteItem response = (SiteItem)serialize.Deserialize(stream);
//=> response always null
//=> stream has the following format
//=> <SiteItem IdSiteItem=\"8436\" ItemName=\"demoweb\" >
}
}
return null;
}
}
}
The problem is that the mapping from xml node to SiteItem does not happen, the props are their default values.
This is the type of response I have from the stored procedure
"<Root>
<SiteItem IdSiteItem=\"8436\" ItemName=\"demoweb\" >
<SiteItem IdSiteItem=\"8465\" ItemName=\"\" />
<SiteItem IdSiteItem=\"8535\" ItemName=\"DocumentPreview\" /></SiteItem>
<SiteItem IdSiteItem=\"7413\" ItemName=\"GlobalNews Search\" />
<SiteItem IdSiteItem=\"5838\" ItemName=\"GlobalQuestionsForm\" />
</Root>"
So what I did is first remove <Root> and </root>. Remove the </SiteItem> since not all elements have this node ending.
After I obtain a string that is free of Root and /SiteItem I've applied a delimiter "|" so that i can split and store the string as a list of strings
each list item is a SiteItem node.
What am i doing wrong here?
Thanks
[XmlRoot("Root")]
public class SiteItem
{
[XmlElement("SiteItem")]
public List<SiteItemChild> Child { get; set; }
}
And the class that represents the child
public class SiteItemChild
{
[XmlAttribute("IdSiteItem")]
public int IdSiteItem { get; set; }
[XmlAttribute("ItemName")]
public int ItemName{ get; set; }
}
this is the deserializer.
public SiteItem Deserialize(string xmlString)
{
using (StringReader reader = new StringReader(xmlString));
{
XmlSerializer serializer = new XmlSerializer(typeof(SiteItem));
SiteItem #object = (SiteItem)serializer.Deserialize(reader);
return #object;
}
}
A better way for this situation.
public SiteItem Deserialize(string xmlString)
{
string processedXml = xmlString.Replace("<Root>" , "");
processedXml = processedXml.Replace("</Root>" , "");
processedXml = processedXml.Replace("</SiteItem>", "");
processedXml = processedXml.Replace(" />", ">");
processedXml = processedXml.Replace(">", "></SiteItem>");
processedXml = processedXml.Insert(0, "<Root>");
processedXml = processedXml.Insert(processedXml.Length, "
</Root>");
using (StringReader reader = new StringReader(processedXml));
{
XmlSerializer serializer = new XmlSerializer(typeof(SiteItem));
SiteItem #object = (SiteItem)serializer.Deserialize(reader);
return #object;
}
}
Why I did this? Because some elements SiteItem nodes have "/>" ending others ">" and others " ... so i standardized by all SiteItems to have an ending tag.
The standard
In the last string processing part i just added the Root start and ending tag again.
Why i've choosen this solution? Specific to my case the business logic is done in procedures and the problem here is that some procedures send an xmlString other send dataSets.

Getting a 'path' of a current XmlReader position

What I really like about JsonReader in Json.NET is that you always know the path of the current JsonReader position. For example, we have a json like this:
{
"name" :
{
"first": "John",
"last": "Smith"
}
}
If we are standing or "John" element, JsonReader.Path would be "name.first"
Is there a way to achieve something similar with XmlReader? Maybe use XPath? For example, we have a xml like this:
<root>
<name>
<first>John/<first>
<last>Smith</last>
</name>
</root>
I want to get "/root/name/first" while standing on "John" and "/root/name/last" while standing on "Smith"
It seems like there is no way to do this using standard .NET functionality, so I came up with my own class.
internal sealed class XmlReaderWrapperWithPath : IDisposable
{
private const string DefaultPathSeparator = ".";
private readonly Stack<string> _previousNames = new Stack<string>();
private readonly XmlReader _reader;
private readonly bool _ownsReader;
public XmlReaderWrapperWithPath(XmlReader reader, bool ownsReader)
{
if (reader == null)
{
throw new ArgumentNullException("reader");
}
_ownsReader = ownsReader;
_reader = reader;
PathSeparator = DefaultPathSeparator;
}
public bool Read()
{
var lastDepth = Depth;
var lastName = Name;
if (!_reader.Read())
{
return false;
}
if (Depth > lastDepth)
{
_previousNames.Push(lastName);
}
else if (Depth < lastDepth)
{
_previousNames.Pop();
}
return true;
}
public string Name
{
get
{
return _reader.Name;
}
}
public string Value
{
get
{
return _reader.Value;
}
}
private int Depth
{
get
{
return _reader.Depth;
}
}
public string Path
{
get
{
return string.Join(PathSeparator, _previousNames.Reverse());
}
}
public string PathSeparator { get; set; }
#region IDisposable
public void Dispose()
{
if (_ownsReader)
{
_reader.Dispose();
}
}
#endregion
}
Note that this class does not form XPath (so no paths for attributes), but this was enough for my needs. Hope this helps someone.
I use XmlDocument and the XmlNode class to work with xml Data.
While standing on a Node is in this case you have the XmlNode in this case x. There is no such methode to get the path to the node. But this code do it.
XmlDocument doc = new XmlDocument();
doc.LoadXml("<root>" +
"<name>" +
"<first>John</first>" +
"<last>Smith</last>" +
"</name>" +
"</root>");
XmlNodeList liste = doc.FirstChild.SelectNodes("*/first");
XmlNode x = liste[0]; //Some Node
string path = "";
while (!x.Name.Equals("document"))
{
path = x.Name + "\\" + path;
x = x.ParentNode;
}

XML Serialization

I want to add multiple record one by one using XML serialization. I have three text boxes and a button which is used to get the data from the user and then serializae in XML file. However, when I add one record on it's own it's fine, but for the another record it declares multiple root elements which I am not able to handle.
I am doing XML serialization and I am getting this error in XML File
**<?xml version="1.0" encoding="utf-8"?>
<sroot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:my-examples:shaping">**
<CustomerId>3a8bb49e-f616-49a5-8ec8-1886881c3042</CustomerId>
<FirstName>HASEEB</FirstName>
<LastName>KHAN</LastName>
<CustomerEmail>SDCFDS</CustomerEmail>
**</sroot><?xml version="1.0" encoding="utf-8"?>
<sroot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:my-examples:shaping">**
<CustomerId>6d2cbe5e-e1fb-4526-9f98-bf396b4ded55</CustomerId>
<FirstName>ammae</FirstName>
<LastName>wdfjk</LastName>
<CustomerEmail>sdkcbnk</CustomerEmail>
</sroot>
As you can see in above XML code that there are multiple root element is written and I am not able to fix that I have a class called customer.cs and the code is written in this class is
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml;
using System.Xml.Serialization;
namespace XmlSearlizeProject.Classes
{
[Serializable]
[XmlRoot(ElementName = "sroot", Namespace = "urn:my-examples:shaping")]
public class Customer
{
string id = default(string);
string firstName = default(string);
string lastName = default(string);
string email = default(string);
public Customer()
{
}
public Customer(string id, string firstName, string lastName, string email)
{
CustomerId = id;
FirstName = firstName;
LastName = lastName;
Email = email;
}
[XmlElement("CustomerId")]
public string CustomerId
{
get
{
return this.id;
}
set
{
this.id = value;
}
}
[XmlElement("FirstName")]
public string FirstName
{
get
{
return this.firstName;
}
set
{
this.firstName = value;
}
}
[XmlElement("LastName")]
public string LastName
{
get
{
return this.lastName;
}
set
{
this.lastName = value;
}
}
[XmlElement("CustomerEmail")]
public string Email
{
get
{
return this.email;
}
set
{
this.email = value;
}
}
}
}
And my C# code is
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml.Serialization;
using System.IO;
using System.Xml;
using System.Text;
namespace XmlSearlizeProject.WebPages
{
public partial class CustomerPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
private void GeneralFunction(Stream xmlStream)
{
//xmlStream.Close();
string customerId = Guid.NewGuid().ToString();
Classes.Customer customer = new Classes.Customer(customerId,this.FirstNameTextBox.Text,this.LastNameTextBox.Text,this.EmailTextBox.Text);
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Classes.Customer));
XmlDocument document = new XmlDocument();
document.Load(xmlStream);
XmlElement id = document.CreateElement("Id");
id.InnerText = customerId;
document.DocumentElement.InsertAfter(id, document.DocumentElement.LastChild);
XmlElement firstName = document.CreateElement("rtgr");
firstName.InnerText = customer.FirstName;
document.DocumentElement.InsertAfter(firstName, document.DocumentElement.LastChild);
XmlElement lastName = document.CreateElement("rtgtr");
lastName.InnerText = customer.LastName;
document.DocumentElement.InsertAfter(lastName, document.DocumentElement.LastChild);
XmlElement email = document.CreateElement("grbfr");
email.InnerText = customer.Email;
document.DocumentElement.InsertAfter(email, document.DocumentElement.LastChild);
XmlTextWriter xmlTextWriter = new XmlTextWriter(xmlStream, Encoding.UTF8);
xmlSerializer.Serialize(xmlTextWriter, customer);
xmlStream.Close();
}
private void SerializeCustomer()
{
if (File.Exists(Server.MapPath("~/Customer.xml")))
{
Stream xmlWriterStream = new FileStream(Server.MapPath("~/Customer.xml"), FileMode.Open, FileAccess.ReadWrite);
GeneralFunction(xmlWriterStream);
xmlWriterStream.Close();
}
}
private void DeSerializeCustomer()
{
Stream xmlReaderStream = new FileStream(Server.MapPath("~/Customer.xml"), FileMode.Open, FileAccess.Read, FileShare.Read);
XmlSerializer xmlDeSerializer = new XmlSerializer(typeof(Classes.Customer));
Classes.Customer customer = (Classes.Customer)xmlDeSerializer.Deserialize(xmlReaderStream);
}
protected void SubmitButton_Click(object sender, EventArgs e)
{
//if (!File.Exists(Server.MapPath("~/Customer.xml")))
//{
SerializeCustomer();
//}
//else
//{
// DeSerializeCustomer();
//}
}
}
}
It looks like you're serializing one customer at a time, versus serializing a list/array/collection of customers to the XML file.
Serializing one works because you have 1 root element - Customer. However, when serializing many, you will need to serializing the collection of customers to the XML file.
So then you'll have (example purposes only):
<Customers>
<sroot/>
<sroot/>
</Customers>
A few articles to look at on this:
C# Serializing a Collection of Objects
http://wcode.net/2009/08/serialize-collection-of-object-in-c/
http://www.codeproject.com/KB/cs/objserial.aspx
Define a schema definition (xsd) in the format you want your xml to look like. Then you can use some external tools like xsd2code. This would Auto-generate your "Customer" class to the format of your xsd. (In case if you are doing in manually). Then your xml will match the way you define in your xsd. Give it a try, defining a xsd for your xml is always a better practice.
You could just inherit from list something like this...
[Serializable]
[XmlRoot(ElementName = "sroot", Namespace = "urn:my-examples:shaping")]
public class CustomerList : List<Customer>
{
}
[Serializable]
public class Customer
{
...
}
Example usage...
CustomerList customerList = new CustomerList
{
new Customer
{
FirstName = "John",
LastName = "Doe",
Email = "johndoe#foobar.com",
CustomerId = "123"
},
new Customer
{
FirstName = "Jane",
LastName = "Doe",
Email = "janedoe#foobar.com",
CustomerId = "456"
}
};
Then your method would serialize the list (instance of CustomerList)...
SerializeCustomerList(CustomerList customers)
{
// Do serialize CustomerList instance...
}
Then the resulting XML would look like...
<sroot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:my-examples:shaping">
<Customer>
<CustomerId>123</CustomerId>
<FirstName>John</FirstName>
<LastName>Doe</LastName>
<CustomerEmail>johndoe#foobar.com</CustomerEmail>
</Customer>
<Customer>
<CustomerId>456</CustomerId>
<FirstName>Jane</FirstName>
<LastName>Doe</LastName>
<CustomerEmail>janedoe#foobar.com</CustomerEmail>
</Customer>
</sroot>
Hope it helps!

Categories