0

我有这个 XmlFile (tasks.xml):

<?xml version="1.0" encoding="utf-8"?>
<Tasks>
  <Task>
    <Id>dc77b03f-468c-4709-b8dc-4d9741c984dd</Id>
    <Name>buy paper</Name>
    <Category>inbox</Category>
    <DueDate></DueDate>
    <Project></Project>
    <Context></Context>
    <Note></Note>
    <Created>03/16/2013 15:33:29</Created>
    <Finished></Finished>
  </Task>
</Tasks>

当我像这样更新元素时​​,一切正常:

try
{
    var item = (CheckBox)sender;
    dynamic itemDC = item.DataContext;

    var folder = ApplicationData.Current.LocalFolder;
    var file = await folder.GetFileAsync("tasks.xml");
    var readStream = await FileIO.ReadTextAsync(file);
    using (var writeStream = await file.OpenStreamForWriteAsync())
    {
        XElement xElem = XElement.Parse(readStream);

        IEnumerable<XElement> singleTask = from task in xElem.Elements("Task")
                                           where (string)task.Element("Id") == itemDC.Id
                                           select task;

        foreach (XElement task in singleTask)
        {
            task.SetElementValue("Finished", DateTime.Now.ToString("MM") + "/" + DateTime.Now.ToString("dd") + "/" + DateTime.Now.ToString("yyyy HH:mm:ss"));
        }

        xElem.Save(writeStream);
    }
}
catch (Exception ex)
{
    new MessageDialog(ex.Message).ShowAsync();
}

但是如果我想<Finnished>再次编辑元素并将值设置为“”,它将在我的 XML 文件中生成两个错误的结束标记。

再次编辑代码:

try
{
    var item = (CheckBox)sender;
    dynamic itemDC = item.DataContext;

    var folder = ApplicationData.Current.LocalFolder;
    var file = await folder.GetFileAsync("tasks.xml");
    var readStream = await FileIO.ReadTextAsync(file);
    using (var writeStream = await file.OpenStreamForWriteAsync())
    {
        XElement xElem = XElement.Parse(readStream);

        IEnumerable<XElement> singleTask = from task in xElem.Elements("Task")
                                           where (string)task.Element("Id") == itemDC.Id
                                           select task;

        foreach (XElement task in singleTask)
        {
            task.SetElementValue("Finished", "");
        }

        xElem.Save(writeStream);
    }
}
catch (Exception ex)
{
    new MessageDialog(ex.Message).ShowAsync();
}

<Finished>编辑为“”后生成的 XML 错误:

<?xml version="1.0" encoding="utf-8"?>
<Tasks>
  <Task>
    <Id>dc77b03f-468c-4709-b8dc-4d9741c984dd</Id>
    <Name>dnešní úkol</Name>
    <Category>inbox</Category>
    <DueDate></DueDate>
    <Project></Project>
    <Context></Context>
    <Note></Note>
    <Created>03/16/2013 15:33:29</Created>
    <Finished></Finished>
  </Task>
</Tasks>  </Task>
</Tasks>

如果我再次使用与日期字符串相同大小的字符串进行编辑,一切正常,但清除“”值会导致该错误。

我花了很多时间来解决这个问题,但现在我不知道如何解决这个问题。

我做错了什么?

4

1 回答 1

1

您的问题与 Linq to XML 没有任何关系。这就是流的工作方式。在第一种情况下,您将获得更长的文件,因此所有先前的内容都将被覆盖。在第二种情况下,新文件更短,因此其余内容保持不变。

保存修改后的 XML 时应覆盖现有文件:

var folder = ApplicationData.Current.LocalFolder;
var file = await folder.GetFileAsync("tasks.xml");
var readStream = await FileIO.ReadTextAsync(file);
XElement xElem = XElement.Parse(readStream);

IEnumerable<XElement> singleTask = from task in xElem.Elements("Task")
                                    where (string)task.Element("Id") == itemDC.Id
                                    select task;
foreach (XElement task in singleTask)
{
    task.SetElementValue("Finished", "");
}

file = await folder.CreateFileAsync("tasks.xml", CreationCollisionOption.ReplaceExisting);
using (var writeStream = await file.OpenStreamForWriteAsync())
{
    xElem.Save(writeStream);
}

此外,当保存DateTime到 XML 时,您确实应该使用以下命令对其进行序列化XmlConvert

task.SetElementValue("Finished", XmlConvert.ToString(DateTime.Now));
于 2013-03-19T05:38:47.767 回答