我在磁盘上有一个非常基本的XML结构/文件,类似于:
<root>
<data timestamp="dd-mm-yyyy" type="comment">kdkdkdk</data>
<data timestamp="dd-mm-yyyy" type="event">kdkdkdkgffgfdgf</data>
<data timestamp="dd-mm-yyyy" type="something">kddsdsfsdkdkdk</data>
</root>
如上所述,XML将位于磁盘上的外部文件中。由于文件可能会变得相当大(实际上每隔几周会被“修剪”),我不想先加载XML文件来添加新节点......
有没有办法添加这样的新节点?它可以被添加到顶部/底部等,因为实际使用XML的进程无论如何都按时间戳排序..
我猜测粗略的方法是将节点附加为文本..但是我认为会在结束标记之后添加节点吗?
任何想法都感激不尽...... 大卫。
答案 0 :(得分:8)
不使用任何XML API或工具。
您可以将文件打开为文本,找到</root>
的位置并从那里开始覆盖。当然,再次添加</root>
。
快速而肮脏的方法,这不是很强大:
====
string closeTag = "</root>";
int closeLength = Encoding.UTF8.GetBytes(closeTag).Length;
var fs = System.IO.File.Open(filename, System.IO.FileMode.Open);
fs.Position = fs.Length - closeLength;
var writer = new StreamWriter(fs); // after the Position is set
writer.WriteLine(newTag);
writer.Write(closeTag); // NOT WriteLine !!
writer.Close();
fs.Close();
当然,您知道使用using() {}
块。
答案 1 :(得分:4)
不知何故,您必须阅读XML文件,因为您不能只是在文档中添加节点。
Xml文件只能有一个根,因此必须在最后一个数据元素之后添加新节点,但是必须在根结束标记之前添加。否则xml无效。
答案 2 :(得分:2)
这里已经有很多不错的答案了,但是为了再次提出这个问题,你确定这些数据需要存储为XML文件吗?
您存储的数据看起来相当简单(即包含三个字段,日期,类型和一些字符串数据的记录。如果您不需要XML提供的任何附加好处(see here),那么为什么不只使用基本的CSV?这样你只需通过File.AppendText("filename")
就像日志文件一样追加它。
(天啊,甚至可以使用像log4net这样的东西来管理日志记录和任何清理内务管理。)
答案 3 :(得分:1)
取决于
如果您想以“正确”的方式执行此操作,则必须阅读文件及其中的XML。例如,您可以使用XmlReader类来避免将其完全加载到内存中。
但是,如果你绝对知道文本的布局和文件的编码,你可以通过打开它作为随机访问文件(FileStream)来避免完全阅读和重写它,跳到最后(减去“&lt; root /&gt;”),在那里添加新条目并写下“&lt; root /&gt;”试。
答案 4 :(得分:1)
在没有阅读完整文件的情况下,我看不到一种方法可以做你正在做的事情,但作为一种解决方法,你可以将文件视为纯文本,即没有根节点(它将是无效的XML) 。然后,您可以将新节点作为纯文本添加到文件中。而且,由于您的XML解析过程无论如何都会加载整个文件,因此它可以在将根节点视为XML之前添加它。
答案 5 :(得分:1)
System.IO.FileInfo[] aryFi = di.GetFiles("*.xml");
foreach (System.IO.FileInfo fi in aryFi) {
System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument();
xmlDocument.Load(fi.FullName);
XmlNode refelem = xmlDocument.LastChild;
XmlNode newElem = xmlDocument.CreateNode("element", "something", "");
newElem.InnerText = "sometext";
xmlDocument.InsertAfter(newElem, refelem);
}
我相信打开和插入节点是最佳选择。无论哪种方式,你都需要使用IO,为什么不采用正确的方法呢?
单个文件
System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument();
xmlDocument.Load("file path");
XmlNode refelem = xmlDocument.LastChild;
XmlNode newElem = xmlDocument.CreateNode("element", "something", "");
newElem.InnerText = "sometext";
xmlDocument.InsertAfter(newElem, refelem);
答案 6 :(得分:1)
如果不加载XML,则表示不构建DOM树,VTD-XML是唯一允许您逐步剪切粘贴拆分或修改的API。此外,由于VTD-XML具有内存效率,因此您不必担心XML文档的大小。 Java中的类似帖子位于How to update large XML file。请注意,vtd-xml在Java,C#,C和C ++中可用。
答案 7 :(得分:-3)
只需使用
string s = File.ReadAllText(path)
s = s.replace("</root>", newnode + "</root>")
File.WriteAllText(s, path)