0

複雑なケースがあります。3つのXMLファイルがあり、それらを同時に読み取り、一致に基づいて結果を取得する必要があります。以下は、私がやっていることとほとんど同じように、実際の(しかし偽の)例です。

たとえば、2つの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のセンテンスIDがx2のセンテンスIDと等しい場合に、x1とx2からセンテンスを選択するためのより良い効率的な方法はありますか?

4

3 に答える 3

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")
            });
于 2012-04-17T15:01:30.553 に答える
1

Linq では、次のステートメントは同等であり、同じ結果が得られます。

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

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

それらは同じ SQL に変換されます (Linq to SQL を使用)。joinどちらの場合も、MS SQL の場合、結果の SQL には join 句が含まれます (そのため、データベースにクエリを実行するときに柔軟性の低いものを使用する必要はありません。

ただし、Linq to ObjectsLinq to XMLの場合、どちらも異なる方法で実行されます。1 つ目はネストされたループになり、2 つ目はそうではありません。

joinしたがって、@NSGagaが提案したように使用するように実装を変更するだけです。

別の最適化は次を追加し.ToList()ます。

ListBox.DataContext = ch;

データバインディングについてはよくわかりませんが、linq の遅延性質のため、式が複数回再評価される可能性があります。

于 2012-04-17T15:20:59.280 に答える
0

簡単!各ファイルを順番に確認するだけです。最初のパス: の辞書を作成しますsentenceNumber > SentenceInlanguage1

SentenceInLanguage12 番目のパスで、示したコードのように列挙型を作成し、変数の最初のパスからのデータを貼り付けます。

両方を一緒に処理したい場合は、列挙子 ( GetEnumerator) を取得し、単純な古いループでそれらを処理し、ループ本体の最後で両方の列挙子whileの次の処理に移動します。XElement

于 2012-04-17T14:50:32.420 に答える