Reputation: 13
I am trying to develop a simple c# program in Visual Studio 2017 which loops through an XML file and will amend certain nodes based on the 'type' number in the file. Each 'code' has a different type number.
For example if type number = 4 then add additional information to node 'name'. e.g A last name at the end.
However I dont want it to amend node 'name' that appears under type 5. I have looked at other questions and the answers but these dont take care of the multiple descendants in the file!
<?xml version="1.0" encoding="utf-8"?>
<testing>
<names>
<name>
<code>0000</code>
<type>4</type>
<steps>
<nStep>
<name>John</name>
</nStep>
</steps>
</name>
<name>
<code>1111</code>
<type>5</type>
<steps>
<nStep>
<name>Paul</name>
</nStep>
</steps>
</name>
</names>
</testing>
Upvotes: 0
Views: 50
Reputation: 5812
You could use Linq to XML to do this.
Depending on how flexible you need it, here are a couple of different approaches. Firstly, using XPath (you need to reference System.Xml.XPath
to get the relevant extension methods). Here you can filter the nodes you want to change using an XPath query expression, for example, in this case we iterate only only nodes that have '4' as the type:
// you can load xml from string or however you have it
var xDoc = XDocument.Load(@"c:\temp\myxml.xml");
foreach (var nameElement in xDoc.XPathSelectElements("//testing/names/name[type='4']"))
{
nameElement
.Descendants("name")
.Single()
.Value += " Smith";
}
Alternatively, this approach will iterate on all of the name
elements under the parent element names
, and allow you to switch on the value of the type
element to perform a different action in each case:
// select the name elements, and parse the type into an integer (optional, you can
// switch on type as a string if you prefer).
var nameElements = xDoc
.Element("testing")
.Element("names")
.Elements("name")
.Select(name => new { Type = int.Parse(name.Element("type").Value), Element = name });
// iterate on each name element
foreach (var nameElement in nameElements)
{
// check the type
switch (nameElement.Type)
{
case 4:
nameElement
.Element
.Descendants("name") // filter to name elements under the parent name element
.Single() // we only expect one
.Value += " Smith"; // append a last name
break;
default:
continue; // don't do anything
}
}
Upvotes: 0