One of my recent tasks at work requires some XML manipulations. This includes reading value of an XML element, changing an element value, reading values of children nodes and reading the outer XML value of an element. In this post, I’m going to show how to do these using XDocument in .Net Core.
We’ll use the following XML string as the example
<Book xmlns="http://some.namespace/service/2.19/">
<Title xmlns="http://some.namespace/schema/2.19/">Some detective fictional book</Title>
<Author xmlns="http://some.namespace/schema/2.19/">
<FirstName>Jane</FirstName>
<LastName>Nerks</LastName>
</Author>
<CountryCode xmlns="http://some.namespace/schema/2.19/">AUS</CountryCode>
<Metadata xmlns="http://some.namespace/schema/2.19/">
<Tag>
<Value>Fiction</Value>
</Tag>
<Tag>
<Value>Detective</Value>
</Tag>
</Metadata>
</Book>
Reading value of an element by name
To read the value of an element by name, you can search for a descendants with a local name matching the target tag name. I use local name here instead of name as the element might have prefix in the name. The following shows how to get the title value of the book.
var xmlString = "The sample xml string goes here";
var xml = XDocument.Parse(xmlString);
var descendants = xml.Descendants();
var titleElement = descendants.FirstOrDefault(x => x.Name.LocalName == "Title");
var titleValue = titleElement.Value;
Changing value of an element
Changing value of the element is pretty straight forward once you have the element. You can simply set the Value property to the value you want.
var titleElement = descendants.FirstOrDefault(x => x.Name.LocalName == "Title");
titleElement.Value = "Updated book title";
Reading all values of children nodes
The following code shows how to get the value of the all Value elements in the Tag elements of the Metadata element
var metadataElement = descendants.FirstOrDefault(x => x.Name.LocalName == "Metadata");
var tagValues = metadataElement.Document.Descendants().Where(x => x.Name.LocalName == "Value").Select(x => x.Value));
Reading the outer XML of an element
You can call ToString on the element to get the outer XML. You can also pass some flag enums to the ToString to disable formatting and/or to omit duplicate namespaces. You can also use this to get the raw XML string of XDocument. The following code will get the outer XML string of the Metadata element without formatting and duplicate namespaces.
var metadataXmlString = descendants.FirstOrDefault(x => x.Name.LocalName == "Metadata").ToString(SaveOptions.DisableFormatting | SaveOptions.OmitDuplicateNamespaces);
// Result: "<Metadata xmlns=\"http://some.namespace/schema/2.19/\"><Tag><Value>Fiction</Value></Tag><Tag><Value>Detective</Value></Tag></Metadata>"