在C#(.NET2.0)中区分大型XML文件
我有点不得不使用.NET2.0,所以LINQXML不可用,尽管我对它的比较感兴趣 我必须编写一个内部程序来下载、提取和比较一些大型XML文件(每个文件大约10兆),这些文件基本上都是构建配置。我第一次尝试使用库,例如,但比较文件需要2-3分钟,即使忽略空白、名称空间等(我一次测试每个忽略一个,以尝试找出最快的速度)。我试图实现我自己的想法-XmlDocument对象中的节点列表,根的直接子代(顺便说一下,45000个子代)的键字典,它们指向int以指示XML文档中的节点位置。。。所有这些都至少花了2分钟运行 我的最终实现在1-2秒内完成——我使用几行上下文对diff进行了系统进程调用,并保存了这些结果以显示(谢天谢地,我们的开发机器包括cygwin) 我忍不住想,有一种更好的、特定于XML的方法可以做到这一点,它的速度与纯文本差异一样快——特别是因为我真正感兴趣的是作为每个直系后代的子元素的Name元素,并且为了我的目的可以丢弃文件的4/5(我们只需要知道包含哪些文件,而不需要知道任何其他涉及语言或版本的内容) 因此,尽管XML很流行,但我相信一定有人做过类似的事情。比较这些大型XML的快速有效方法是什么?(首选开源或免费) 编辑:一个节点示例-我只需要找到缺少的名称元素(也有超过45k个节点)在C#(.NET2.0)中区分大型XML文件,c#,xml,diff,C#,Xml,Diff,我有点不得不使用.NET2.0,所以LINQXML不可用,尽管我对它的比较感兴趣 我必须编写一个内部程序来下载、提取和比较一些大型XML文件(每个文件大约10兆),这些文件基本上都是构建配置。我第一次尝试使用库,例如,但比较文件需要2-3分钟,即使忽略空白、名称空间等(我一次测试每个忽略一个,以尝试找出最快的速度)。我试图实现我自己的想法-XmlDocument对象中的节点列表,根的直接子代(顺便说一下,45000个子代)的键字典,它们指向int以指示XML文档中的节点位置。。。所有这些都至少花
某个文件
10.234
加州,美国
EN
废话
N
XmlDocument source=new XmlDocument();
Load(“source.xml”);
字典文件=新字典();
foreach(source.SelectNodes(“//文件”)中的XmlNode文件)
files.Add(file.SelectSingleNode(“./name”).InnerText,file);
XmlDocument source2=新的XmlDocument();
加载(“source2.xml”);
XmlNode值;
foreach(source2.SelectNodes(“//文件”)中的XmlNode文件)
if(files.TryGetValue(file.SelectSingleNode(“./name”).InnerText,out值))
//此文件位于source和source2中。
其他的
//此文件仅在source2中。
我不确定你到底想要什么,我希望这个例子能帮助你完成你的任务。区分XML有很多方法。不过,你对细节不是很具体。事实上,文件很大,你只需要4/5的信息 那么算法如下所示:
- 将文档规范化并简化为重要信息
- 保存结果
- 比较结果
- 使用,这是有效的,以产生您的信息的纯文本表示。为什么纯文本表示?因为diff工具基于存在纯文本的假设。我们的眼球也是如此。为什么
?您可以使用SAX,这是内存有效的,但是XmlReader
更有效。至于纯文本文件的精确规格…您只是没有包含足够的信息XmlReader
- 将纯文本文件保存到某个临时目录
- 使用命令行diff实用程序可以获得一些diff输出。是的,我知道,这不是纯粹的和正确的,但它是开箱即用的,并且没有编码要做。如果你熟悉一些C#diff API(我不熟悉),那么,当然可以使用该API
- 删除临时文件。(如果要重复使用,可以选择保留它们。)
<file>
<name>SomeFile</name>
<version>10.234</version>
<countries>CA,US</countries>
<languages>EN</languages>
<types>blah blah</types>
<internal>N</internal>
</file>
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.