将XML附加到文件而不从头开始编写吗? [英] Append XML to file without writing it from scratch?

查看:51
本文介绍了将XML附加到文件而不从头开始编写吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在LINQ-to-XML中附加XML文件的标准方法是读入,修改内存中的文档并从头开始写出整个文件.例如:

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

或者,用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);
    }
}

但是,在两种情况下,都将现有XML文档加载到内存中,在内存中进行修改,然后从头开始 写入XML文件.对于小型XML文件,这是可以的,但是对于具有数百或数千个节点的大型文件,这似乎是效率很低的过程.有什么方法可以使XDocument(或者也许是类似XmlWriter的东西)仅将必要的附加节点附加到现有XML文档中,而不是将其清空并从头开始?

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?

推荐答案

这完全取决于您需要添加其他元素的位置.当然,您可以实施一些删除结束"</root>"标记,写入其他元素,然后再次添加"</root>"的操作.但是,这样的代码已针对您的目的进行了高度优化,您可能找不到适合它的库.

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.

您的代码可能看起来像这样(迅速而肮脏,没有输入检查,假设<root/>不存在):

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

这篇关于将XML附加到文件而不从头开始编写吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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