C#: How to save list of objects to XML - c#

I am a beginner in XML and I would like to save Students with their fields into XML. But I dont know how to save "type" as object. Here is my code:
class Student
{
private int id;
private string name;
private string surname;
public Type type;
public Student(int id, string name, string surname, Type type)
{
this.id = id;
this.name = name;
this.surname = surname;
this.type = type;
}
}
class Type
{
private string ID;
private string name;
public Odbor(string ID, string name)
{
this.ID = ID;
this.name= name;
}
}
class Program
{
static void Main(string[] args)
{
Type type1 = new Type("IRT","info");
Type type2 = new Type("MATH","mathematic");
List<Student> Students = new List<Student>();
Students.Add(new Student(10,"Jon","Snow", type1));
Students.Add(new Student(11,"Ned","Stark", type2));
//Save Students to XML
}
}
Thanks for help.

You can try something like this : Note This code is for example purposes only and can be made much better
using System.Xml.Linq;
class Student {
public int id;
public string name;
public string surname;
public Type type;
public Student(int id, string name, string surname, Type type)
{
this.id = id;
this.name = name;
this.surname = surname;
this.type = type;
}
}
class Type
{
public string ID;
public string name;
public Type(string ID, string name)
{
this.ID = ID;
this.name = name;
}
}
class Program
{
static void Main(string[] args)
{
Type type1 = new Type("IRT", "info");
Type type2 = new Type("MATH", "mathematic");
List<Student> Students = new List<Student>();
Students.Add(new Student(10, "Jon", "Snow", type1));
Students.Add(new Student(11, "Ned", "Stark", type2));
//Save Students to XML
XElement xmlElements = new XElement("Students");
foreach (Student student in Students)
{
var xmlstudent = new XElement("student");
var xmlstudenttype = new XElement("studenttype");
xmlstudenttype.Add(new XAttribute("ID", student.type.ID),
new XAttribute("name",student.type.name));
xmlstudent.Add(new XAttribute("id", student.id),
new XAttribute("name", student.name),
new XAttribute("surname", student.surname),
new XElement("type", xmlstudenttype));
xmlElements.Add(xmlstudent);
}
System.Console.Write(xmlElements);
System.Console.Read();
}
}

Related

Type casting in C# .net

