C# XmlDocument - working with XML in C# with XmlDocument (2024)

last modified July 5, 2023

C# XmlDocument tutorial shows how to work with XML in C# with XmlDocument.

Extensible Markup Language (XML) is a markup language that defines aset of rules for encoding documents in a format that is both human-readable andmachine-readable. XML is often used for application configuration, data storageand exchange.

XML is similar to HTML, but does not have predefined tags; we can design our owntags.

XmlDocument

The XmlDocument represents an XML document. It can be use to load,modify, validate, an navigate XML documents.

The XmlDocument class is an in-memory representation of an XMLdocument. It implements the W3C XML Document Object Model (DOM).

The Document Object Model (DOM) is a language-independentprogramming interface for HTML and XML documents. It represents a page. Throughthe DOM interface, the programs can change the document structure, style, andcontent. The DOM represents the document as nodes and objects.

The XmlElement is a common node in the XmlDocument.

XPath (XML Path Language) is a query language for selecting nodesfrom an XML document. It can be also used to compute values from the content ofan XML document.

In the examples, we with the following files:

words.xml

<?xml version="1.0" encoding="UTF-8"?><words> <word>falcon</word> <word>sky</word> <word>bottom</word> <word>cup</word> <word>book</word> <word>rock</word> <word>sand</word> <word>river</word></words>

This is the words.xml file.

users.xml

<?xml version="1.0" encoding="UTF-8"?><users> <user id="1"> <name>John Doe</name> <occupation>gardener</occupation> </user> <user id="2"> <name>Jane Doe</name> <occupation>teacher</occupation> </user> <user id="3"> <name>Roger Roe</name> <occupation>driver</occupation> </user> <user id="4"> <name>Lucia Smith</name> <occupation>shopkeeper</occupation> </user></users>

This is the users.xml file.

continents.xml

<?xml version="1.0" encoding="UTF-8"?><continents> <europe> <slovakia> <capital>Bratislava</capital> <population>421000</population> </slovakia> <hungary> <capital>Budapest</capital> <population>1759000</population> </hungary> <poland> <capital>Warsaw</capital> <population>1735000</population> </poland> </europe> <asia> <china> <capital>Beijing</capital> <population>21700000</population> </china> <vietnam> <capital>Hanoi</capital> <population>7500000</population> </vietnam> </asia></continents>

This is the continents.xml file.

C# XmlDocument DocumentElement

The DocumentElement returns the root XmlElement forthe document.

Program.cs

using System.Xml;var xmlData = @"<?xml version=""1.0"" encoding=""UTF-8""?> <words> <word>falcon</word> <word>sky</word> <word>bottom</word> <word>cup</word> <word>book</word> <word>rock</word> <word>sand</word> <word>river</word> </words> ";var doc = new XmlDocument();doc.LoadXml(xmlData);Console.WriteLine(doc.DocumentElement?.Name);Console.WriteLine(doc.DocumentElement?.FirstChild?.InnerText);Console.WriteLine(doc.DocumentElement?.LastChild?.InnerText);Console.WriteLine(doc.DocumentElement?.OuterXml);Console.WriteLine(doc.DocumentElement?.InnerXml);

We load XML data into the XmlDocument and get the root element ofthe document; we call properties of the root node.

var xmlData = @"<?xml version=""1.0"" encoding=""UTF-8""?> <words> <word>falcon</word> <word>sky</word> <word>bottom</word> <word>cup</word> <word>book</word> <word>rock</word> <word>sand</word> <word>river</word> </words> ";

We have XML data as a multi-line string.

var doc = new XmlDocument();doc.LoadXml(xmlData);

We create an XmlDocument and load the XML data withLoadXml method.

Console.WriteLine(doc.DocumentElement?.Name);

The Name property returns the name of the node.

Console.WriteLine(doc.DocumentElement?.FirstChild?.InnerText);Console.WriteLine(doc.DocumentElement?.LastChild?.InnerText);

We get the first and last child of the root node with FirstChildand LastChild. The InnerText propertyreturns the values of the node and all its child nodes.

