每次添加节点时,Xml都会被破坏

时间:2015-02-05 20:37:10

标签: c# xml linq-to-xml windows-phone-8.1

我有一个Xml文件:

<?xml version="1.0"?>
<hashnotes>
  <hashtags>
    <hashtag>#birthday</hashtag>
    <hashtag>#meeting</hashtag>
    <hashtag>#anniversary</hashtag>
  </hashtags>
  <lastid>0</lastid>
  <Settings>
    <Font>Arial</Font>
    <HashtagColor>red</HashtagColor>
    <passwordset>0</passwordset>
    <password></password>
  </Settings>
</hashnotes>

然后我调用一个函数在xml中添加一个节点,

功能是:

public static void CreateNoteNodeInXDocument(XDocument argXmlDoc, string argNoteText)
    {
       string lastId=((Convert.ToInt32(argXmlDoc.Root.Element("lastid").Value)) +1).ToString();
       string date = DateTime.Now.ToString("MM/dd/yyyy");
        argXmlDoc.Element("hashnotes").Add(new XElement("Note", new XAttribute("ID", lastId), new XAttribute("Date",date),new XElement("Text", argNoteText)));
        //argXmlDoc.Root.Note.Add new XElement("Text", argNoteText)
        List<string> hashtagList = Utilities.GetHashtagsFromText(argNoteText);

        XElement reqNoteElement = (from xml2 in argXmlDoc.Descendants("Note")
                            where xml2.Attribute("ID").Value == lastId
                            select xml2).FirstOrDefault();
        if (reqNoteElement != null)
        {
            foreach (string hashTag in hashtagList)
            {
                reqNoteElement.Add(new XElement("hashtag", hashTag));
            }
        }

        argXmlDoc.Root.Element("lastid").Value = lastId;
    }

在此之后我保存了xml。 下次当我尝试加载Xml时,它失败并出现异常: System.Xml.XmlException:意外的XML声明。 XML声明必须是文档中的第一个节点,并且不允许在其前面显示空白字符。

以下是加载XML的代码:

private static XDocument hashNotesXDocument;
private static Stream hashNotesStream;

StorageFile hashNoteXml = await InstallationFolder.GetFileAsync("hashnotes.xml");
hashNotesStream = await hashNoteXml.OpenStreamForWriteAsync();
hashNotesXDocument = XDocument.Load(hashNotesStream);

我用以下方法保存:

hashNotesXDocument.Save(hashNotesStream);

1 个答案:

答案 0 :(得分:1)

您没有显示所有代码,但看起来您打开XML文件,将其中的XML读入XDocument,编辑内存中的XDocument,然后写回打开的溪流。由于流仍处于打开状态,因此它将位于文件的末尾,因此新的XML将附加到文件中。

建议取消hashNotesXDocumenthashNotesStream作为静态变量,而是打开并读取文件,修改XDocument,然后使用显示的模式打开并写入文件{{3} }。

我只使用桌面代码(使用旧版本的.Net),所以我无法对此进行测试,但以下内容应该有效:

    static async Task LoadUpdateAndSaveXml(Action<XDocument> editor)
    {
        XDocument doc;
        var xmlFile = await InstallationFolder.GetFileAsync("hashnotes.xml");
        using (var reader = new StreamReader(await xmlFile.OpenStreamForReadAsync()))
        {
            doc = XDocument.Load(reader);
        }        

        if (doc != null)
        {
            editor(doc);
            using (var writer = new StreamWriter(await xmlFile.OpenStreamForWriteAsync()))
            {
                // Truncate - https://stackoverflow.com/questions/13454584/writing-a-shorter-stream-to-a-storagefile
                if (writer.CanSeek && writer.Length > 0) 
                    writer.SetLength(0);
                doc.Save(writer);
            }
        }
    }

另外,请务必here