Format XmlDocument (indentation) without removing line breaks

900 Views Asked by At

I have an XML file that I want to modify (add new elements) and then save. The problem is that the file has empty lines that should not be deleted.

This is what I'm currently doing:

// loading document with PreserveWhiteSpace = true
var doc = new XmlDocument { PreserveWhitespace = true };
doc.Load(inputFilePath);

// add a new element to the document
var el = doc.CreateElement("TestElement");
doc.InsertAfter(el, doc["SomeParentElement"]["SomeChildElement"]);

// save document
var settings = new XmlWriterSettings
{
  Indent = true,
  IndentChars = @"  ",
  NewLineChars = "\r\n",
  NewLineHandling = NewLineHandling.Replace,
  OmitXmlDeclaration = true
};

using (var writer = XmlWriter.Create(outputFilePath, settings))
{
  doc.Save(writer);
}

I'm setting the documents PreserveWhitespace to true before loading, so that the line breaks do not get ignored. Because of this, the new element I'm adding after the doc["SomeParentElement"]["SomeChildElement"] does not start on a new line and, if I add the newline myself, does not have the correct indentation. I tried many of the settings in XmlWriterSetting, but nothing in there seemed to work when PreserveWhitespace is set to true.

Is it possible to insert a new element into an xml file and save it with a nice formatting but without deleting empty lines in the document?

Example:

<SomeParentElement>
  <SomeChildElement/>

  <SomeChildElement2/>
  <SomeChildElement3/>
</SomeParentElement>

Should look like this after running the code above:

<SomeParentElement>
  <SomeChildElement/>
  <TestElement/>

  <SomeChildElement2/>
  <SomeChildElement3/>
</SomeParentElement>
1

There are 1 best solutions below

4
On

I'd generally suggest LINQ to XML is a far nicer API. You can insert the whitespace you need to keep the formatting you want. For example:

var doc = XDocument.Load(inputFilePath, LoadOptions.PreserveWhitespace);

var child = doc.Elements("SomeParentElement").Elements("SomeChildElement").First();

child.AddAfterSelf(
    new XText("\r\n  "),
    new XElement("TestElement"));

doc.Save(outputFilePath);

See this fiddle for a working demo.