Console.WriteLine(doc.DocumentElement?.OuterXml);

The OuterXml property gets the markup containing this node and allits child nodes.

Console.WriteLine(doc.DocumentElement?.InnerXml);

The InnerXml property gets or sets the markup representing only thechild nodes of this node.

$ dotnet run wordsfalconriver<words><word>falcon</word><word>sky</word><word>bottom</word><word>cup</word>...<word>falcon</word><word>sky</word><word>bottom</word><word>cup</word>...

C# XmlNode.RemoveChild

The XmlNode.RemoveChild method removes the specified child node.

Program.cs

using System.Xml;var xmlFile = "/home/janbodnar/Documents/users.xml";var doc = new XmlDocument();doc.Load(xmlFile);XmlElement root = doc.DocumentElement;XmlNode userNode = root?.LastChild;if (userNode != null){ root.RemoveChild(userNode);}var xmlFile2 = "/home/janbodnar/Documents/users2.xml";doc.Save(xmlFile2);

In the example, we remove the last child in the document. Note that the methoddoes not modify the original file; it modifies the in-memory representation ofthe document and the modified document is saved into a new file.

C# XmlDocument.CreateElement

The XmlDocument.CreateElement method creates an element with thespecified name.

Program.cs

using System.Xml;var xmlFile = "/home/janbodnar/Documents/words.xml";var doc = new XmlDocument();doc.Load(xmlFile);XmlElement root = doc.DocumentElement;XmlElement e1 = doc.CreateElement("word");e1.InnerText = "eagle";root?.InsertAfter(e1, root.LastChild);XmlElement e2 = doc.CreateElement("word");e2.InnerText = "cheetah";root?.InsertBefore(e2, root.FirstChild);var xmlFile2 = "/home/janbodnar/Documents/words2.xml";doc.Save(xmlFile2);

In the example, we create two new elements.

XmlElement e1 = doc.CreateElement("word");e1.InnerText = "eagle";

A new element named word is created withCreateElement. Its text is set with InnerTextproperty.

root?.InsertAfter(e1, root.LastChild);

The newly created element is inserted after the last child withInsertAfter.

XmlElement e2 = doc.CreateElement("word");e2.InnerText = "cheetah";root?.InsertBefore(e2, root.FirstChild);

The second element is inserted before the first element withInsertBefore.

C# XmlDocument create new document

In the following example, we create a new XML document.

Program.cs

using System.Xml;var users = new Dictionary<long, User>();users.Add(1, new User(1L, "John Doe", "gardener"));users.Add(2, new User(2L, "Jane Doe", "teacher"));users.Add(3, new User(3L, "Roger Roe", "driver"));users.Add(4, new User(4L, "Lucia Smith", "shopkeeper"));var doc = new XmlDocument();XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "UTF-8", string.Empty);doc.AppendChild(xmlDeclaration);XmlElement usersNode = doc.CreateElement("users");doc.AppendChild(usersNode);foreach (var (_, value) in users){ XmlElement userEl = doc.CreateElement("user"); usersNode.AppendChild(userEl); XmlAttribute e = doc.CreateAttribute("id"); e.Value = value.Id.ToString(); userEl.Attributes.Append(e); XmlElement e2 = doc.CreateElement("name"); e2.InnerText = value.Name; userEl.AppendChild(e2); XmlElement e3 = doc.CreateElement("occupation"); e3.InnerText = value.Occupation; userEl.AppendChild(e3);}doc.Save(Console.Out);internal record User(long Id, string Name, string Occupation);

A new XML document is created from a dictionary of user objects.

var users = new Dictionary<long, User>();users.Add(1, new User(1L, "John Doe", "gardener"));users.Add(2, new User(2L, "Jane Doe", "teacher"));users.Add(3, new User(3L, "Roger Roe", "driver"));users.Add(4, new User(4L, "Lucia Smith", "shopkeeper"));

We have a dictionary of users.

var doc = new XmlDocument();XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "UTF-8", string.Empty);

An XmlDocument and a XmlDeclaration are created.

doc.AppendChild(xmlDeclaration);

