Written by 10:35 ASP .NET CORE, Languages & Coding, Uncategorized

XML Made Easy – LINQ to XML

After reading the following 12 key facts about MySQL ENUM, you can decide if this is good for your next database or table in MySQL.

LINQ to XML is an in-memory XML programming interface that enables XML manipulation. Similar to the more traditional Document Object Model (DOM), LINQ to XML brings XML documents into memory and lets you query and modify them before saving the results to a file or data stream. What is different from the DOM is the new, lighter, and more intuitive object model and LINQ integration.

Integration to LINQ allows for querying XML elements similarly as it does with all the other object collections that implement IEnumerable interface.

In addition to advanced querying, LINQ to XML enables using query results as a parameter to XElement and XAttribute object constructors which provides easy XML data and structure manipulation.

Generating XML Trees

To jump-start our examples, we will use our Faculty data model from previous articles to combine LINQ to Entities and LINQ to XML features.

Let’s see how difficult it is to export data from the database to a single XML file. using (var db = new FacultyContext())

{ 
   var studentsXml = db.Students.ToList() 
      .Select(m => new XElement("Student", new XAttribute("ID", m.Id), 
            new XAttribute("FirstName", m.FirstName), 
            new XAttribute("LastName", m.LastName), 
            new XAttribute("BirthYear", m.BirthYear), 
            new XAttribute("Gender", m.Gender), 
            new XAttribute("Interests", m.Interests))).ToList(); 
   var subjectsXML = db.Subjects.ToList() 
      .Select(m => new XElement("Subject", new XAttribute("ID", m.Id), 
            new XAttribute("Name", m.Name),
            new XAttribute("StartDate", m.StartDate), 
            new XAttribute("TeacherId", m.TeacherId), 
            new XAttribute("Capacity", m.Capacity), 
            new XAttribute("DateAdded", m.DateAdded), 
            new XElement("StudentIds", m.Students.Select(s => s.Id).ToList() 
                        .Select(sid => new XElement("Student", new XAttribute("ID", 
sid))).ToList()) 
               )).ToList(); 
   var teachersXml = db.Teachers.ToList() 
      .Select(m => new XElement("Teacher", new XAttribute("ID", m.Id), 
            new XAttribute("FirstName", m.FirstName), 
            new XAttribute("LastName", m.LastName))).ToList(); 
   var xmlDoc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"), 
            new XComment("Faculty XML representation"), 
            new XElement("Faculty", 
                        new XElement("Students", studentsXml), 
                        new XElement("Subjects", subjectsXML), 
                        new XElement("Teachers", teachersXml) 
                        ) 
            ); 
      xmlDoc.Save("Faculty.xml"); 
}

Here we can see how easy it is to create the XML tree using LINQ to XML. Resulting XML is <?xml version=”1.0″ encoding=”utf-8″ standalone=”yes”?>

<!--Faculty XML representation--> 
<Faculty> 
     <Students> 
               <Student ID="3" FirstName="Ivan" LastName="Matec" BirthYear="1984" Gender="Male"               Interests="Programming, Math" /> 
               <Student ID="4" FirstName="Student 2" LastName="Last Name 2" BirthYear="1988" Gender="Female" Interests="Economy" /> 
               <Student ID="5" FirstName="Student 3" LastName="Last Name 3" BirthYear="1975" Gender="Female" Interests="Biology, Math" /> 
               <Student ID="6" FirstName="Student 4" LastName="Last Name 4" BirthYear="1991" Gender="Male" Interests="Politics" /> 
     </Students> 
     <Subjects> 
               <Subject ID="3" Name="Math" StartDate="2021-06-01T21:15:12.377" TeacherId="1" Capacity="30" DateAdded="1900-01-01T00:00:00"> 
                    <StudentIds> 
                              <Student ID="4" /> 
                              <Student ID="5" /> 
                              <Student ID="6" /> 
                    </StudentIds> 
     </Subject> 
     <Subject ID="4" Name="Programming" StartDate="2021-06-01T21:28:33.467" TeacherId="2" Capacity="30" DateAdded="2021-05-22T21:28:33.467"> 
     <StudentIds> 
               <Student ID="4" /> 
               <Student ID="6" />
     </StudentIds> 
     </Subject> 
     <Subject ID="7" Name="Biology" StartDate="2021-06-30T00:00:00" TeacherId="3" Capacity="25" DateAdded="1900-01-01T00:00:00"> 
     <StudentIds /> 
     </Subject> 
     </Subjects> 
     <Teachers> 
     <Teacher ID="1" FirstName="Teacher 1" LastName="One" /> 
     <Teacher ID="2" FirstName="Teacher 2" LastName="Two" /> 
     <Teacher ID="3" FirstName="Teacher 3" LastName="Three" /> 
   </Teachers> 
