Click here to Skip to main content
15,881,173 members
Articles / Programming Languages / XML
Tip/Trick

Convert XML to Object using LINQ

Rate me:
Please Sign up or sign in to vote.
4.80/5 (14 votes)
17 Apr 2012CPOL1 min read 89.8K   16   7
Convert complex XML to an object using LINQ

Introduction

I had a requirement as part of my assignment to convert complex XML to an object using LINQ.

The same thing using XML serialization and deserialization is available at this link.

Using the Code

We need to create the XML file in this format:

XML
<students>
 <student>
  <name>Raju</name>
  <batch>III</batch>
  <school>School Name</school >
  <marks>
   <mark>
    <term>I</term>
    <science>46</science>
    <mathematics>50</mathematics >
    <language>46</language>
    <result>Pass</result>
    <comments>
     <teacher>good</teacher>
     <parent></parent>
    </comments>
   </mark>
   <mark>
    <term>II</term>
    <science>47</science>
    <mathematics >45</mathematics>
    <language>48</language>
    <result>Pass</result>
    <comments>
     <teacher>need to improve</teacher>
     <parent>thanks</parent>
    </comments>
   </mark>
  </marks>
 </student>
</students>

Here the XML format is fairly simple – we need to convert this XML to a class object containing object array (for <marks> node) using LINQ.

A brief explanation about this XML structure is given below.

From Top Node

  • Each student has name, batch and school
  • Each student has multiple term marks (example, First Term/Second Term, etc.)
  • In each term, there will be separate comments about student performance (teacher/parent)

How do we convert this as an object?

It is really simple ... we start from the bottom i.e., <comments>.

Step I: Convert <comments> as class:

XML
<comments>
  <teacher>need to improve</teacher>
  <parent>thanks.</parent>
</comments>
public class Comment
{
    private string _teacherComment;
    private string _parentComment;
    public string TeacherComment
    {
        get { return _teacherComment; }
        set { _teacherComment = value; }
    }
    public string ParentComment
    {
        get { return _parentComment; }
        set { _parentComment = value; }
    }
}

Step II: Convert <mark> as class:

XML
<mark>        
    <term>I</term>
    <science>46</science>
    <mathematics>50</mathematics >
    <language>46</language>
    <result>Pass</result>
    <comments>
      <teacher>good</teacher>
      <parent></parent>
    </comments>
</mark>
public class Mark
{
  private string _term;
  private string _science;
  private string _mathematics;
  private string _language;
  private string _result;
  public string Term
 {
   get { return _term; }
   set { _term = value; }
 }
 public string Science { get / set }
 …
 …
 public string Result { get / set }
 public Comment objComment = new Comment();
}

Here we added Comment within Mark class -i.e.,

C#
public Comment objComment = new Comment();

As I mentioned at the top, a student can have multiple marks based on the term/session. so we need to create List <T> of marks as below:

C#
List<Mark> objMarkList = new List<Mark>();

Step III: Create a class for <student>:

C#
public class Student
{
    private string _studentName;
    private string _batch;
    private string _school;
    public string StudentName 
        { get { return _studentName; } set { _studentName = value; } }
    public string Batch 
        { get { return _batch; } set { _batch = value; } }
    public string School 
        { get { return _school; } set { _school = value; } }
    public List<Mark> objMarkList = new List<Mark>();
}

We have created a Student class with Mark which contains Comment.

Let’s move to LINQ

C#
XDocument xdoc1 = XDocument.Load("your xml Path");
Student objStudent = new Student(); 
List<Student> lstStudent
   = (from _student in xdoc1.Element("students").Elements("student")
      select new Student
      {
          StudentName = _student.Element("name").Value,
          Batch = _student.Element("batch").Value,
          School = _student.Element("school").Value,
          objMarkList = (from _marks in _student.Element("marks").Elements("mark")
                         select new Mark
                         {
                             Term  = _marks.Element("term").Value,
                             Science  = _marks.Element("science").Value,
                             Mathematics  = _marks.Element("mathematics").Value,
                             Language  = _marks.Element("language").Value,
                             Result = _marks.Element("result").Value,
                             objComment = (from _cmt in _marks.Elements("comments")
                                           select new Comment
                                           {
                                               TeacherComment = _cmt.Element("teacher").Value,
                                               ParentComment = _cmt.Element("parent").Value
                                           }).FirstOrDefault(),
                         }).ToList()
      }).ToList();
foreach (var _stud in lstStudent)
{
  // Your code
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
PraiseSimple, elegant and useful. Pin
marcelo iván rojas hernández14-Jun-18 9:39
marcelo iván rojas hernández14-Jun-18 9:39 
GeneralMy vote of 5 Pin
Jesus Bocanegra12-Mar-13 5:58
Jesus Bocanegra12-Mar-13 5:58 
Questionthe LINQ can be reduced to a single statement too Pin
S@53K^S18-Apr-12 6:09
S@53K^S18-Apr-12 6:09 
QuestionI agree with John Pin
Mehdi Gholam16-Apr-12 4:01
Mehdi Gholam16-Apr-12 4:01 
AnswerRe: I agree with John Pin
Naufel Basheer17-Apr-12 1:29
Naufel Basheer17-Apr-12 1:29 
QuestionWhy use this over XmlSerialize? Pin
John Brett16-Apr-12 2:06
John Brett16-Apr-12 2:06 
It would be useful if you could explain why you don't just use the built-in Xml serialization support.
There are a number of reasons why you might choose to do this, but there are also reasons for not doing so.
How, for example, do you manage and justify the fragility of having the serialization code duplicate the object layout and hierarchy?
AnswerRe: Why use this over XmlSerialize? Pin
Naufel Basheer17-Apr-12 1:28
Naufel Basheer17-Apr-12 1:28 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.