0

我有点不得不使用 .Net 2.0,所以 LINQ xml 不可用,虽然我很感兴趣它会如何比较......

我必须编写一个内部程序来下载、提取和比较一些本质上是构建配置的大型 XML 文件(每个大约 10 兆)。我第一次尝试使用库,例如​​ Microsoft 的 XML diff/patch,但比较文件需要 2-3 分钟,即使忽略空格、命名空间等(我一次测试每个忽略一个,试图找出什么是最快)。我试图实现我自己的想法——来自 XmlDocument 对象的节点列表、根的直接后代的键的字典(顺便说一下,45000 个孩子)指向整数以指示 XML 文档中的节点位置......至少运行 2 分钟。

我的最终实现在 1-2 秒内完成 - 我使用几行上下文对 diff 进行了系统进程调用,并将这些结果保存以显示(我们的开发机器包括 cygwin,谢天谢地)。

我不禁想到有一种更好的、特定于 XML 的方法来做到这一点,它与纯文本差异一样快 - 特别是因为我真正感兴趣的是 Name 元素,它是每个直接的子元素后代,并且可以出于我的目的丢弃文件的 4/5(我们只需要知道包含哪些文件,而不需要知道涉及语言或版本的任何其他内容)

因此,尽管 XML 很受欢迎,但我敢肯定有人不得不做类似的事情。比较这些大型 XML 的快速有效方法是什么?(最好是开源或免费的)

编辑:节点样本 - 我只需要找到缺失的 Name 元素(也有超过 45k 个节点)

<file>
     <name>SomeFile</name>
     <version>10.234</version>
     <countries>CA,US</countries>
     <languages>EN</languages>
     <types>blah blah</types>
     <internal>N</internal>
</file>
4

2 回答 2

0
XmlDocument source = new XmlDocument();
source.Load("source.xml");
Dictionary<string, XmlNode> files = new Dictionary<string, XmlNode>();
foreach(XmlNode file in source.SelectNodes("//file"))
    files.Add(file.SelectSingleNode("./name").InnerText, file);

XmlDocument source2 = new XmlDocument();
source2.Load("source2.xml");
XmlNode value;
foreach(XmlNode file in source2.SelectNodes("//file"))
    if (files.TryGetValue(file.SelectSingleNode("./name").InnerText, out value))
      // This file is both in source and source2.
    else
      // This file is only in source2.

我不确定你到底想要什么,我希望这个例子对你的追求有所帮助。

于 2012-06-06T20:29:23.210 回答
0

可以通过多种方式区分 XML。不过,您对细节并不是很具体。发生的是文件很大,您只需要 4/5 的信息。

那么算法如下:

  • 规范化文档并将其简化为重要的信息。
  • 保存结果。
  • 比较结果。

实施

  • 使用高效的XmlReader API生成信息的纯文本表示。为什么是纯文本表示?因为差异工具基于存在​​纯文本的假设。我们的眼球也是如此。为什么XmlReader?您可以使用 SAX,它可以节省内存,但XmlReader效率更高。至于该纯文本文件的确切规格……您只是没有包含足够的信息。
  • 将纯文本文件保存到某个临时目录。
  • 使用命令行 diff 实用程序(如GnuWin32 diff)来获取一些 diff 输出。是的,我知道,不是完全正确,而是开箱即用,无需编码。如果您熟悉某些 C# diff API(我不熟悉),那么当然可以使用该 API。
  • 删除临时文件。(或者如果您要重复使用它们,可以选择保留它们。)
于 2012-06-06T20:33:12.247 回答