A Discussion of Class C#, XML, and LINQ: Updating an XML File

C#, XML, and LINQ: Deleting an XML Node

Posted January 22, 2010 in Tutorials by Tieson

So far we've learned how to load & parse an XML file, add new nodes to it, and update it's nodes. Today we're gonna learn the scary part: deleting nodes.

The XML File

First, we need a data file to parse. For the sake of consistency, we'll use the same data file from the previous tutorials:

<?xml version="1.0" encoding="utf-8"?>
<record>
  <student>
    <id>2</id>
    <firstname>Buddy</firstname>
    <lastname>Lee</lastname>
    <major>SENG</major>
  </student>
  <student>
    <id>1</id>
    <firstname>Forrest</firstname>
    <lastname>Gump</lastname>
    <major>SENG</major>
  </student>
</record>

Simplistic, I know, but this file serves our purpose.

The Code

And now we will explore the wonderful code I used to delete nodes. Look this over, and then I'll explain what's happening.

   1:  /// <summary>
   2:  /// Remove a student from the student data file
   3:  /// </summary>
   4:  /// <param name="id">Student's ID</param>
   5:  /// <returns>true if node removed, false if node was not removed</returns>
   6:  public static bool RemoveStudent(string id)
   7:  {
   8:      if (id != string.Empty)
   9:      {
  10:          try
  11:          {
  12:              XDocument xd = XDocument.Load( "students.xml" );
  13:              xd.Element("record").Elements("student").Where(x => x.Element("id").Value.Trim() == id).Remove();
  14:   
  15:              xd.Save( "students.xml" );
  16:   
  17:              return true;
  18:          }
  19:          catch (Exception ex)
  20:          {
  21:              throw (
  22:                      new Exception(String.Format("An error occurred. The student could not be removed. Details of this error:\n\n{0}", ex))
  23:                  );
  24:          }
  25:      }
  26:      else
  27:      {
  28:          throw (new Exception("ID cannot be negative or null."));
  29:      }
  30:  }

This method gets an ID passed in that should correspond to an ID in the data file. We are again using the awesome LINQ lambda method syntax to search for a "student" node whose "id" element has a value matching the ID that was passed into the method.

xd.Element("record").Elements("student").Where(x => x.Element("id").Value.Trim() == id).Remove();

The Remove() method removes all nodes from the parent node (in our case, "record") that are specified by whatever preceded it. In our case, it's deleting the node (or nodes) that match the Where() clause we specified.

It's worth noting that the code I present here will delete multiple nodes if they happen to have the same value for their "id" element. I did not code against that simply because the code I use to write to the data file checks to see if an ID exists already and will not add the node if the ID exists. This basically mimics the "primary key" attribute of a RMDBMS system. If your system does allow the ID element to have duplicates then you will want to add a limit clause such as First() or FirstOrDefault() after the Where() clause.

This method could also be extended by changing the parameter from a single string to a params array. You would then add a loop around the Remove() method call to loop until each of the passed-in IDs have been processed, like so:

   1: /// <summary>
   2: /// Remove a series of students from the student data file
   3: /// </summary>
   4: /// <param name="id_list">Student IDs</param>
   5: /// <returns>true if node(s) removed, false if node(s) was/were not removed</returns>
   6: public static bool RemoveStudent( params string[] id_list )
   7: {
   8:       if ( id_list.Count() > 0 )
   9:       {
  10:           try
  11:           {
  12:               XDocument xd = XDocument.Load( "students.xml" );
  13:               foreach ( string id in id_list )
  14:               {
  15:                   xd.Element( "record" ).Elements( "student" ).Where( x => x.Element( "id" ).Value.Trim() == id ).Remove();
  16:               }
  17:   
  18:               xd.Save( "students.xml" );
  19:   
  20:               return true;
  21:           }
  22:           catch ( Exception ex )
  23:           {
  24:               throw (
  25:                       new Exception( String.Format( "An error occurred. The student could not be removed. Details of this error:\n\n{0}", ex ) )
  26:                   );
  27:           }
  28:       }
  29:       else
  30:       {
  31:           throw ( new Exception( "ID cannot be negative or null." ) );
  32:       }
  33: }

Questions or comments? You know what to do... :]

Add Comment:

Remember: If you can't say anything nice, don't say it at all... :D

Updated: March 2, 2010 ↑Back to top

A Discussion of Class C#, XML, and LINQ: Updating an XML File