The XmlDeclaration is appended to the document withAppendChild. The declaration tag is the first tag in the document.

XmlElement usersNode = doc.CreateElement("users");doc.AppendChild(usersNode);

We create the root node of the document.

foreach (var (_, value) in users){ XmlElement userEl = doc.CreateElement("user"); usersNode.AppendChild(userEl); XmlAttribute e = doc.CreateAttribute("id"); e.Value = value.Id.ToString(); userEl.Attributes.Append(e); XmlElement e2 = doc.CreateElement("name"); e2.InnerText = value.Name; userEl.AppendChild(e2); XmlElement e3 = doc.CreateElement("occupation"); e3.InnerText = value.Occupation; userEl.AppendChild(e3);}

We go through the dictionary and create necessary elements and an attribute foreach user object.

doc.Save(Console.Out);

This time we output the XML data to the console.

$ dotnet run<?xml version="1.0" encoding="utf-8"?><users> <user id="1"> <name>John Doe</name> <occupation>gardener</occupation> </user> <user id="2"> <name>Jane Doe</name> <occupation>teacher</occupation> </user> <user id="3"> <name>Roger Roe</name> <occupation>driver</occupation> </user> <user id="4"> <name>Lucia Smith</name> <occupation>shopkeeper</occupation> </user></users>

C# XmlNode.ChildNodes

The XmlNode.ChildNodes returns all the children of the given node.The property returns the XmlNodeList, which represents an orderedcollection of nodes.

Program.cs

using System.Xml;var xmlFile = "/home/janbodnar/Documents/words.xml";var doc = new XmlDocument();doc.Load(xmlFile);XmlElement root = doc.DocumentElement;XmlNodeList childNodes = root?.ChildNodes;if (childNodes == null){ Console.WriteLine("no nodes found"); Environment.Exit(1);}foreach (XmlNode node in childNodes){ Console.WriteLine(node.InnerText);}

In the example, we get all the children of the root node and print their innertext content.

$ dotnet runfalconskybottomcupbookrocksandriver

C# XmlNodeList.Count

The XmlNodeList.Count property gets the number of nodes in theXmlNodeList.

Program.cs

using System.Xml;var xmlFile = "/home/janbodnar/Documents/words.xml"; var doc = new XmlDocument();doc.Load(xmlFile);XmlElement root = doc.DocumentElement;int? n = root?.ChildNodes.Count;Console.WriteLine($"There are {n} elements");

We get the number of elements inside the root node.

$ dotnet run There are 8 elements

C# XmlNode.SelectSingleNode

The XmlNode.SelectSingleNode selects the first XmlNode that matchesthe XPath expression.

Program.cs

using System.Xml;var xmlFile = "/home/janbodnar/Documents/users.xml";var doc = new XmlDocument();doc.Load(xmlFile);int id = 2;XmlNode node = doc.SelectSingleNode($"/users/user[@id='{id}']");if (node == null){ Console.WriteLine("node not found"); Environment.Exit(1);}var name = node.ChildNodes[0]?.InnerText;var occupation = node.ChildNodes[1]?.InnerText;var uid = node.Attributes?["id"]?.Value;Console.WriteLine($"Id: {uid}");Console.WriteLine($"Name: {name}");Console.WriteLine($"Occupation: {occupation}");

From the words.xml file, we select the word node with Id attribute6.

XmlNode node = doc.SelectSingleNode($"/users/user[@id='{id}']");

A single node is selected with SelectSingleNode; the/users/user[@id='{id}'] is the query expression to get to thedesired node.

var name = node.ChildNodes[0]?.InnerText;var occupation = node.ChildNodes[1]?.InnerText;var uid = node.Attributes?["id"]?.Value;

We get the node's text and attribute.

$ dotnet runId: 2Name: Jane DoeOccupation: teacher

C# XmlNode.SelectNodes

The XmlNode.SelectNodes selects a list of nodes matching the XPathexpression.

Program.cs

