Processing XML Files Using XmlDocument, XmlTextReader, and LINQ to XML in C#

This guide details XML file operasions in C# using three distinct technologies: the traditional XmlDocument for in-memory document object model (DOM) manipulation, the forward-only XmlTextReader for stream-based reading, and the modern LINQ to XML for declarative querying and modification. Each method is demonstrtaed through common CRUD operations (Create, Read, Update, Delete) on a sample XML file representing a bookstore catalog.

XmlTextWriter for XML Creation and Serialization

The XmlTextWriter class provides a forward-only, write-only stream for generating XML data. It is efficient for creating new XML documents from scratch.

/// <summary>
/// Resets data and writes to an XML file using XmlTextWriter.
/// </summary>
private void ResetXmlData()
{
    using (XmlTextWriter xmlWriter = new XmlTextWriter(XmlFilePath, Encoding.UTF8))
    {
        xmlWriter.Formatting = Formatting.Indented;
        xmlWriter.WriteStartDocument(true);
        xmlWriter.WriteStartElement("bookstore");
        xmlWriter.WriteComment("Book catalog information");

        // Write book elements
        xmlWriter.WriteStartElement("book");
        xmlWriter.WriteAttributeString("category", "Elective");
        xmlWriter.WriteAttributeString("isbn", "978-0-321-94786-4");
        xmlWriter.WriteElementString("title", "Operating System Concepts");
        xmlWriter.WriteElementString("author", "Abraham Silberschatz");
        xmlWriter.WriteElementString("price", "85.00");
        xmlWriter.WriteEndElement(); // Closes book element

        xmlWriter.WriteEndElement(); // Closes bookstore element
        xmlWriter.WriteComment("Reset operation completed");
    }
    MessageBox.Show("Data reset successful.");
}

XmlDocument for DOM-Based Operations

The XmlDocument class loads the entire XML document into memory, enabling random access and modification of the node tree.

Loading and Displaying Data

private XmlDocument xmlDoc;
private DataTable dataTable;

/// <summary>
/// Loads XML data into a DataTable using XmlDocument.
/// </summary>
public void LoadWithXmlDocument()
{
    InitializeDataTable();
    xmlDoc = new XmlDocument();
    XmlReaderSettings settings = new XmlReaderSettings { IgnoreComments = true };
    using (XmlReader reader = XmlReader.Create(XmlFilePath, settings))
    {
        xmlDoc.Load(reader);
    }
    XmlNode root = xmlDoc.SelectSingleNode("/bookstore");
    XmlNodeList bookNodes = root.ChildNodes;

    foreach (XmlNode node in bookNodes)
    {
        XmlElement element = (XmlElement)node;
        DataRow row = dataTable.NewRow();
        row["Category"] = element.GetAttribute("category");
        row["ISBN"] = element.GetAttribute("isbn");
        row["Title"] = element["title"].InnerText;
        row["Author"] = element["author"].InnerText;
        row["Price"] = element["price"].InnerText;
        dataTable.Rows.Add(row);
    }
    dataGridView.DataSource = dataTable;
}

Adding a New Record

/// <summary>
/// Adds a new book record to the XML document.
/// </summary>
public void AddBookWithXmlDocument()
{
    DataRow newRow = GenerateNewDataRow();
    XmlNode bookstore = xmlDoc.SelectSingleNode("/bookstore");
    XmlElement newBook = xmlDoc.CreateElement("book");
    newBook.SetAttribute("category", newRow["Category"].ToString());
    newBook.SetAttribute("isbn", newRow["ISBN"].ToString());

    XmlElement titleElem = xmlDoc.CreateElement("title");
    titleElem.InnerText = newRow["Title"].ToString();
    newBook.AppendChild(titleElem);

    XmlElement authorElem = xmlDoc.CreateElement("author");
    authorElem.InnerText = newRow["Author"].ToString();
    newBook.AppendChild(authorElem);

    XmlElement priceElem = xmlDoc.CreateElement("price");
    priceElem.InnerText = newRow["Price"].ToString();
    newBook.AppendChild(priceElem);

    bookstore.AppendChild(newBook);
    xmlDoc.Save(XmlFilePath);
    LoadWithXmlDocument();
}

Updating an Existing Record

/// <summary>
/// Updates a book record identified by its ISBN.
/// </summary>
public void UpdateBookWithXmlDocument(string isbnToUpdate)
{
    XmlNodeList books = xmlDoc.SelectNodes("/bookstore/book[@isbn='" + isbnToUpdate + "']");
    if (books.Count == 0) return;

    XmlElement book = (XmlElement)books[0];
    DataRow updatedData = GenerateUpdatedDataRow(isbnToUpdate);
    book.SetAttribute("category", updatedData["Category"].ToString());
    book["title"].InnerText = updatedData["Title"].ToString();
    book["author"].InnerText = updatedData["Author"].ToString();
    book["price"].InnerText = updatedData["Price"].ToString();

    xmlDoc.Save(XmlFilePath);
    LoadWithXmlDocument();
}

Deleting a Record