</Faculty>

Querying XML

Loading XML file is straightforward:

var xmlDoc = XElement.Load("Faculty.xml");

To get the list of students we can use the Descendants method:

var students = xmlDoc.Descendants("Student");

If we want to get only female students from the XML list of students, we can simply query the list of XElement objects the same way as any other collection of objects.

var femaleStudents = xmlDoc.Descendants("Student").Where(m => (string)m.Attribute("Gender") == "Female");

The following table presents examples of LINQ queries on an XElement list along with the corresponding LINQ to Entities query:

Query Description LINQ to XML query LINQ to Entities query
Get first and last name for all studentsxmlDoc.Descendants(“Student”). Select(m => new { FirstName = (string)m.Attribute(“FirstName”), LastName = (string)m.Attribute(“LastName”), });db.Students.Select(m => new { m.FirstName, m.LastName });
Get first and last name for all female studentsxmlDoc.Descendants(“Student”). Where(m => (string)m.Attribute(“Gender”) == “Female”).Select(m => new { FirstName = (string)m.Attribute(“FirstName”), LastName = (string)m.Attribute(“LastName”), });db.Students.Where(m => m.Gender == Student.GenderType.Female).Sel ect(m => new { m.FirstName, m.LastName });
Get first and last name for first 10 female students ordered alphabetically by last namexmlDoc.Descendants(“Student”). Where(m => (string)m.Attribute(“Gender”) == “Female”).Select(m => new { FirstName = (string)m.Attribute(“FirstName”), LastName = (string)m.Attribute(“LastName”), }) .OrderBy(m => m.LastName) .Take(10);db.Students .Where(m => m.Gender == Student.GenderType.Female) .Select(m => new { m.FirstName, m.LastName }) .OrderBy(m =>m.LastName) .Take(10);
Get subject ID, Name and first and last name of the teacher for all subjectsxmlDoc.Descendants(“Subject”) .Join(xmlDoc.Descendants(“Teac her”), m => (string)m.Attribute(“TeacherId”), n => (string)n.Attribute(“ID”), (m, n) =>db.Subjects .Join(db.Teachers, m => m.TeacherId, n => n.Id, (m, n) =>

Manipulating XML

Now we want to make all female students a year younger and interested in programming if they are not already.

foreach(var student in femaleStudents) 
     { 
          student.Attribute("BirthYear").Value = ((int)student.Attribute("BirthYear") – 
          1).ToString(); if (!student.Attribute("Interests").Value.Contains("Programming")) 
student.Attribute("Interests").Value += ", Programming"; 
     } 

And we want to remove a student with the ID = 4 from all subjects.

xmlDoc.Descendants("Subjects") 
     .Descendants("Student") 
     .Where(m => (int)m.Attribute("ID") == 4) 
     .Remove(); 

And now we can simply save everything back to the file

xmlDoc.Save("Faculty.xml"); 

And just for the sake of closing the example loop, let’s update students in the database from the XML. using (var db = new FacultyContext())

{ 
          foreach (var student in db.Students) 
           { 
               var studentXml = students.FirstOrDefault(m => (int)m.Attribute("ID") == student.Id); if(studentXml != null) 
               { 
                    student.Interests = studentXml.Attribute("Interests").Value; 
                    student.BirthYear = (int)studentXml.Attribute("BirthYear"); 
                } 
            } 
            db.SaveChanges(); 
     } 

Conclusion

XML is a widely used data format that is applicable in many contexts and technologies. LINQ to XML adds even more flexibility and usability thanks to LINQ integration. You might have noted that the above examples are a little like those we already covered in previous articles related to other LINQ technologies. That only shows that LINQ to XML is the logical addition to the LINQ technologies family.

With this article, we have come to the end of our LINQ-related series. I hope we were successful in our effort to introduce the LINQ technologies, clarifying some aspects of them, or simply bringing another view on technologies you are already familiar with.

Thank you very much for following us to the end. I hope you enjoyed it and will join us in our future articles.

(Visited 99 times, 2 visits today)

Subscribe to our digest
to get SQL Server industry insides!

Close