using System.Xml;var xmlFile = "/home/janbodnar/Documents/users.xml";var doc = new XmlDocument();doc.Load(xmlFile);XmlNodeList nodes = doc.SelectNodes("/users/user");var users = new List<User>();if (nodes == null){ Console.WriteLine("No users found"); Environment.Exit(1);}foreach (XmlNode node in nodes){ long id = long.Parse(node.Attributes?.GetNamedItem("id")?.Value!); string name = node.ChildNodes[0]?.InnerText; string occupation = node.ChildNodes[1]?.InnerText; var user = new User(id, name, occupation); users.Add(user);}users.ForEach(Console.WriteLine);record User(long Id, string Name, string Occupation);

In the example, we select all users from the users.xml file.

XmlNodeList nodes = doc.SelectNodes("/users/user");

The /users/user is the path to get all users. TheSelectNodes method returns an XmlNodeList.

foreach (XmlNode node in nodes){ long id = long.Parse(node.Attributes?.GetNamedItem("id")?.Value!); string name = node.ChildNodes[0]?.InnerText; string occupation = node.ChildNodes[1]?.InnerText; var user = new User(id, name, occupation); users.Add(user);}

We go through the XmlNodeList and create a User objectfrom the retrieved data.

$ dotnet runUser { Id = 1, Name = John Doe, Occupation = gardener }User { Id = 2, Name = Jane Doe, Occupation = teacher }User { Id = 3, Name = Roger Roe, Occupation = driver }User { Id = 4, Name = Lucia Smith, Occupation = shopkeeper }

C# XmlElement.GetElementsByTagName

The XmlElement.GetElementsByTagName returns anXmlNodeList containing a list of all descendant elements that matchthe specified tag name.

Program.cs

using System.Xml;var xmlFile = "/home/janbodnar/Documents/continents.xml";XmlDocument doc = new XmlDocument();doc.Load(xmlFile);XmlNodeList nodes = doc.GetElementsByTagName("capital");Console.WriteLine("All capitals:");foreach (XmlNode node in nodes){ var text = node.InnerText; Console.WriteLine(text);}

We go over the capital tags in the continents.xmlfile.

$ dotnet runAll capitals:BratislavaBudapestWarsawBeijingHanoi

C# XmlDocument.CreateNavigator

The XmlDocument.CreateNavigator creates aXPathNavigator object for navigating the document. TheXPathNodeIterator provides an iterator over a selected set ofnodes.

Program.cs

using System.Xml;using System.Xml.XPath;var xmlFile = "/home/janbodnar/Documents/users.xml";var doc = new XmlDocument();doc.Load(xmlFile);XPathNavigator rootNav = doc.CreateNavigator();XPathNodeIterator it = rootNav?.Select("descendant::users/user");if (it == null){ Console.WriteLine("no users found"); Environment.Exit(1);}while (it.MoveNext()){ XPathNavigator nav = it.Current; var uId = nav?.GetAttribute("id", string.Empty); Console.WriteLine(uId); XPathNodeIterator nodeIt = nav?.SelectChildren(XPathNodeType.Element); if (nodeIt != null) { foreach (var e in nodeIt) { Console.WriteLine(e); } } Console.WriteLine("--------------------");}

We use the XPathNavigator and the XPathNodeIterator togo over users in the users.xml file.

XPathNavigator rootNav = doc.CreateNavigator();XPathNodeIterator it = rootNav?.Select("descendant::users/user");...while (it.MoveNext())

First, we go over the user tags.

XPathNavigator nav = it.Current;var uId = nav?.GetAttribute("id", string.Empty);Console.WriteLine(uId);XPathNodeIterator nodeIt = nav?.SelectChildren(XPathNodeType.Element);if (nodeIt != null){ foreach (var e in nodeIt) { Console.WriteLine(e); }}

Then we go over the elements of each user tag.

$ dotnet run1John Doegardener--------------------2Jane Doeteacher--------------------3Roger Roedriver--------------------4Lucia Smithshopkeeper--------------------

C# XmlDocument recursive loop

In the following example, we recursively loop over the tags of theusers.xml file.

Program.cs