/// <summary>
/// Deletes a book record by its ISBN.
/// </summary>
public void DeleteBookWithXmlDocument(string isbnToDelete)
{
    XmlNode bookstore = xmlDoc.DocumentElement;
    XmlNode bookToRemove = xmlDoc.SelectSingleNode("/bookstore/book[@isbn='" + isbnToDelete + "']");
    if (bookToRemove != null)
    {
        bookstore.RemoveChild(bookToRemove);
        xmlDoc.Save(XmlFilePath);
        LoadWithXmlDocument();
    }
}

XmlTextReader for Stream-Based Reading

The XmlTextReader provides a fast, forward-only, read-only cursor for processing XML data. It is memory-efficient for large files.

/// <summary>
/// Loads data using XmlTextReader for sequential parsing.
/// </summary>
public void LoadWithXmlTextReader()
{
    InitializeDataTable();
    DataRow currentRow = dataTable.NewRow();
    using (XmlTextReader xmlReader = new XmlTextReader(XmlFilePath))
    {
        while (xmlReader.Read())
        {
            if (xmlReader.NodeType == XmlNodeType.Element)
            {
                if (xmlReader.Name == "book")
                {
                    currentRow["Category"] = xmlReader.GetAttribute("category");
                    currentRow["ISBN"] = xmlReader.GetAttribute("isbn");
                }
                if (xmlReader.Name == "title")
                {
                    currentRow["Title"] = xmlReader.ReadString();
                }
                if (xmlReader.Name == "author")
                {
                    currentRow["Author"] = xmlReader.ReadString();
                }
                if (xmlReader.Name == "price")
                {
                    currentRow["Price"] = xmlReader.ReadString();
                }
            }
            if (xmlReader.NodeType == XmlNodeType.EndElement && xmlReader.Name == "book")
            {
                dataTable.Rows.Add(currentRow);
                currentRow = dataTable.NewRow();
            }
        }
    }
    dataGridView.DataSource = dataTable;
}

LINQ to XML for Modern XML Processing

LINQ to XML provides an intuitive, in-memory XML programming API integrated with Language-Integrated Query (LINQ).

Loading Data with LINQ to XML

private XElement xElement;

/// <summary>
/// Loads and displays XML data using LINQ to XML.
/// </summary>
public void LoadWithLinq()
{
    InitializeDataTable();
    xElement = XElement.Load(XmlFilePath);

    var bookQuery = from book in xElement.Elements("book")
                    select new
                    {
                        Category = book.Attribute("category").Value,
                        ISBN = book.Attribute("isbn").Value,
                        Title = book.Element("title").Value,
                        Author = book.Element("author").Value,
                        Price = book.Element("price").Value
                    };

    foreach (var book in bookQuery)
    {
        DataRow row = dataTable.NewRow();
        row["Category"] = book.Category;
        row["ISBN"] = book.ISBN;
        row["Title"] = book.Title;
        row["Author"] = book.Author;
        row["Price"] = book.Price;
        dataTable.Rows.Add(row);
    }
    dataGridView.DataSource = dataTable;
}

Adding a Record with LINQ to XML

/// <summary>
/// Adds a new book element using LINQ to XML.
/// </summary>
public void AddBookWithLinq()
{
    DataRow newBookData = GenerateNewDataRow();
    XElement newBook = new XElement("book",
        new XAttribute("category", newBookData["Category"]),
        new XAttribute("isbn", newBookData["ISBN"]),
        new XElement("title", newBookData["Title"]),
        new XElement("author", newBookData["Author"]),
        new XElement("price", newBookData["Price"])
    );
    xElement.Add(newBook);
    xElement.Save(XmlFilePath);
    LoadWithLinq();
}

Updating a Record with LINQ to XML

/// <summary>
/// Updates a book element identified by its ISBN.
/// </summary>
public void UpdateBookWithLinq(string targetIsbn)
{
    XElement bookToUpdate = xElement.Elements("book")
                                    .FirstOrDefault(b => b.Attribute("isbn").Value == targetIsbn);
    if (bookToUpdate == null) return;

    DataRow updatedData = GenerateUpdatedDataRow(targetIsbn);
    bookToUpdate.SetAttributeValue("category", updatedData["Category"]);
    bookToUpdate.SetElementValue("title", updatedData["Title"]);
    bookToUpdate.SetElementValue("author", updatedData["Author"]);
    bookToUpdate.SetElementValue("price", updatedData["Price"]);

    xElement.Save(XmlFilePath);
    LoadWithLinq();
}

Deleting a Record with LINQ to XML

/// <summary>
/// Removes a book element by its ISBN.
/// </summary>
public void DeleteBookWithLinq(string targetIsbn)
{
    XElement bookToRemove = xElement.Elements("book")
                                    .FirstOrDefault(b => b.Attribute("isbn").Value == targetIsbn);
    if (bookToRemove != null)
    {
        bookToRemove.Remove();
        xElement.Save(XmlFilePath);
        LoadWithLinq();
    }
}

Tags: C# XML XmlDocument XmlTextReader LINQ to XML

Posted on Sat, 29 Aug 2026 16:33:58 +0000 by PHP-Editors.com