2012-04-17 13 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

相關問題