每当我附加一个节点时,Xml都会损坏 [英] Xml gets corrupted each time I append a node

查看:72
本文介绍了每当我附加一个节点时,Xml都会损坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Xml文件为:

I have an Xml file as:

<?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中添加节点,

I then call a function to add a node in the 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声明必须是文档中的第一个节点,并且不允许在其之前出现空格字符.

After this I save the xml. Next time when I try to load the Xml, it fails with an exception: System.Xml.XmlException: Unexpected XML declaration. The XML declaration must be the first node in the document, and no white space characters are allowed to appear before it.

以下是加载XML的代码:

Here is the code to load the XML:

private static XDocument hashNotesXDocument;
private static Stream hashNotesStream;

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

然后我使用以下方法保存它:

and I save it using:

hashNotesXDocument.Save(hashNotesStream);

推荐答案

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

You don't show all of your code, but it looks like you open the XML file, read the XML from it into an XDocument, edit the XDocument in memory, then write back to the opened stream. Since the stream is still open it will be positioned at the end of the file and thus the new XML will be appended to the file.

建议消除hashNotesXDocumenthashNotesStream作为静态变量,而是打开并读取文件,修改XDocument,然后使用

Suggest eliminating hashNotesXDocument and hashNotesStream as static variables, and instead open and read the file, modify the XDocument, then open and write the file using the pattern shown here.

我仅在桌面代码上工作(使用.Net的较早版本),因此我无法对其进行测试,但是类似以下的内容应该可以工作:

I'm working only on desktop code (using an older version of .Net) so I can't test this, but something like the following should work:

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

此外,请务必 查看全文

相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