I try to read data from a Xml file. My plan is to save all students as an object of Student with the name and the semester.
<persons>
<student><name>255211</name><semester>MI</semester></student>
<student><name>255212</name><semester>MI</semester></student>
<student><name>255213</name><semester>MI</semester></student>
</persons>
I found a guide with XmlReader and switch case so i tried it.
private static void readData()
{
XmlTextReader reader = new XmlTextReader("data.xml");
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case "student":
Student student = new Student();
Students.Add(student);
break;
case "name":
student.name = reader.ReadString();
//Console.WriteLine(student.name);
break;
case "semester":
student.semester = reader.ReadString();
break;
}
}
}
reader.Close();
}
My problem now is that Visual Studio Code gives me an error: error CS0165: Use of unassigned local variable 'student' (student.name in case "name"). I guess it is because there wouldn't be a student.name if the code does not go into case "student". I tried with try catch but that didn't helped me.
How can I achieve that every student gets his name and semester correct?
You only assign student
in the "student"
case; from the compiler's point of view, student
is unassigned at the start of the "name"
and "semester"
cases, so you can't set properties on them. You might have knowledge that <student>
always comes first, but the compiler doesn't know that. Also, from it's view, the scope is separate for each element. But if you're 100% sure that there's always a <student>
between each then you could probably move the assignment around a little:
Student student = null;
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case "student":
student = new Student();
Students.Add(student);
break;
case "name":
student.name = reader.ReadString();
//Console.WriteLine(student.name);
break;
case "semester":
student.semester = reader.ReadString();
break;
}
}
}
However, in reality, in most scenarios, I would strongly recommend using XmlSerializer
or similar to parse the input into objects, and then just deal with them as objects.
Based on the xml layout in the question, this should work:
public class Student {
[XmlElement("name")]
public string Name {get;set;}
[XmlElement("semester")]
public string Semester {get;set;}
}
[XmlRoot("persons")]
public class SomeData {
[XmlElement("student")]
public List<Student> Students {get;} = new List<Student>();
}
and:
var ser = new XmlSerializer(typeof(SomeData));
var data = (SomeData)ser.Deserialize(source);
List<Student> students = data.Students;