using System.Xml;var xmlFile = "/home/janbodnar/Documents/users.xml";var doc = new XmlDocument();doc.Load(xmlFile);traverse(doc.DocumentElement);void traverse(XmlNode node){ if (node is XmlElement) { if (node.Name == "users") { Console.WriteLine(node.Name); } else if (node.Name == "user") { Console.WriteLine("--------------------"); Console.WriteLine(node.Name); } else { Console.WriteLine($" {node.Name}"); } if (node.HasChildNodes) { traverse(node.FirstChild); } if (node.NextSibling != null) { traverse(node.NextSibling); } } else if (node is XmlText) { var text = ((XmlText) node).Value; Console.WriteLine($" {text}"); }}

We parse the users.xml with a recursive algorithm.

traverse(doc.DocumentElement);

We start by passing the root element to the traverse method.

if (node is XmlElement){ ...}else if (node is XmlText){ var text = ((XmlText) node).Value; Console.WriteLine($" {text}");}

We check if the node is an XmlElement or an XmlText.In the latter case, we output the textual content of the node.

if (node.HasChildNodes){ traverse(node.FirstChild);}

If the node has children, we recursively call the traverse methodpassing it its first child.

if (node.NextSibling != null){ traverse(node.NextSibling);}

We go recursively to the next sibling if there is any.

$ dotnet runusers--------------------user name John Doe occupation gardener--------------------user name Jane Doe occupation teacher--------------------user name Roger Roe occupation driver--------------------user name Lucia Smith occupation shopkeeper

In this article we have worked with XML data in C# usingXmlDocument.

C# XmlDocument read currency rates

In the following example, we read data from European Central Bank.

Program.cs

using System.Xml;var xmlRes = "http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml";var doc = new XmlDocument();doc.Load(xmlRes);XmlNodeList nodes = doc.DocumentElement?.ChildNodes[2]?.ChildNodes[0]?.ChildNodes;foreach (XmlNode xmlNode in nodes!){ if (xmlNode.Attributes == null) continue; var cur = xmlNode.Attributes["currency"]?.Value; var rate = xmlNode.Attributes["rate"]?.Value; Console.WriteLine($"{cur}: {rate}");}

We get the currency rates for Euro.

$ dotnet runUSD: 1.1904JPY: 130.20BGN: 1.9558CZK: 26.031DKK: 7.4369GBP: 0.86518HUF: 356.43PLN: 4.5246RON: 4.9203SEK: 10.1975CHF: 1.0998ISK: 151.90NOK: 10.0940HRK: 7.5673RUB: 91.9588...

C# XmlDocument validate

An XML document with a correct syntax is said to be well formed. Validation isthe process of checking an XML document to confirm that it is both well-formedand also valid. A valid document adheres the rules dictated by a particular DTDor XML schema.

XML Schema, or XML Schema Definition (XSD), is a formal description of thethe structure and the content of an XML document. It is used to validate theXML document.

users.xsd

<?xml version="1.0" encoding="UTF-8"?><xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="users" type="usersType"/> <xs:complexType name="userType"> <xs:sequence> <xs:element name="name" type="xs:string"/> <xs:element name="occupation" type="xs:string"/> </xs:sequence> <xs:attribute type="xs:string" name="id"/> </xs:complexType> <xs:complexType name="usersType"> <xs:sequence> <xs:element name="user" type="userType" maxOccurs="unbounded" minOccurs="0"/> </xs:sequence> </xs:complexType> </xs:schema>

We have the schema definition for the users.xml file.

Program.cs

using System.Xml;using System.Xml.Schema;var xmlFile = "/home/janbodnar/Documents/users.xml";var xmlSchema = "/home/janbodnar/Documents/users.xsd";try{ var settings = new XmlReaderSettings(); settings.Schemas.Add(null, xmlSchema); settings.ValidationType = ValidationType.Schema; settings.ValidationEventHandler += ValidationEventHandler; XmlReader reader = XmlReader.Create(xmlFile, settings); var doc = new XmlDocument(); doc.Load(reader); Console.WriteLine("validation passed");}catch (Exception ex){ Console.WriteLine(ex.Message);}void ValidationEventHandler(object sender, ValidationEventArgs e){ Console.WriteLine($"Document validation error: {e.Message}"); Environment.Exit(1);}

