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

LINQ to XML: Easy Work in C#

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.

Introduction to LINQ to XML Main Classes

LINQ to XML provides a rich set of classes for working with XML data in .NET applications. Here are some of the main classes you’ll use when working with LINQ to XML:

  1. XDocument: Represents an entire XML document, including the XML declaration and the root element. The XDocument class provides methods for loading and saving XML documents, as well as for querying and modifying the contents of the document.
  2. XElement: Represents an XML element within an XML tree. An XElement can contain other XElement objects as well as XAttribute objects. The XElement class provides methods for querying and modifying the attributes and child elements of an element, as well as for creating new elements and attributes.
  3. XAttribute: Represents an attribute associated with an XML element. An XAttribute can only belong to a single XElement. The XAttribute class provides methods for querying and modifying the value of an attribute, as well as for creating new attributes.
  4. XNamespace: Represents a namespace declaration within an XML document. The XNamespace class provides methods for creating and querying namespace declarations, which are used to disambiguate element and attribute names that might otherwise be ambiguous.
  5. XNode: Represents a node within an XML tree. The XNode class is the base class for XElement, XAttribute, and other node types in LINQ to XML. The XNode class provides methods for querying and modifying the parent, sibling, and descendant nodes of a node, as well as for creating new nodes.
  6. XText: Represents a text node within an XML tree. An XText object contains the text content of an element or attribute. The XText class provides methods for querying and modifying the text content of a node, as well as for creating new text nodes.

These are some of the main classes you’ll work with when using LINQ to XML to manipulate XML data. By understanding these classes and their methods, you can create, query, and modify XML documents more easily and efficiently in your .NET applications.

Create XML file using LINQ

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())

C#

{ 
   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>

LINQ to XML for Querying

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");

Examples of LINQ queries on an XElement list

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) =>

XML Updating in C# with LINQ

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.

Tags: , Last modified: March 13, 2023
Close