Append XML to file without writing it from scratch? [duplicate]

 ̄綄美尐妖づ 提交于 2020-01-05 07:08:20

问题


The standard way to append an XML file in LINQ-to-XML is to read it in, modify the in-memory document, and write the whole file out from scratch. For example:

XDocument doc = XDocument.Load("pathToDoc.xml");
doc.Root.Add(new XElement(namespace + "anotherChild", new XAttribute("child-id", childId)));
doc.Save("pathToDoc.xml");

Or, with a FileStream:

using (FileStream fs = new FileStream("pathToDoc.xml", FileMode.Open, FileAccess.ReadWrite)) {
    XDocument doc = XDocument.Load(fs);
    doc.Root.Add(new XElement(namespace + "anotherChild", new XAttribute("child-id", childId)));

    fs.SetLength(0);
    using (var writer = new StreamWriter(fs, new UTF8Encoding(false))) {
        doc.Save(writer);
    }
}

However, in both cases, the existing XML document is being loaded into memory, modified in memory, and then written from scratch to the XML file. For small XML files this is OK, but for large files with hundreds or thousands of nodes this seems like a very inefficient process. Is there any way to make XDocument (or perhaps something like an XmlWriter) just append the necessary additional nodes to the existing XML document rather than blanking it out and starting from scratch?


回答1:


This totally depends on the position where you need to add the additional elements. Of course you can implement something that removes the closing "</root>" tag, writes additional elements and then adds the "</root>" again. However, such code is highly optimized for your purpose and you'll probably not find a library for it.

Your code could look like this (quick and dirty, without input checking, assuming that <root/> cannot exist):

using System.IO;
using System.Xml.Linq;

namespace XmlAddElementWithoutLoading
{
    class Program
    {
        static void Main()
        {
            var rootelement = "root";
            var doc = GetDocumentWithNewNodes(rootelement);
            var newNodes = GetXmlOfNewNodes(doc);

            using (var fs = new FileStream("pathToDoc.xml", FileMode.Open, FileAccess.ReadWrite))
            {
                using (var writer = new StreamWriter(fs))
                {
                    RemoveClosingRootNode(fs, rootelement);
                    writer.Write(newNodes);
                    writer.Write("</"+rootelement+">");
                }
            }
        }

        private static void RemoveClosingRootNode(FileStream fs, string rootelement)
        {
            fs.SetLength(fs.Length - ("</" + rootelement + ">").Length);
            fs.Seek(0, SeekOrigin.End);
        }

        private static string GetXmlOfNewNodes(XDocument doc)
        {
            var reader = doc.Root.CreateReader();
            reader.MoveToContent();
            return reader.ReadInnerXml();
        }

        private static XDocument GetDocumentWithNewNodes(string rootelement)
        {
            var doc = XDocument.Parse("<" + rootelement + "/>");
            var childId = "2";
            XNamespace ns = "namespace";
            doc.Root.Add(new XElement(ns + "anotherChild", new XAttribute("child-id", childId)));
            return doc;
        }
    }
}


来源:https://stackoverflow.com/questions/45531295/append-xml-to-file-without-writing-it-from-scratch

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!