【问题标题】:What's the best way to update xml in a file?更新文件中的 xml 的最佳方法是什么?
【发布时间】:2016-03-13 17:52:51
【问题描述】:

我一直在寻找更新文件中 xml 的最佳方法。我刚刚切换到使用 XmlReader(来自 XDocument 方法)以提高速度(不必读取内存中的整个文件)。

我的 XmlReader 方法运行良好,当我需要读取一个值时,它会打开 xml,开始读取并且只读取到所需的节点,然后关闭所有内容。它非常快速有效。

现在我已经完成了这项工作,我想创建一个更新已经存在的 xml 的方法。我想保持相同的想法,只在内存中读取需要的内容。所以想法是,阅读直到我正在更改的节点,然后使用编写器更新该值。

我看到的所有东西都有一个 XmlReader 读取,而使用一个 XmlWriter 写入所有东西。如果我这样做了,我会假设我必须让它像 XDocument 那样运行整个文件。以answer 为例。

是否有可能只使用阅读器并阅读到我正在尝试编辑的节点然后更改 innerxml 或其他东西?

在文件中更新 XML 的最快和最有效的方法是什么?

  • 我只想将我正在尝试编辑的内容读入内存,而不是 整个文件。
  • 我还想说明不支持的节点 存在(需要添加)。

【问题讨论】:

  • 您是在问如何就地更新 XML 文件吗?因为 XML 不是为此而设计的。或者您是在问如何通过修改旧文件而不将整个旧文件读入内存来创建新文件?如果是后者,见blogs.msdn.com/b/mfussell/archive/2005/02/12/371546.aspx
  • 确实我在问“如何就地更新它”。那不可能吗?如果我有一个巨大的 xml 文件,并且我只想更新加载整个 XML 文件的第一个节点,那将需要很长时间。我想避免这种情况。至于你的第二个问题,我引用的答案就是……
  • 并非如此,请参阅Write to existing xml file without replacing it's contents (XmlWriter)XML 文件只是连续的文本文件。它们不是数据库或随机访问文件。没有办法只写到它们中间。 我能想到的就是像stackoverflow.com/questions/10252974/… 那样操作底层流
  • 我喜欢结合使用 XmlReader 和 Linq。请参阅我在以下帖子中的回答:stackoverflow.com/questions/35736230/…。获得 XmlElement 后,使用 Linq 方法很容易更新。
  • @jdweng 介意在这里提交答案吗?我在您引用的那个答案中看到的是(1)不写入 xml 文档(这是我的问题的全部内容)和(2)我的问题明确表示不要使用 XDocument(读取整个 xml 文件)做。但我欢迎一个我可能能够接受的答案。 ;) 谢谢

标签: c# xml winforms .net-4.0


【解决方案1】:

根据设计,XmlReader 代表文档的“只读只进”视图,不能用于更新内容。使用XmlDocumentXDocumentXElementLoad 方法仍会导致将整个文件读入内存。 (在后台,XDocumentXElement 仍然使用 XmlReader。)但是,您可以使用 Load 方法的重载将原始 XmlReaderXElement 组合在一起使用 @987654332 @。

您没有描述您的 XML 结构,但您会想要做类似的事情:

var reader = XmlReader.Create(@"file://c:\test.xml");  
var document = XElement.Load(reader);
document.Add(new XElement("branch", "leaves"));
document.Save("Tree.xml");

要查找特定节点(例如,具有特定属性值),您需要执行类似的操作:

var node = document.Descendants("branch")
                   .SingleOrDefault(e => (string)e.Attribute("name") == "foo");

【讨论】:

  • 只是为了确认所有方法 XmlDocument.Load()、XElement.Load() 和 XDocument.Load() 仍然正确加载整个文件?您的答案的措辞方式使您似乎可以选择是否选择将整个文件加载到内存中。我的印象是流式读/写的唯一方法是使用 XmlReader/XmlWriter。我认为所有的 Load() 方法都会将整个文件加载到内存中。
  • @ArvoBowen 这几乎是正确的。 XmlDocument.Load() 会将整个文档加载到内存中。 XElement.Load()XDocument.Load() 方法不会将整个文档加载到内存中。将它们视为“按需加载”。
  • 我不同意...XDocument doc = XDocument.Load(@"file://c:\test.xml"); File.Delete(@"c:\test.xml"); Console.WriteLine(doc); 显示整个 xml 文件。一旦调用 Load() 方法,整个 xml 文件就在内存中。在我的示例中,我 Load() 文件,然后删除实际的 xml 文件,然后显示 doc 对象的内容并返回整个文件。
  • @ArvoBowen:我明白你在说什么。 XDocument.Load()XElement.Load() 在引擎盖下都使用 XmlReader。当您致电Console.WriteLine(doc)。如果您尝试类似的测试但使用原始 XmlReader 并删除文件,您会得到相同的结果吗?
  • 不,因为使用 XmlReader 您必须执行 XmlReader reader = XmlReader.Create(@"file://c:\test.xml"); reader.Read(); Console.WriteLine(reader.Value); 并且只会让您获得声明。阅读器与 XmlDocument 和 XDocument 等基于 DOM 的对象完全不同。我所知道的流式读写的唯一方法是 XmlReader/XmlWriter。您的回答很好,我不介意点击那张支票,但它给读者留下了错误的印象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-28
  • 1970-01-01
  • 1970-01-01
  • 2011-06-08
  • 2010-09-22
相关资源
最近更新 更多