Reputation: 151
I am trying to delete an element from a xml file stored in a storage file using UWP. My problem is that the doc.Save command only adds the full doc to the end to the file instead of replacing it. I have tried to search for som replace option but have not been successful.
So the question is actually two parts: 1. Is there a better way to remove an element from a xml file then replacing it completly? 2. If not how do I replace the file?
public async Task DeleteSingleById(int id)
{
StorageFolder folder = ApplicationData.Current.LocalFolder;
StorageFile file = await folder.GetFileAsync("Data.xml");
Stream stream = await file.OpenStreamForWriteAsync();
using (stream)
{
XDocument doc = XDocument.Load(stream);
doc.Descendants("Companies").Elements("Company").FirstOrDefault(x => x.Elements("Id").Any(e => e.Value == id.ToString())).Remove();
doc.Save(stream);
}
}
Update 1: This solved the problem but it does not look nice. Any comments on improvements would be great.
public async Task DeleteSingleById(int id)
{
StorageFolder folder = ApplicationData.Current.LocalFolder;
StorageFile file = await folder.GetFileAsync("Data.xml");
Stream stream = await file.OpenStreamForWriteAsync();
XDocument doc = XDocument.Load(stream);
using (stream)
{
doc.Descendants("Companies").Elements("Company").FirstOrDefault(x => x.Elements("Id").Any(e => e.Value == id.ToString())).Remove();
}
await file.DeleteAsync();
file = await folder.CreateFileAsync("Data.xml", CreationCollisionOption.ReplaceExisting);
stream = await file.OpenStreamForWriteAsync();
using (stream)
{
doc.Save(stream);
}
}
Upvotes: 1
Views: 575
Reputation: 15758
The problem here is that you forgot to reset the position to the begin within the current stream, so the new XML document is appended to the original file.
To solve this problem, we can use Stream.SetLength method before saving XDocument to the stream like following. While setting the length of the current stream to zero, it will clear the current stream and automatically reset the position to the begin.
public async Task DeleteSingleById(int id)
{
StorageFolder folder = ApplicationData.Current.LocalFolder;
StorageFile file = await folder.GetFileAsync("Data.xml");
Stream stream = await file.OpenStreamForWriteAsync();
using (stream)
{
XDocument doc = XDocument.Load(stream);
doc.Descendants("Companies").Elements("Company").FirstOrDefault(x => x.Elements("Id").Any(e => e.Value == id.ToString())).Remove();
stream.SetLength(0);
doc.Save(stream);
}
}
Upvotes: 3