I was finally able to create a Xml file with some coding (with lots of help here from some people). I can store the file but the next process is reading it back. This gave me an error:
"Unexpected Xml declaration". After searching a bit I understand that a Xml file can have only one time <?xml version=1.0 etc>. But my document has several of these statements in the document. And therefore the code
xmlDocument doc = new XmlDocument
Throws me this error. The question is how do I get rid of all these comments in the xml document.
The document is create with 2 functions:
private void btnSave_Click(object sender, EventArgs e)
{
//Check if all fields are filled in
if (txbCompany.Text == "" || txbSiteName.Text == "" || txbIMO.Text == "")
{
MessageBox.Show("Please fill in all empty fields");
}
else if (NumMachTot.Value == 0)
{
MessageBox.Show("A Client profile needs at least one assigned machine!");
}
else
{
var appData = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "VibroManager");
Directory.CreateDirectory(appData);
//Create the Company Profile Class
CompanyProfile companyProfile = new CompanyProfile();
companyProfile.CompanyName = txbCompany.Text;
companyProfile.SiteName = txbSiteName.Text;
companyProfile.Imo = txbIMO.Text;
companyProfile.MachineTotal = (int)NumMachTot.Value;
//Serialization of the companyProfile and append to the document
System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(CompanyProfile));
using (var writer = new StreamWriter(Path.Combine(appData, $"{txbCompany.Text}_{txbSiteName.Text}.xml"), true))
{
x.Serialize(writer, companyProfile);
}
//Iterate the datasource list, NOT the DataGridView.
foreach (MachineProfile machineProfile in dsMachineProfile)
{
AppendMachineData(machineProfile, fileName: Path.Combine(appData, $"{txbCompany.Text}_{txbSiteName.Text}.xml"));
}
//Close form and open Main form
this.Hide();
frmMain fMain = new frmMain();
fMain.ShowDialog();
}
}
changed Code:
private void AppendMachineData(MachineProfile machineProfile, string fileName)
{
//Serialization of the MachineProle and append to the document
System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(typeof(MachineProfile));
var settings = new XmlWriterSettings();
using (var writer = new StreamWriter(fileName, true))
{
settings.Indent = true;
settings.OmitXmlDeclaration = true;
x.Serialize(writer, machineProfile);
}
}
I think in these two functions the problem is created but in fact I do not know why and how. Or maybe there is another way to solve this.
This is the code that I use to read the xml file
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
var filePath = string.Empty;
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData );
openFileDialog.Filter = "All files (*.*)|*.*";
openFileDialog.FilterIndex = 2;
openFileDialog.RestoreDirectory = true;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
//Get the path of specified file
filePath = openFileDialog.FileName;
XmlDocument doc = new XmlDocument();
doc.Load(filePath);
XmlNode node = doc.DocumentElement.SelectSingleNode("/CompanyName");
lblCompanyName.Text = node.InnerText;
}
}
}
Here is a screenshot of the Xml file
Below shows how to use XML serialization which allows one to use classes to store one's data and then serialize these classes to save the data to an XML file. Deserialization reads the data from the XML file and populates the classes.
Try the following:
To each of the classes below, add the following using statements
using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;
Create a class (name: XmlCompanyProfile.cs)
public class XmlCompanyProfile
{
public string CompanyName { get; set; }
public string SiteName { get; set; }
public int Imo { get; set; }
public int MachineTotal { get; set; }
}
If an element name isn't specified, the name of the property is used in the XML file.
Example 1:
public string CompanyName { get; set; }
By specifying an ElementName, one can make the property name different than the name used in the XML file.
Example 2:
[XmlElement(ElementName = "Name")]
public string CompanyName { get; set; }
Of course, one can also set the value of ElementName to the property name.
Example 3:
[XmlElement(ElementName = "CompanyName")]
public string CompanyName { get; set; }
Note: In Example 3, since the element name is set to the same value as the property name, it will have the same result as Example 1.
If one wishes to specify the element names, the XmlCompanyProfile class will look like the following instead:
public class XmlCompanyProfile
{
[XmlElement(ElementName = "CompanyName")]
public string CompanyName { get; set; }
[XmlElement(ElementName = "SiteName")]
public string SiteName { get; set; }
[XmlElement(ElementName = "Imo")]
public int Imo { get; set; }
[XmlElement(ElementName = "MachineTotal")]
public int MachineTotal { get; set; }
}
Create a class (name: XmlMachineProfile.cs)
public class XmlMachineProfile
{
[XmlElement(ElementName = "MachineName")]
public string MachineName { get; set; }
[XmlElement(ElementName = "NominalSpeed")]
public int NominalSpeed { get; set; }
}
Create a class (name: XmlRoot.cs)
[XmlRoot(ElementName = "Root")]
public class XmlRoot
{
[XmlElement(ElementName = "CompanyProfile")]
public XmlCompanyProfile CompanyProfile { get; set; } = new XmlCompanyProfile();
[XmlElement(ElementName = "MachineProfile")]
public List<XmlMachineProfile> MachineProfiles { get; set; } = new List<XmlMachineProfile>();
}
To serialize and deserialize the data:
Create a class (name: HelperXml.cs)
public static class HelperXml
{
public static T DeserializeXMLFileToObject<T>(string xmlFilename)
{
//Usage: Class1 myClass1 = DeserializeXMLFileToObject<Class1>(xmlFilename);
T rObject = default(T);
if (string.IsNullOrEmpty(xmlFilename))
{
throw new Exception($"Error: XML filename not specified (xmlFilename: '{xmlFilename}'");
}
using (System.IO.StreamReader xmlStream = new System.IO.StreamReader(xmlFilename))
{
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
rObject = (T)serializer.Deserialize(xmlStream);
}
return rObject;
}
public static void SerializeObjectToXMLFile(object obj, string xmlFilename)
{
//Usage: Class1 myClass1 = new Class1();
//SerializeObjectToXMLFile(myClass1, xmlFilename);
if (string.IsNullOrEmpty(xmlFilename))
{
throw new Exception($"Error: XML filename not specified (xmlFilename: '{xmlFilename}'");
}
System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings() { Indent = true, OmitXmlDeclaration = true};
using (System.Xml.XmlWriter xmlWriter = System.Xml.XmlWriter.Create(xmlFilename, settings))
{
//specify namespaces
System.Xml.Serialization.XmlSerializerNamespaces ns = new System.Xml.Serialization.XmlSerializerNamespaces();
ns.Add(string.Empty, "urn:none"); //eliminates "xsd" and "xsi" namespaces
//create new instance
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());
//serialize (write to XML file)
serializer.Serialize(xmlWriter, obj, ns);
}
}
}
Usage (serialization):
Note: In the code below, the name of the button is btnSerialize.
private XmlRoot _root = null;
...
private void btnSerialize_Click(object sender, EventArgs e)
{
//create new instance
_root = new XmlRoot();
//set CompanyProfile info
_root.CompanyProfile.CompanyName = "ABB";
_root.CompanyProfile.SiteName = "Rotterdam";
_root.CompanyProfile.Imo = 123456;
_root.CompanyProfile.MachineTotal = 3;
//add machine profile
_root.MachineProfiles.Add(new XmlMachineProfile() { MachineName = "Machine 1", NominalSpeed = 50 });
_root.MachineProfiles.Add(new XmlMachineProfile() { MachineName = "Machine 2", NominalSpeed = 60 });
_root.MachineProfiles.Add(new XmlMachineProfile() { MachineName = "Machine 3", NominalSpeed = 50 });
//prompt user for XML filename
using (SaveFileDialog sfd = new SaveFileDialog())
{
sfd.FileName = "Test.xml"; //default filename
sfd.Filter = "XML File (*.xml)|*.xml";
sfd.Title = "Save XML file";
if (sfd.ShowDialog() == DialogResult.OK)
{
//serialize
HelperXml.SerializeObjectToXMLFile(_root, sfd.FileName);
}
}
}
Usage (deserialization):
Note: In the code below, the name of the button is btnDeserialize.
private XmlRoot _root = null;
...
private void btnDeserialize_Click(object sender, EventArgs e)
{
//prompt user for XML filename
using (OpenFileDialog ofd = new OpenFileDialog())
{
ofd.Filter = "XML File (*.xml)|*.xml";
ofd.Title = "Open XML file";
if (ofd.ShowDialog() == DialogResult.OK)
{
//deserialize
_root = HelperXml.DeserializeXMLFileToObject<XmlRoot>(ofd.FileName);
System.Diagnostics.Debug.WriteLine($"CompanyName: '{_root.CompanyProfile.CompanyName}'");
}
}
}
Here's what the XML file looks like:
<Root>
<CompanyProfile>
<CompanyName>ABB</CompanyName>
<SiteName>Rotterdam</SiteName>
<Imo>123456</Imo>
<MachineTotal>3</MachineTotal>
</CompanyProfile>
<MachineProfile>
<MachineName>Machine 1</MachineName>
<NominalSpeed>50</NominalSpeed>
</MachineProfile>
<MachineProfile>
<MachineName>Machine 2</MachineName>
<NominalSpeed>60</NominalSpeed>
</MachineProfile>
<MachineProfile>
<MachineName>Machine 3</MachineName>
<NominalSpeed>50</NominalSpeed>
</MachineProfile>
</Root>
Resources:
XML serialization
Examples of XML Serialization
XDocument Class
JSON Utils
Related
I have a file .xml inside multiple xml in one line.
How can I read this file and convert to object?
I tried with this code it works if there is only one.
Please help and thank you all
[XmlRoot(ElementName = "DepartmentMaster")]
public class DepartmentMaster
{
[XmlElement(ElementName = "DepartmentId")]
public int DepartmentId { get; set; }
[XmlElement(ElementName = "Name")]
public string Name { get; set; }
[XmlElement(ElementName = "Description")]
public string Description { get; set; }
[XmlElement(ElementName = "test")]
public int Test { get; set; }
}
//string xml = "<DepartmentMaster><DepartmentId>267854</DepartmentId><Name>Purchase</Name><Description>Purchase Department</Description><test>1</test></DepartmentMaster>";
string xml = "<DepartmentMaster><DepartmentId>267854</DepartmentId><Name>Purchase</Name><Description>Purchase Department</Description><test>1</test></DepartmentMaster><DepartmentMaster><DepartmentId>267855</DepartmentId><Name>Purchase5</Name><Description>Purchase Department5</Description><test>5</test></DepartmentMaster>";
using (TextReader reader = new StringReader(xml))
{
System.Xml.Serialization.XmlSerializer deserializer = new System.Xml.Serialization.XmlSerializer(typeof(DepartmentMaster));
var model = (DepartmentMaster)deserializer.Deserialize(reader);
}
image from the database
image from the database
Here it is two approaches below.
The first is using setting to accept XML data with multiple root elements (ConformanceLevel.Fragment).
private static IList<DepartmentMaster> DeserializeFragment(string xml)
{
var settings = new XmlReaderSettings
{
ConformanceLevel = ConformanceLevel.Fragment
};
XmlReader reader = XmlReader.Create(new MemoryStream(Encoding.ASCII.GetBytes(xml)), settings);
var serializer = new XmlSerializer(typeof(DepartmentMaster));
var list = new List<DepartmentMaster>();
while (serializer.Deserialize(reader) is DepartmentMaster element)
{
list.Add(element);
}
return list;
}
And the second by adding a root element to deserialize a well-formed XML document.
public class DepartmentMasters
{
[XmlElement("DepartmentMaster")]
public List<DepartmentMaster> Items;
}
private static DepartmentMasters DeserializeWellFormedXML(string xml)
{
var text = #"<?xml version=""1.0""?><DepartmentMasters>" + xml + "</DepartmentMasters>";
var serializer = new XmlSerializer(typeof(DepartmentMasters));
return (DepartmentMasters)serializer.Deserialize(new StringReader(text));
}
This is a sample xml. If a new font is to be added in the sense, all the existing fonts to be compare with the new font before adding to the preference.
How do I check the node(font) whether already exists or not in case of XmlDocument?
<preferences>
<font role="console">
<size>9</size>
<fname>Courier</fname>
</font>
<font role="default">
<fname>Times New Roman</fname>
<size>14</size>
</font>
<font role="titles">
<size>10</size>
<fname>Helvetica</fname>
</font>
</preferences>
Xnode has a feature called DeepEqual to compare nodes. XmlNode can be converted into Xnode by simple parsing.
XElement XmlElementToXElement(XmlNode e)
{
return XElement.Parse(e.OuterXml);
}
So, it will be easier from here. The method below will return true if two nodes are equal.
bool XmlNode_DeepEquals(XmlNode node1, XmlNode node2)
{
XElement tempX = XmlElementToXElement(node2);
XElement searchX = XmlElementToXElement(node1);
return XNode.DeepEquals(tempX, searchX))
}
This method is for comparing a list of Node.
bool isNodeAlreadyExists(XmlNode searchNode, XmlNodeList list)
{
bool exists = false;
foreach (XmlNode node in list)
{
if (XmlNode_DeepEquals(searchNode, node))
{
exists = true;
}
}
return exists;
}
One approach would be to create a couple of classes to represent the XML document and implement the IEquatable<T> Interface.
https://dotnetfiddle.net/QZFwDy
Classes for XML
[XmlRoot(ElementName = "font")]
public class Font : IEquatable<Font>
{
[XmlElement(ElementName = "size")]
public string Size { get; set; }
[XmlElement(ElementName = "fname")]
public string Fname { get; set; }
[XmlAttribute(AttributeName = "role")]
public string Role { get; set; }
public bool Equals(Font font)
{
if (font == null) return false;
return (Size == font.Size) && (Fname == font.Fname) && (Role == font.Role);
}
}
[XmlRoot(ElementName = "preferences")]
public class Preferences
{
[XmlElement(ElementName = "font")]
public List<Font> Font { get; set; }
}
Then use the Preferences class to deserialize the XML. Once the document is deserialized, leverage the List<T>.Contains(T item) method to see if the font node exists. The .Contains method will call the implementation of Equals in the Font class.
Code to Demonstrate
static void Main(string[] args)
{
Preferences preferences = null;
var xmlString = Data.XML;
using (var stream = new StringReader(xmlString))
{
var serializer = new XmlSerializer(typeof(Preferences));
preferences = (Preferences)serializer.Deserialize(stream);
}
var node0 = new Font()
{
Fname = "New One",
Role = "console",
Size = "12"
};
var node1 = new Font()
{
Fname = "Helvetica",
Role = "titles",
Size = "10"
};
if (preferences.Font.Contains(node0))
{
// Not expecting to enter here
Console.WriteLine($"'{nameof(node0)}' is already present");
}
if (preferences.Font.Contains(node1))
{
Console.WriteLine($"'{nameof(node1)}' is already present");
}
}
How to get a namespace set at a child level element when serializing an object to XML with C#?
The XML I want to end up with this as the XML output:
<clsPerson>
<FirstName>Jeff</FirstName>
<MI>J</MI>
<LastName>Jefferson</LastName>
<ns1:Addresses xmlns="www.whatever.co.uk">
<Home>Here</Home>
<Work>There</Work>
</Addresses>
</clsPerson>
The code I'm using is mostly taken from other questions, and is as follows:
using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
public class clsPerson
{
public string FirstName;
public string MI;
public string LastName;
[XmlElement(Namespace = "www.whatever.co.uk")]
public clsPlaces Addresses;
public clsPerson()
{
clsPlaces clsPlaces = new clsPlaces();
}
}
[XmlRoot(Namespace = "")]
public class clsPlaces
{
public string Home { get; set; }
public string Work { get; set; }
}
class class1
{
static void Main(string[] args)
{
clsPerson p = new clsPerson();
var xml = "";
p.FirstName = "Jeff";
p.MI = "J";
p.LastName = "Jefefrson";
p.Addresses = new clsPlaces();
p.Addresses.Home = "Here";
p.Addresses.Work = "There";
var emptyNamepsaces = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty });
var serializer = new XmlSerializer(p.GetType());
var settings = new XmlWriterSettings();
settings.Indent = true;
settings.OmitXmlDeclaration = true;
emptyNamepsaces.Add("ns", "www.whatever.co.uk");
using (var stream = new StringWriter())
using (var writer = XmlWriter.Create(stream, settings))
{
serializer.Serialize(writer, p, emptyNamepsaces);
xml = stream.ToString();
}
Console.WriteLine(xml)
Console.ReadLine();
}
}
The above gives:
<clsPerson xmlns:ns="www.whatever.co.uk">
<FirstName>Jeff</FirstName>
<MI>J</MI>
<LastName>Jefefrson</LastName>
<ns:Addresses>
<Home>Here</Home>
<Work>There</Work>
</ns:Addresses>
How would I get the xmlns on the element only? I have tried everything I can see search stackoverflow, and not been able to find/understand the answer.
Thanks
Remove this - adding the namespace will ensure the prefix gets added to the root:
emptyNamepsaces.Add("ns", "www.whatever.co.uk");
The declaration for addresses will get added automatically. You also need to remove the empty namespace from clsPlaces, else the namspaces for Home and Work will be incorrect:
public class clsPlaces
{
public string Home { get; set; }
public string Work { get; set; }
}
The output will then look like this:
<clsPerson>
<FirstName>Jeff</FirstName>
<MI>J</MI>
<LastName>Jefefrson</LastName>
<Addresses xmlns="www.whatever.co.uk">
<Home>Here</Home>
<Work>There</Work>
</Addresses>
</clsPerson>
See this fiddle for a demo.
I create a form so I use textbox and I would like when I push the button "send" he filled xml :
for exemple 1 time :
<?xml version="1.0" encoding="utf-8"?>
<DonneesLocale>
<Donnee>
<id>1</id>
<libelle>bla </libelle>
<email_asso>bla#</email_asso>
<login>bla</login>
<psw>bla</psw>
<site>bla</site>
<description>bla</description>
<data_1_lib></data_1_lib>
<data_1_val></data_1_val>
<data_2_lib></data_2_lib>
<data_2_val></data_2_val>
</Donnee>
</DonneesLocale>
and 2nd time when I push the button:
<?xml version="1.0" encoding="utf-8"?>
<DonneesLocale>
<Donnee>
<id>1</id>
<libelle>bla </libelle>
<email_asso>bla#</email_asso>
<login>bla</login>
<psw>bla</psw>
<site>bla</site>
<description>bla</description>
<data_1_lib></data_1_lib>
<data_1_val></data_1_val>
<data_2_lib></data_2_lib>
<data_2_val></data_2_val>
</Donnee>
<DonneesLocale>
<Donnee>
<id>2</id>
<libelle>hello</libelle>
<email_asso>hello#</email_asso>
<login>hello</login>
<psw>hello</psw>
<site>hello</site>
<description>hello</description>
<data_1_lib></data_1_lib>
<data_1_val></data_1_val>
<data_2_lib></data_2_lib>
<data_2_val></data_2_val>
</Donnee>
</DonneesLocale>
Someone can help me please ?
(Sorry for my English !)
Thanks !
So if I get it correct, you want to append new data to your existing xml.
For that you can chose to temporarily store the current xml and and add new data to it using Linq Xml.
To do this, now you need to modify your current code with an additional check for xml file exists before all calls to press button event. The code for appending to xml can be found Appending an existing XML file with XmlWriter
If you are using a list of objects then you can update the list on button click and parse your object list in xml like below:
var xml = new XElement("DonneesLocales", DonneesLocalList.Select(x => new XElement("DonneesLocale",
new XElement("Donnee",
new XElement("id"),
new XElement("libelle"),
new XElement("email_asso"),
new XElement("login"),
new XElement("psw"),
new XElement("site"),
new XElement("description"),
new XElement("data_1_lib"),
new XElement("data_1_val"),
new XElement("data_2_lib"),
new XElement("data_2_val")))));
Another option is their for XML Serialization and Deserialization which will be done with the help of XMLSerializer,
public class DonneesLocale
{
private List<Donnee> donnee = new List<Donnee>();
[XmlArray("DonneesLocale")]
public List<Donnee> Donnee
{
get { return donnee; }
set { donnee = value; }
}
}
[XmlType("Donnee")]
public class Donnee
{
[XmlElement("id")]
public int id { get; set; }
[XmlElement("libelle")]
public string libelle { get; set; }
[XmlElement("email_asso")]
public string email_asso { get; set; }
[XmlElement("login")]
public string login { get; set; }
[XmlElement("psw")]
public string psw { get; set; }
[XmlElement("site")]
public string site { get; set; }
[XmlElement("description")]
public string description { get; set; }
[XmlElement("data_1_lib")]
public string data_1_lib { get; set; }
[XmlElement("data_1_val")]
public string data_1_val { get; set; }
[XmlElement("data_2_lib")]
public string data_2_lib { get; set; }
[XmlElement("data_2_val")]
public string data_2_val { get; set; }
}
DonneesLocale dnl = new DonneesLocale();
private void Serialize(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++)
{
var temp = new Donnee() { id = i, libelle = "libelle " + i, email_asso = "email_asso " + i, login = "login " + i, psw = "psw " + i, site = "site " + i, description = "description " + i, data_1_lib = "data_1_lib " + i, data_1_val = "data_1_val " + i, data_2_lib = "data_2_lib " + i, data_2_val = "data_2_val " + i };
dnl.Donnee.Add(temp);
}
try
{
// to Save columnorders to the file
var serializer = new XmlSerializer(typeof(DonneesLocale));
var ns = new XmlSerializerNamespaces();
ns.Add("", "");
using (TextWriter writer = new StreamWriter(#"Your XML Path"))
{
serializer.Serialize(writer, dnl, ns);
}
}
catch { }
}
private void Deserialize(object sender, EventArgs e)
{
try
{
if (File.Exists(#"Your XML Path"))
{
var deserializer = new XmlSerializer(typeof(DonneesLocale));
using (TextReader reader = new StreamReader(#"Your XML Path"))
{
dnl = (DonneesLocale)deserializer.Deserialize(reader);
}
}
}
catch
{
}
}
all you need is to add an object to the list and serialize the object to XML whenever you want,
this will work as you expected,
I have a situation where in I have to read my master data from XML files.
Hence I have created a Repository which looks like this.
public class XmlReadRepository<T> : IReadRepository<T> where T : class, new()
{
private IEnumerable<T> _data { get; set; }
private IQueryable<T> _query { get; set; }
public XmlReadRepository()
{
Type t = typeof(T);
//Load _data from xml
}
public IQueryable<T> All()
{
return _query;
}
public IQueryable<T> Get(System.Linq.Expressions.Expression<Func<T, bool>> filter = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, string includeProperties = "")
{
throw new NotImplementedException();
}
}
I have exported all my SQL database data into XML file using below SQL query
SELECT *
FROM Company
FOR XML RAW, ROOT('Company')
Whose outputs comes as below
<Company>
<row Id="1" Name="ABC" StartDate="2000-03-01" />
<row Id="2" Name="XYZ" StartDate="2001-13-11" />
</Company>
The xml is physically saved to a file and is embedded as a resource.
Now I am looking for some fast way to serialize the xml data into list.
I have tried loading the xml file with stream and then using reflection created objects by iterating through the XML. Is there any better way by which I can serialize the xml data to my C# object.
Also please share your inputs on whether is it good to have xml as an embedded resource as the size of each xml can be around 8MB and there are 5 such XMLs.
You can turn my code into a function
public class Row
{
private static XmlTextReader reader = null;
public int Id { get; set; }
public string name { get; set; }
public DateTime startDate { get; set; }
public Row() { }
public Row(TextReader sReader)
{
reader = new XmlTextReader(sReader); //can be filename instead of stringreader
}
public Row Get(string elementName)
{
Row results = null;
if (!reader.EOF)
{
if (reader.Name != elementName)
{
reader.ReadToFollowing(elementName);
}
if (!reader.EOF)
{
XElement newRow = (XElement)XElement.ReadFrom(reader);
results = new Row() { Id = (int)newRow.Attribute("Id"), name = (string)newRow.Attribute("Name"), startDate = (DateTime)newRow.Attribute("StartDate") };
}
}
return results;
}
}
Use xml linq like below
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string xml =
"<Company>" +
"<row Id=\"1\" Name=\"ABC\" StartDate=\"2000-03-01\" />" +
"<row Id=\"2\" Name=\"XYZ\" StartDate=\"2001-13-11\" />" +
"</Company>";
XDocument doc = XDocument.Parse(xml); // use Load to read from file
var rows = doc.Descendants("row").Select(x => new
{
id = (int)x.Attribute("Id"),
name = (string)x.Attribute("Name"),
startDate = (DateTime)x.Attribute("StartDate")
}).ToList();
//using xmltextreader
List<Row> rows2 = new List<Row>();
StringReader sReader = new StringReader(xml);
XmlTextReader reader = new XmlTextReader(sReader); //can be filename instead of stringreader
while(!reader.EOF)
{
if (reader.Name != "row")
{
reader.ReadToFollowing("row");
}
if (!reader.EOF)
{
XElement newRow = (XElement)XElement.ReadFrom(reader);
rows2.Add(new Row() { Id = (int)newRow.Attribute("Id"), name = (string)newRow.Attribute("Name"), startDate = (DateTime)newRow.Attribute("StartDate") });
}
}
}
}
public class Row
{
public int Id { get; set; }
public string name { get; set; }
public DateTime startDate { get; set; }
}
}