Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.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# 如何高效地同时读取两个XML文件_C#_.net_Performance_Linq_Linq To Xml - Fatal编程技术网

C# 如何高效地同时读取两个XML文件

C# 如何高效地同时读取两个XML文件,c#,.net,performance,linq,linq-to-xml,C#,.net,Performance,Linq,Linq To Xml,我有一个复杂的例子:我有三个XML文件,我需要同时读取它们并根据匹配得到结果。下面是一个工作,但虚假的例子,几乎类似于我所做的 例如,我有两个xml文件,它们都相似,但在标记和属性方面相似,但内容语言不同。我同时阅读两种语言,就像C文件中的代码: XElement x1 = XElement.Load (@"abc.xml"); XElement x2 = XElement.Load (@"xyz.xml"); var ch = from var1 in x1.Elements("langu

我有一个复杂的例子:我有三个XML文件,我需要同时读取它们并根据匹配得到结果。下面是一个工作,但虚假的例子,几乎类似于我所做的

例如,我有两个xml文件,它们都相似,但在标记和属性方面相似,但内容语言不同。我同时阅读两种语言,就像C文件中的代码:

XElement x1 = XElement.Load (@"abc.xml");
XElement x2 = XElement.Load (@"xyz.xml");


var ch = from var1 in x1.Elements("language1") 
         where var1.Attribute("index").Value == "1"
         from var2 in x2.Elements("language2")
         where var2.Attribute("index").Value == var1.Attribute("index").Value
         select dictChapter as new
         {  
             sentenceNumber = var1.Attribute("index").Value,
             SentenceInLanguage1 = var1.Attribute("text").Value,
             SentenceInLanguage2 = var2.Attribute("text").Value,
         };

ListBox.DataContext = ch;
这里的问题是,x1包含1000个句子,因此x2。上述逻辑的工作方式类似于嵌套循环,这大大降低了处理速度。它就像

x1.1 -> x2.1:1000
x1.2 -> x2.1:1000


有没有更好更有效的方法从x1和x2中选择句子,其中x1的句子id等于x2的句子id?

简单!只需按顺序浏览每个文件。第一步:创建一个sentenceNumber>SentenceInlanguage1字典

在第二个过程中,按照显示的代码创建可枚举项,将第一个过程中的数据粘贴到SentenceInLanguage1变量中


如果您希望同时使用这两种方法,只需获取一个枚举器GetEnumerator,并在一个普通的旧while循环中使用它们,然后移动到循环体末尾两个枚举器的下一个元素。

根据我的理解,您需要

你可以用join来做这件事

下面是一个很好的示例链接

…或者类似的东西

var root = (from var1 in x1.Elements("language1")
            join var2 in x2.Elements("language2") on (string)var1.Attribute("index") equals (string)var2.Attribute("index")
            select new
            {
                SentenceNumber = (string)var1.Attribute("index"),
                SentenceInLanguage1 = (string)var1.Element("text"),
                SentenceInLanguage2 = (string)var2.Element("text")
            });

在Linq中,以下语句是等效的,并将提供相同的结果:

from i1 in items1
from i2 in items2
where i1 == i2

它们甚至将使用LINQtoSQL转换为相同的SQL。对于MS SQL,在这两种情况下,结果SQL都将包含join子句,这就是为什么在查询数据库时不需要使用不太灵活的join

然而,对于LINQtoObjects和LINQtoXML,它们都将以不同的方式执行。第一个将导致嵌套循环,第二个不会

因此,您只需要按照@NSGaga的建议更改您的实现以使用join

另一个优化是添加。ToList:

ListBox.DataContext=ch


我不确定数据绑定,但由于linq的不同性质,您的表达式可能会被重新计算多次

您是否对此进行了调试或分析,以查看繁重的处理发生在何处?知道更繁重的处理是否来自于将文件数据读入内存或进行匹配,这可能是有利的。我对调试工具知之甚少。但是当我使用简单的调试时,但是执行下面的语句时需要时间lstBox.DataContext=chOn同样的注释,当我仅用一种语言读取一个文件时,几乎不需要时间,但是当我读取两个文件时,如上所述,时间呈指数增长。如果有两个列表框,您可能希望尝试并行地为每个列表框分配DataContext。你的代码没有显示你在过滤之后做了什么,所以我不确定是什么原因造成的。这可能与未被访问/读取的数据有关,然后分配给列表框,直到实际使用为止。LINQ就是这样做的。这正是问题所在,我只有一个列表框,无法将两个数据项绑定到一个列表框。我需要再添加一个条件,var1.something>='10',我该怎么做?试试where var1.Attributesomehting.ToInt>10-如果这是您想要的,我添加了where,它可以工作。。。这真的很有效!效率高!现在我真的需要了解JOIN子句是如何工作的?我的版本和使用JOINfrom的不同之处在于,在join被优化时,第一次和第二次都会选择Many,也就是说,在^2或m x n上都会选择Many,但不确定确切的实现方式,但可能是两次或更多。我将尝试这个方法,并从另一个答案中找到解决方案,根据我对效率的观察,我会进一步让你知道。但是,在读取了两个单独数据项中的数据之后,如何绑定到单个列表框?几乎完成了,但是我无法使用and语句x1.inex=x2.index和x1.sss>=10。。。谷歌搜索答案这就是join不酷的原因:你很难做到,x1.sss>=10部分。我建议为这个条件添加另一个where,你是说join只支持一个条件?是的。您可以通过使用匿名对象来实现和for“equal”:在new{i1.prop1,i1.prop2}上,等于new{i2.prop1,i2.prop2},但是像>=这样的东西更复杂
from i1 in items1
from i2 in items2
where i1 == i2
from i1 in items1
join i2 in items2 on i1 equals i2