2012-04-17 15 views
0

我有一个复杂的案例:我有三个XML文件,我需要同时读取并根据匹配获取结果。下面是一个工作(但是假的)例子,与我正在做的几乎相似。如何以高效的方式同时读取两个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 

for i in x1 
    for j in x2 

有选择从X1和X2,其中X1的句子ID等于x2的句子ID句子什么更好的和有效的方式?

+1

你有没有调试或分析这看到重处理发生的地方?如果更重的处理来自将文件数据读入内存或进行匹配,可能有利的是知道。 – jlafay 2012-04-17 14:48:22

+0

我不太了解调试工具。但是当我使用简单的调试,但执行下面的语句需要时间'lstBox.DataContext = ch' – wafers 2012-04-17 14:51:34

+0

在同样的笔记中,当我只以一种语言从一个文件读取时,它几乎没有时间,但是当我从两个文件中读取,如上所述,时间呈指数级增长。 – wafers 2012-04-17 14:52:30

回答

1

从我的理解,要,

你可以使用join做到这一点。

这里是一个很好的例子链接LINQ to XML : Join Xml Data (Wriju's BLOG)

...或沿着这些路线的东西...

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") 
      }); 
+0

我需要添加一个条件“和var1.something> ='10'”,我该怎么做? – wafers 2012-04-17 15:15:39

+0

尝试'哪里var1.Attribute(“somehting”)。ToInt()> 10' - 如果这就是你想要的 – NSGaga 2012-04-17 15:28:49

+0

是的,我加了WHERE,它的工作原理...它真的工作!有效率的! – wafers 2012-04-17 15:38:05

0

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

在您的第二遍中,像您在显示的代码中一样创建您的enumerable,并将第一遍中的数据粘贴到SentenceInLanguage1变量中。

如果您希望通过两个一起去,只得到一个枚举(GetEnumerator)并办理那些在一个普通的老while循环,移动到下一个XElement两个普查员在循环体的结束。

+0

我会尝试这个,并从另一个答案的解决方案,根据我的效率观察,我会进一步让你知道。但是,在读取两个单独的数据项中的数据之后,我如何绑定到单个ListBox? – wafers 2012-04-17 15:18:14

1

在LINQ下面的语句是等价的,并会提供相同的结果:

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

and

from i1 in items1 
join i2 in items2 on i1 equals i2 

它们甚至会被转换为相同的SQL(使用Linq to SQL)。对于MS SQL在这两种情况下导致SQL将包含连接子句(这就是为什么疗法是没必要用不太灵活join当您查询数据库。

然而,对于LINQ到对象的LINQ to XML都将被执行首先会导致嵌套循环,其次将不会产生

所以你只需要改变你的实现使用join @NSGaga建议。

另一个优化将增加.ToList()

ListBox.DataContext = ch;

我不知道有关数据绑定,而是因为LINQ的递延性质的存在,你的表现会被重新评估一次以上的可能性。

+0

这几乎完成了,但我无法使用“和”语句x1.inex等于x2.index“和”x1.sss> = 10 ...谷歌搜索的答案 – wafers 2012-04-17 15:23:52

+0

这就是为什么'加入'不是很酷: )几乎你可以做'和x1.sss> = 10'部分。我愿意为这种情况添加另一个'where' – 2012-04-17 15:26:04

+0

,所以你的意思是加入只支持一个条件? – wafers 2012-04-17 15:28:03

相关问题