If you open an XML Document with XDocument.Load(path) and then look through Descendants when you find the one you are looking for and use SetElementValue if you set the value to an empty string ("") or null it ends up removing the tag so when you save the document it's lost.
I want to be able to keep the tag when the value is null or an empty string. I've not been able to find a way to do this.
Is my only option to deserialize the entire XML document into objects edit those objects and write over the file rather than just loading the XmlDocument and editing it?
Sorry, it took me a while to get back to this. I found what my issue was so the code was all correct. What I hadn't noticed before was that this line was at the end before the save.
xDocument.Descendants().Where(e => string.IsNullOrEmpty(e.Value)).Remove();
This goes through all the descendants and finds any that are null or empty strings and removes them which was my problem.
XElement.SetElementValue(elementName, elementValue);
This does exactly as documented. When the elementValue is NULL it will remove the element but when it's an empty string it will put leave the element as an empty element in long-form, not the short form which is fine for my case.
For completeness of this answer and since those asked for example code here is some.
Sample.cfg
<?xml version="1.0" encoding="utf-8"?>
<ParentNode>
<ChildNode>
<PropertyOne>1</PropertyOne>
<PropertyTwo>Y</PropertyTwo>
</ChildNode>
<ChildNode>
<PropertyOne>2</PropertyOne>
<PropertyTwo>N</PropertyTwo>
</ChildNode>
</ParentNode>
Sample Code
// See https://aka.ms/new-console-template for more information
using System.Xml.Linq;
var xDocument = XDocument.Load("Sample.cfg");
foreach (var childNode in xDocument.Descendants("ChildNode"))
{
foreach (var element in childNode.Elements())
{
if (element.Name == "PropertyOne" && element.Value == "2")
{
childNode.SetElementValue("PropertyTwo", "");
}
// Uncomment this line to always have it remove null and empty string descendants
//xDocument.Descendants().Where(e => string.IsNullOrEmpty(e.Value)).Remove();
xDocument.Save("Sample.cfg");
}
}