Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C#(.NET2.0)中区分大型XML文件_C#_Xml_Diff - Fatal编程技术网

在C#(.NET2.0)中区分大型XML文件

在C#(.NET2.0)中区分大型XML文件,c#,xml,diff,C#,Xml,Diff,我有点不得不使用.NET2.0,所以LINQXML不可用,尽管我对它的比较感兴趣 我必须编写一个内部程序来下载、提取和比较一些大型XML文件(每个文件大约10兆),这些文件基本上都是构建配置。我第一次尝试使用库,例如,但比较文件需要2-3分钟,即使忽略空白、名称空间等(我一次测试每个忽略一个,以尝试找出最快的速度)。我试图实现我自己的想法-XmlDocument对象中的节点列表,根的直接子代(顺便说一下,45000个子代)的键字典,它们指向int以指示XML文档中的节点位置。。。所有这些都至少花

我有点不得不使用.NET2.0,所以LINQXML不可用,尽管我对它的比较感兴趣

我必须编写一个内部程序来下载、提取和比较一些大型XML文件(每个文件大约10兆),这些文件基本上都是构建配置。我第一次尝试使用库,例如,但比较文件需要2-3分钟,即使忽略空白、名称空间等(我一次测试每个忽略一个,以尝试找出最快的速度)。我试图实现我自己的想法-XmlDocument对象中的节点列表,根的直接子代(顺便说一下,45000个子代)的键字典,它们指向int以指示XML文档中的节点位置。。。所有这些都至少花了2分钟运行

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

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

因此,尽管XML很流行,但我相信一定有人做过类似的事情。比较这些大型XML的快速有效方法是什么?(首选开源或免费)

编辑:一个节点示例-我只需要找到缺少的名称元素(也有超过45k个节点)


某个文件
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工具基于存在纯文本的假设。我们的眼球也是如此。为什么
    XmlReader
    ?您可以使用SAX,这是内存有效的,但是
    XmlReader
    更有效。至于纯文本文件的精确规格…您只是没有包含足够的信息
  • 将纯文本文件保存到某个临时目录
  • 使用命令行diff实用程序可以获得一些diff输出。是的,我知道,这不是纯粹的和正确的,但它是开箱即用的,并且没有编码要做。如果你熟悉一些C#diff API(我不熟悉),那么,当然可以使用该API
  • 删除临时文件。(如果要重复使用,可以选择保留它们。)

请提供更多的上下文。您需要什么样的输出?您想要什么样的差异?@Robert Harvey-我已经浏览了该页面,没有luck@Drake:嗯,佩奇得出的结论是,用Linq将您自己的解决方案转换为XML相对简单。如果这仅仅是“购物”问题,这并不是真正的主题。是的,这就是我到目前为止所做的,而且效果很好,只是希望有一个更“XML”比纯文本更有效diff@DrakeClarris,这里的关键洞察是XML和diff输出根本不匹配和结合。这就是为什么希望使用更XML的方式做事情是没有意义的。你也可以希望使用更角度的方式来滚动轮子。我以前试过一本字典,但出于任何原因,在我的大脑中,我认为T将更有效地将索引存储到节点列表中使用(不能真的说为什么,我想在错误的方向上思考)。这花了几分钟。给了一个镜头-并且工作得很好,几乎和纯文本扩散一样快。不知道为什么我没有考虑将引用存储到实际节点而不是…
<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.