Search code examples
c#.netxmlxmldocument

Why does overwriting an XML file create an extra end tag?


I am creating an application in C# that has to write some user settings to an XML file. They are read perfectly fine, but when I try to write them back they create an extra end tag that the program cannot read.

XML file:

<?xml version="1.0" encoding="utf-8" ?>
<options>
   <fullscreen>False</fullscreen>
   <resolutionX>1280</resolutionX>
   <resolutionY>720</resolutionY>
   <vsync>True</vsync>
   <AA>2</AA>
   <musicvolume>0</musicvolume>
   <soundvolume>0</soundvolume>
</options>

Code that writes:

FileStream stream =
    new FileStream("configs/options.xml", FileMode.Open, FileAccess.ReadWrite);

XmlDocument doc = new XmlDocument();

doc.Load(stream);

stream.Seek(0, SeekOrigin.Begin);

doc.SelectSingleNode("/options/fullscreen").InnerText = fullscreen.ToString();
doc.SelectSingleNode("/options/vsync").InnerText = vsync.ToString();
doc.SelectSingleNode("/options/resolutionX").InnerText = resolutionX.ToString();
doc.SelectSingleNode("/options/resolutionY").InnerText = resolutionY.ToString();
doc.SelectSingleNode("/options/AA").InnerText = aa.ToString();
doc.SelectSingleNode("/options/musicvolume").InnerText = musicvolume.ToString();
doc.SelectSingleNode("/options/soundvolume").InnerText = soundvolume.ToString();

doc.Save(stream);
stream.Close();

What I end up with:

<?xml version="1.0" encoding="utf-8" ?>
<options>
   <fullscreen>True</fullscreen>
   <resolutionX>1280</resolutionX>
   <resolutionY>720</resolutionY>
   <vsync>True</vsync>
   <AA>4</AA>
   <musicvolume>0</musicvolume>
   <soundvolume>0</soundvolume>
</options>/options>

Solution

  • Since you’re writing to the same stream, if the modified XML is shorter than the original, the difference will remain. You can use FileStream.SetLength after saving to fix that:

    doc.Save(stream);
    stream.SetLength(stream.Position);
    stream.Close();