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 ファイルに 2 つの間違った終了タグが生成されます。

コードをもう一度編集します:

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

あなたの問題は、LinqtoXMLとはまったく関係ありません。それがストリームの仕組みです。最初のケースでは、より長いファイルを取得しているため、以前の内容はすべて上書きされます。2番目のケースでは、新しいファイルが短いため、残りの内容は変更されません。

変更した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);
}

また、XMLに保存DateTimeするときは、実際には次のようにシリアル化する必要がありますXmlConvert

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