【问题标题】:Replace XML file or delete Element in XML file using UWP使用 UWP 替换 XML 文件或删除 XML 文件中的元素
【发布时间】:2016-12-06 10:03:07
【问题描述】:

我正在尝试从使用 UWP 存储在存储文件中的 xml 文件中删除一个元素。我的问题是 doc.Save 命令仅将完整的文档添加到文件的末尾,而不是替换它。 我试图搜索 som 替换选项但没有成功。

所以问题实际上是两个部分: 1. 有没有更好的方法从 xml 文件中删除元素然后完全替换它? 2. 如果不是,我该如何替换文件?

    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);
        }
    }

更新 1: 这解决了问题,但看起来不太好。任何关于改进的 cmets 都会很棒。

    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);
        }
    }

【问题讨论】:

    标签: c# xml uwp


    【解决方案1】:

    这里的问题是您忘记将位置重置为当前流中的开头,因此新的 XML 文档被附加到原始文件中。

    为了解决这个问题,我们可以在将XDocument 保存到流中之前使用Stream.SetLength 方法,如下所示。在将当前流的长度设置为零的同时,它会清除当前流并自动将位置重置为开始。

    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);
        }
    }
    

    【讨论】:

    • 其实这行不通。它只在文件的开头写了所有内容,并在最后留下了没有被覆盖的所有内容。
    • @SamuelWahlberg 是的,仅将位置重置为开始不会解决问题。这里我们需要清除当前流进行重写。我已经更新了我的答案,它现在应该可以工作了。谢谢你抓住那个。 ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多