We validate the users.xml document against theusers.xsd schema.

C# XmlDocument event

There are event handlers to react to nodes being changed, inserted, or removed.

Program.cs

using System.Xml;var xmlFile = "/home/janbodnar/Documents/words.xml";var doc = new XmlDocument();doc.Load(xmlFile);XmlElement root = doc.DocumentElement;doc.NodeChanged += MyNodeChangedEvent;doc.NodeInserted += MyNodeInsertedEvent;doc.NodeRemoved += MyNodeRemovedEvent;XmlNode node = root?.LastChild;root?.RemoveChild(node!);XmlElement e1 = doc.CreateElement("word");e1.InnerText = "eagle";root?.AppendChild(e1);XmlNode n1 = doc.SelectSingleNode("//words/word[text()='bottom']");Console.WriteLine(n1?.InnerText);if (n1 != null) n1.InnerText = "star";doc.Save("/home/janbodnar/Documents/words3.xml");void MyNodeChangedEvent(Object src, XmlNodeChangedEventArgs args){ Console.WriteLine($"Node Changed Event Fired for node {args.Node?.Name}"); Console.WriteLine(args.Node?.Value);}void MyNodeInsertedEvent(Object src, XmlNodeChangedEventArgs args){ Console.WriteLine($"Node Inserted Event Fired for node {args.Node?.Name}"); Console.WriteLine(args.Node?.Value);}void MyNodeRemovedEvent(Object src, XmlNodeChangedEventArgs args){ Console.WriteLine($"Node Removed Event Fired for node {args.Node?.Name}"); Console.WriteLine(args.Node?.Value);}

In the example, we create three event handlers.

doc.NodeChanged += MyNodeChangedEvent;doc.NodeInserted += MyNodeInsertedEvent;doc.NodeRemoved += MyNodeRemovedEvent;

We plug event handlers for nodes being changed, inserted, and removed.

XmlNode node = root?.LastChild;root?.RemoveChild(node!);

We remove the last child. This triggers the MyNodeRemovedEvent.

XmlElement e1 = doc.CreateElement("word");e1.InnerText = "eagle";root?.AppendChild(e1);

We create a new node. This triggers the two pieces ofMyNodeInsertedEvent: one for inserting text and one for insertingthe node.

XmlNode n1 = doc.SelectSingleNode("//words/word[text()='bottom']");Console.WriteLine(n1?.InnerText);if (n1 != null) n1.InnerText = "star";

We modify the content of a node. This triggers theMyNodeChangedEvent.

$ dotnet run Node Removed Event Fired for node wordNode Inserted Event Fired for node #texteagleNode Inserted Event Fired for node wordbottomNode Changed Event Fired for node #textstar

Source

XmlDocument class - language reference

In this article we have worked with XML data in C# usingXmlDocument.

Author

My name is Jan Bodnar and I am a passionate programmer with many years ofprogramming experience. I have been writing programming articles since 2007. Sofar, I have written over 1400 articles and 8 e-books. I have over eight years ofexperience in teaching programming.

List all C# tutorials.

C# XmlDocument - working with XML in C# with XmlDocument (2024)
Top Articles
Latest Posts
Recommended Articles
Article information

Author: Foster Heidenreich CPA

Last Updated:

Views: 6442

Rating: 4.6 / 5 (56 voted)

Reviews: 87% of readers found this page helpful

Author information

Name: Foster Heidenreich CPA

Birthday: 1995-01-14

Address: 55021 Usha Garden, North Larisa, DE 19209

Phone: +6812240846623

Job: Corporate Healthcare Strategist

Hobby: Singing, Listening to music, Rafting, LARPing, Gardening, Quilting, Rappelling

Introduction: My name is Foster Heidenreich CPA, I am a delightful, quaint, glorious, quaint, faithful, enchanting, fine person who loves writing and wants to share my knowledge and understanding with you.