I am learning a MOOC course on c#. we had to create an Arraylist of type students and then using the foreach loop had to iterate over it and print the names. i have tried all casting methods but could not get through it. please help
c.students.Add(student1);
c.students.Add(student2);
c.students.Add(student3);
foreach(object o in students)
{
Student s = (Student)o;
Console.WriteLine(s.FirstName);
}
c is the course object. course is a class. students is the arraylist. Student is a class.
Not sure where you face the error. Check out my .NET Fiddle here. Code shown below as well. Hope it helps.
using System;
using System.Collections;
public class Program
{
public static void Main()
{
var students = new ArrayList();
students.Add(new Student() { FirstName = "John", LastName = "Doe" });
students.Add(new Student() { FirstName = "Richard", LastName = "Roe" });
foreach(Student s in students)
{
Console.WriteLine(s.FirstName);
}
}
}
public class Student
{
public string FirstName {get;set;}
public string LastName {get;set;}
}
foreach(object o in c.students)
this should do it, its probably a silly mistake
namespace stackOverflow
{
class Program
{
static void Main(string[] args)
{
course c = new course();
student student1 = new student("a");
student student2 = new student("b");
student student3 = new student("c");
c.students.Add(student1);
c.students.Add(student2);
c.students.Add(student3);
foreach (object o in c.students)
{
student s = (student)o;
Console.WriteLine(s.name);
}
}
}
class course
{
public List<student> students = new List<student>();
}
class student
{
public string name { get; set; }
public student(string s)
{
name = s;
}
}
}
ArrayList students = new ArrayList();
This line should be: c.students = new ArrayList(); as mentioned by Channs previously.
As you have written it, it is trying to create a new variable in your main function called students, it never accesses the students array inside your course object.
Although your initialisation of internal object variables should be done within the object itself.
So inside your course object do something more like this:
class Course
{
public ArrayList students;
public Course()
{
students = new ArrayList();
}
}
This way, whenever you declare a new object of type Course ( ie: Course c = new Course() ) it will initialise the array automatically.
Another issue I noticed was in your Student constructor declaration, you are always trying to take a parameter of string fname.
public Student(string fname)
Then in your code you never pass that data ie:
Student student1 = new Student();
So either pass the firstname variable in when you are initialising or change your constructor in Student to allow it to accept nothing as well as a firstname as shown below:
class Student
{
private string firstName;
private string lastName;
public Student(string fname = null)
{
this.FirstName = fname;
}
this way you don't have to pass the data, but if you do it will be copied over to the firstname of the student object.
You could always change the null to something like "John" or "No Name" so that you have printable data in the object. just a suggestion though.
Regards,
Slipoch
Here is your code fixed up. There were 2 things:
Your student class did not have a default constructor.
Your student array list was not initialized in the course class.
Hope this helps.
using System;
using System.Collections;
class Program
{
public static void Main(string[] args)
{
Student student1 = new Student();
student1.FirstName = "a";
student1.LastName = "w";
Student student2 = new Student();
student2.FirstName = "e";
student2.LastName = "s";
Student student3 = new Student();
student3.FirstName = "i";
student3.LastName = "o";
Course c = new Course();
ArrayList students = new ArrayList();
c.students.Add(student1);
c.students.Add(student2);
c.students.Add(student3);
foreach (Student o in c.students)
{
Student s = (Student)o;
Console.WriteLine(s.FirstName);
}
Console.ReadLine();
}
}
internal class Course
{
public ArrayList students = new ArrayList();
}
internal class Student
{
private string firstName;
private string lastName;
public Student()
{
}
public Student(string fname)
{
this.FirstName = fname;
}
public string FirstName
{
get
{
return firstName;
}
set
{
firstName = value;
}
}
public string LastName
{
get
{
return lastName;
}
set
{
lastName = value;
}
}
}

How count number of objects created with a static class variable?

I created 3 objects of a class and I want to display on the console how many objects I have created (using a static class variable) - How do I do this ?
I put public static int count = 0; in the class I created but I couldn't get it to increment (count++;) based on how many objects I created of the class. I created the 3 objects in the main method and gave them values for variables.
here is the class I created in my program :
public class Student
{
public static int count = 0;
// count++;
private string firstName;
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
private string lastName;
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
private string birthDate;
public string BirthDate
{
get { return birthDate; }
set { birthDate = value; }
}
}
In the main method I created 3 objects of class Student:
static void Main(string[] args)
{
// Create 3 students
Student student1 = new Student
{
FirstName = "John",
LastName = "Wayne",
BirthDate = "26/05/1907"
};
Student student2 = new Student
{
FirstName = "Craig",
LastName = "Playstead",
BirthDate ="01/01/1967"
};
Student student3 = new Student
{
FirstName = "Paula",
LastName = "Smith",
BirthDate = "01/12/1977"
};
// Console.WriteLine("The course contains {1} students(s) " studentCounter );
I can't get the counter to ++ based on the way I created the objects.
Increment the count in the constructor:
public class Student
{
public static int count = 0;
public Student()
{
// Thread safe since this is a static property
Interlocked.Increment(ref count);
}
// use properties!
public string FirstName { get; set; }
public string LastName { get; set; }
public string BirthDate { get; set; }
}
You just need a constructor, there you can increment the count.
public Student()
{
count++;
}
You can increment the counter in the constructor
public Student()
{
count++;
}
To print the count variable
we should write some code like below
public static int GetCount()
{
return count;
}
and main class look like :
static void Main(string[] args)
{
// Create 3 students
Student student1 = new Student
{
FirstName = "John",
LastName = "Wayne",
BirthDate = "26/05/1907"
};
Student student2 = new Student
{
FirstName = "Craig",
LastName = "Playstead",
BirthDate ="01/01/1967"
};
Student student3 = new Student
{
FirstName = "Paula",
LastName = "Smith",
BirthDate = "01/12/1977"
};
//To print the count
Console.WriteLine(" Number of Objects is : "+Student.GetCount());
}
and if we have parameterized constructor then we also have to write count++ in that constructor.

Removing the optional fields from writing to text field Filehelpers

How do I go about removing the optional field from the text field that I have output using the Filehelpers library. I'm using c#
For example,
I have a shared class file
with attributes such as recordnumber, filler, payment, endingspaces
Then I need to write only recordnumber and payment into the text file without the filler.
[FixedLengthRecord(FixedMode.ExactLength)]
public partial class Person
{
[FieldFixedLength(10)]
public string FirstName;
[FieldFixedLength(10)]
public string LastName;
[FieldOptional]
[FieldFixedLength(5)]
public string Optional1;
[FieldOptional]
[FieldFixedLength(5)]
public string Optional2;
[FieldOptional]
[FieldFixedLength(5)]
public string Optional3;
}
class Program
{
private static void Main(string[] args)
{
var engine = new FileHelperEngine<Person>();
Person[] allPersonRecords = GetPersonExportFromDataBase() as Person[];//This will only get the FirstName,LastName,Optional2. No result for Optional1 and Optional3
FileHelperEngine enginePerson = new FileHelperEngine(typeof(Person));
enginePerson.AppendToFile(FileName, allPersonRecords ); //Write the records to the file
//Current Output looks like this:John Lee title
//The output which I want is:John Lee title
}
}
You can use the INotifyWrite attribute to intercept the line before it is written and modify it. Here is a working example.
[DelimitedRecord(",")]
public partial class Person : INotifyWrite<Person>
{
public string FirstName;
public string LastName;
[FieldOptional]
public string Optional1;
[FieldOptional]
public string Optional2;
[FieldOptional]
public string Optional3;
public void BeforeWrite(BeforeWriteEventArgs<Person> e)
{
}
public void AfterWrite(AfterWriteEventArgs<Person> e)
{
// count the non-optional fields
var numberOfNonOptionalFields = typeof(Person).GetFields()
.Where(f => !f.GetCustomAttributes(false).Any(a => a is FieldOptionalAttribute))
.Count();
// take only the first n tokens
e.RecordLine = String.Join(",", e.RecordLine.Split(',').Take(numberOfNonOptionalFields));
}
}
class Program
{
private static void Main(string[] args)
{
var engine = new FileHelperEngine<Person>();
var export = engine.WriteString(
new Person[] {
new Person() {
FirstName = "Joe",
LastName = "Bloggs",
Optional1 = "Option 1",
Optional2 = "Option 2",
Optional3 = "Option 3"
}
});
Assert.AreEqual("Joe,Bloggs" + Environment.NewLine, export);
Console.WriteLine("Export was as expected");
Console.ReadLine();
}
}
If you want to just statically omit the optional fields (i.e. they are never used and you never want to output them) you could just create another class representing the desired output format and then convert the list from one object type to another using LINQ:
class Program
{
static void Main(string[] args)
{
// dummy test data
var originalAllPersonRecords = new Person[]
{
new Person { FirstName = "John", LastName = "Lee", Optional2 = "title" },
};//This will only get the FirstName,LastName,Optional2. No result for Optional1 and Optional3
var allPersonRecords = from p in originalAllPersonRecords select new OutputPerson{ FirstName = p.FirstName, LastName = p.LastName, Optional2 = p.Optional2 };
FileHelperEngine enginePerson = new FileHelperEngine(typeof(OutputPerson));
string fileName = "Wherever you want the file to go";
enginePerson.AppendToFile(fileName, allPersonRecords); //Write the records to the file
//Current Output looks like this:John Lee title
//The output which I want is:John Lee title
}
}
//New class added representing the output format
[FixedLengthRecord(FixedMode.ExactLength)]
class OutputPerson
{
[FieldFixedLength(10)]
public string FirstName;
[FieldFixedLength(10)]
public string LastName;
[FieldOptional]
[FieldFixedLength(5)]
public string Optional2;
}
[FixedLengthRecord(FixedMode.ExactLength)]
class Person
{
[FieldFixedLength(10)]
public string FirstName;
[FieldFixedLength(10)]
public string LastName;
[FieldOptional]
[FieldFixedLength(5)]
public string Optional1;
[FieldOptional]
[FieldFixedLength(5)]
public string Optional2;
[FieldOptional]
[FieldFixedLength(5)]
public string Optional3;
}

How to create an array to hold structures?

I was asked to create some structures: student, teacher, course, program
and then make an array to hold 5 students structures, and assign values to the fields of students in the array, I'm stuck in creating the array to hold the structures, here is the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Module4Assignment
{
class Program
{
//Student structure:
public struct Student
{
public Student (string name , string address , string country , string birthday , int telephone)
{
this.Name = name;
this.Address = address;
this.Country = country;
this.Birthday = birthday;
this.Telephone =telephone;
}
public string Name;
public string Address;
public string Country;
public string Birthday;
public int Telephone;
}
//Teacher structure:
public struct Teacher
{
public Teacher(string tname, string taddress, string tcountry, string tbirthday, int ttelephone)
{
this.TName = tname;
this.TAddress = taddress;
this.TCountry = tcountry;
this.TBirthday = tbirthday;
this.TTelephone = ttelephone;
}
public string TName;
public string TAddress;
public string TCountry;
public string TBirthday;
public int TTelephone;
}
//Program structure
public struct Program
{
public Program(string pname , string department , int pcredits)
{
this.PName = pname;
this.Department = department;
this.PCredits = pcredits;
}
public string PName;
public string Department;
public int PCredits;
}
//Course structure
public struct Course
{
public Course(string cname, string day, int ccredits)
{
this.CName = cname;
this.Day = day;
this.CCredits = ccredits;
}
public string CName;
public string Day;
public int CCredits;
}
static void Main(string[] args)
{
//Instantiating 5 students structures:
Student student1 = new Student();
Student student2 = new Student();
Student student3 = new Student();
Student student4 = new Student();
Student student5 = new Student();
//creating the array:
string[] studentArray = new string[5];
studentArray[0]=student1;
studentArray[1]=student2;
studentArray[2]=student3;
studentArray[3]=student4;
studentArray[4]=student5;
}
}
}
I have a lot of problems with what you're doing here, but the simple answer is that you cant put Student objects into an array of strings:
static void Main(string[] args)
{
//Instantiating 5 students structures :
Student student1 = new Student();
Student student2 = new Student();
Student student3 = new Student();
Student student4 = new Student();
Student student5 = new Student();
//creating the array :
Student [] studentArray = new Student[5]; // <---- array of Student!
studentArray[0]=student1;
studentArray[1]=student2;
studentArray[2]=student3;
studentArray[3]=student4;
studentArray[4]=student5;
}
static void Main(string[] args)
{
Student[] studentArray = new Student[5];
}
That's it. You do not need to explicitly create and assign the elements, because Student is a struct (value type).
what you did on the code above is a repetition of just creating an array of a structure because you are supposed to create 5 structures with the properties of the original structure so you should do it like this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace EDXonline_AssignmentFour
{
class Program
{
static void Main(string[] args)
{
student[] studentArray = new student[5];
studentArray[0].FirstName = "einstein";
studentArray[0].LastName = "makuyana";
DateTime date1 = new DateTime(1993, 11, 22, 02, 00, 0);
studentArray[0].Birthdate = date1;
Console.WriteLine("student First Name: {0}", studentArray[0].FirstName);
Console.WriteLine("student Last Name: {0}", studentArray[0].LastName);
Console.WriteLine("student birthday: {0}", studentArray[0].Birthdate.ToString());
Console.ReadKey();
}
public struct student
{
// This is the custom constructor.
public student(string firstname, string lastname, DateTime birthdate)
{
this.FirstName = firstname;
this.LastName = lastname;
this.Birthdate = birthdate;
}
// These statements declare the struct fields and set the default values.
public string FirstName;
public string LastName;
public DateTime Birthdate;
}

Display Data from a class

How can i show Data from a class into a gridview?
MY Class is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
public class EmployeeDetails
{
private int employeeID;
public int EmployeeID
{
get
{
return employeeID;
}
set
{
employeeID = value;
}
}
private string firstName;
public string FirstName
{
get
{
return firstName;
}
set
{
firstName = value;
}
}
private string lastName;
public string LastName
{
get
{
return lastName;
}
set
{
lastName = value;
}
}
private string titleOfCourtesy;
public string TitleOfCourtesy
{
get
{
return titleOfCourtesy;
}
set
{
titleOfCourtesy = value;
}
}
public EmployeeDetails(int employeeID, string firstName, string lastName, string titleOfCourtesy)
{
EmployeeID = employeeID;
FirstName = firstName;
LastName = lastName;
TitleOfCourtesy = titleOfCourtesy;
}
}
I`ve done this:
protected void Page_Load(object sender, EventArgs e)
{
int id = 15;
string f_name = "asd";
string l_name = "asd";
string title = "asd";
EmployeeDetails emp = new EmployeeDetails(id,f_name,l_name,title);
emp.EmployeeID = id;
emp.FirstName = f_name;
emp.LastName = l_name;
emp.TitleOfCourtesy = title;
}
List<EmployeeDetails> lst = new List<EmployeeDetails>() ;
GridView1.DataSource = lst ;
GrdiView1.DataBind();
you may populate the list with your EmployeeDetails Objects
A GridView is generally used to display multiple objects/rows. To get it to display your class you need to make a collection containing your class, such as a List<EmployeeDetails>. Then bind that to your gridview.
You could use another control more suited to displaying a single object such as a DetailsView.
I assume you are looking for an answer to show multiple item instead of just 1.
C#
var myList = List<EmploymentDetails>();
foreach (var employee in SomeOtherDataSource)
{
EmployeeDetails emp = new EmployeeDetails{EmployeeID = id, FirstName = f_name, LastName = l_name, TitleOfCourtesy = title};
myList.Add(emp);
}
var EmployeeDS = from eds in myList select new { ID = EmployeeID, FName = FirstName, LName = LastName, Title = TitleofCourtest };
MyGridview.DataSource = EmployeeDS;
MyGridView.DataBind();
By doing this: var EmployeeDS = from eds in myList select new { ID = EmployeeID, FName = FirstName, LName = LastName, Title = TitleofCourtest }; it makes it possible to just use <%# Eval('ID/FName/LName/Title'%> in the GridView's boundfields instead of those long variable names you've made in your entity class.

Categories