C# | XDocument and the System.Xml.Linq namespace
Generate an XML document
Section titled “Generate an XML document”The goal is to generate the following XML document:
<FruitBasket xmlns="http://www.fruitauthority.fake"> <Fruit ID="F0001"> <FruitName>Banana</FruitName> <FruitColor>Yellow</FruitColor> </Fruit> <Fruit ID="F0002"> <FruitName>Apple</FruitName> <FruitColor>Red</FruitColor> </Fruit></FruitBasket>Code:
XNamespace xns = "http://www.fruitauthority.fake";XDeclaration xDeclaration = new XDeclaration("1.0", "utf-8", "yes");XDocument xDoc = new XDocument(xDeclaration);XElement xRoot = new XElement(xns + "FruitBasket");xDoc.Add(xRoot);
XElement xelFruit1 = new XElement(xns + "Fruit");XAttribute idAttribute1 = new XAttribute("ID", "F0001");xelFruit1.Add(idAttribute1);XElement xelFruitName1 = new XElement(xns + "FruitName", "Banana");XElement xelFruitColor1 = new XElement(xns + "FruitColor", "Yellow");xelFruit1.Add(xelFruitName1);xelFruit1.Add(xelFruitColor1);xRoot.Add(xelFruit1);
XElement xelFruit2 = new XElement(xns + "Fruit");XAttribute idAttribute2 = new XAttribute("ID", "F0002");xelFruit2.Add(idAttribute2);XElement xelFruitName2 = new XElement(xns + "FruitName", "Apple");XElement xelFruitColor2 = new XElement(xns + "FruitColor", "Red");xelFruit2.Add(xelFruitName2);xelFruit2.Add(xelFruitColor2);xRoot.Add(xelFruit2);Modify XML File
Section titled “Modify XML File”To modify an XML file with XDocument, you load the file into a variable of type XDocument, modify it in memory, then save it, overwriting the original file.
A common mistake is to modify the XML in memory and expect the file on disk to change.
Given an XML file:
<?xml version="1.0" encoding="utf-8"?><FruitBasket xmlns="http://www.fruitauthority.fake"> <Fruit> <FruitName>Banana</FruitName> <FruitColor>Yellow</FruitColor> </Fruit> <Fruit> <FruitName>Apple</FruitName> <FruitColor>Red</FruitColor> </Fruit></FruitBasket>You want to modify the Banana’s color to brown:
- We need to know the path to the file on disk.
- One overload of
XDocument.Loadreceives a URI (file path). - Since the xml file uses a namespace, we must query with the namespace AND element name.
- A Linq query utilizing C# 6 syntax to accommodate for the possibility of null values. Every
.used in this query has the potential to return a null set if the condition finds no elements. Before C# 6 you would do this in multiple steps, checking for null along the way. The result is the<Fruit>element that contains the Banana. Actually anIEnumerable<XElement>, which is why the next step usesFirstOfDefault(). - Now we extract the FruitColor element out of the Fruit element we just found. Here we assume there is just one, or we only care about the first one.
- If it is not null, we set the FruitColor to “Brown”.
- Finally, we save the
XDocument, overwriting the original file on disk.
// 1.string xmlFilePath = "c:\\users\\public\\fruit.xml";
// 2.XDocument xdoc = XDocument.Load(xmlFilePath);
// 3.XNamespace ns = "http://www.fruitauthority.fake";
//4.var elBanana = xdoc.Descendants()?. Elements(ns + "FruitName")?. Where(x => x.Value == "Banana")?. Ancestors(ns + "Fruit");
// 5.var elColor = elBanana.Elements(ns + "FruitColor").FirstOrDefault();
// 6.if (elColor != null){ elColor.Value = "Brown";}
// 7.xdoc.Save(xmlFilePath);The file now looks like this:
<?xml version="1.0" encoding="utf-8"?><FruitBasket xmlns="http://www.fruitauthority.fake"> <Fruit> <FruitName>Banana</FruitName> <FruitColor>Brown</FruitColor> </Fruit> <Fruit> <FruitName>Apple</FruitName> <FruitColor>Red</FruitColor> </Fruit></FruitBasket>Generate an XML document using fluent syntax
Section titled “Generate an XML document using fluent syntax”Goal:
<FruitBasket xmlns="http://www.fruitauthority.fake"> <Fruit> <FruitName>Banana</FruitName> <FruitColor>Yellow</FruitColor> </Fruit> <Fruit> <FruitName>Apple</FruitName> <FruitColor>Red</FruitColor> </Fruit></FruitBasket>Code:
XNamespace xns = "http://www.fruitauthority.fake";XDocument xDoc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"), new XElement(xns + "FruitBasket", new XElement(xns + "Fruit", new XElement(xns + "FruitName", "Banana"), new XElement(xns + "FruitColor", "Yellow")), new XElement(xns + "Fruit", new XElement(xns + "FruitName", "Apple"), new XElement(xns + "FruitColor", "Red")) ));