2017-05-08 5 views
0

私は現在取り組んでいる一連の関数を持っていますが、そのうちの1つはXMLファイルを解析し、属性ベース私が持っている条件。属性名と値のペアに基づいたXML XMLのlinq検索を作成する

これは私が使用する必要がXMLのサンプルです:

<rs:insert> 
<z:row Inst='AM5001' Event='EventA' HostName='HostA' EventType='NORMAL' TXID='0000003327'/> 
<z:row Inst='AM5001' Event='EventB' HostName='HostB' EventType='NORMAL' TXID='0000011173'/> 
<z:row Inst='AM4067' Event='EventA' HostName='HostA' EventType='NORMAL' TXID='0000011175'/> 
<z:row Inst='AM5546' Event='EventC' HostName='HostC' EventType='NORMAL' TXID='0000011177'/> 
<z:row Inst='AM4567' Event='EventQ' HostName='HostD' EventType='NORMAL' TXID='0000011593'/> 

、これは私がこれまで持っているものの抜粋です:

internal protected IEnumerable<XElement> GetElement(XDocument oXMLDoc 
     , List<KeyValuePair<string, string>> SearchCriteria) 
    { 
     var vElementQuery = oXMLDoc.Elements() 
      .Where(e => SearchCriteria.ForEach(sc => e.Attribute(sc.Key).Value.ToUpper() == sc.Value.ToUpper())) 
      .Select(e => e); 

     foreach (var xElement in vElementQuery) 
     { 
      yield return xElement; 
     } 
    } 

私はエラーを取得していますvElementQueryの私のwhere句に:

のみ割り当て、呼び出し、インクリメント、デクリメント、待って、新しいオブジェクト 式はuのことができステートメントとしてsed

簡単に言うと、私はInstとEventに基づいてクエリを実行しますが、時にはホスト名とEventtypeに基づいている必要があります。

基本的には、一致させる必要のある属性条件の数がわからないので、リストまたは配列として追加することができます。KeyValuePairは名前と私が必要とする比較(値)。

ありがとうございました。

答えて

1

Whereには、述語:e(この場合はXElement)をとり、boolを返す関数が必要です。

voidを返すSearchCriteria.ForEach()の結果を返そうとしています。それはコレクション全体を反復し、各アイテムのためにvoidラムダを呼び出すだけです。したがって、それを述語の本体として使用することはできません。この問題を修正した後は、次の問題になりますが、同じ修正が両方を処理します。

.Where(e => 
    SearchCriteria.ForEach(sc => 
     e.Attribute(sc.Key).Value.ToUpper() == sc.Value.ToUpper() 
    ) 
) 

ForEachので戻りvoid、それはvoidを返すラムダをとります。関数の本体は文でなければなりません。ラムダでは、戻り値の型がvoidでなく、本体が式である場合、その式の結果が返されます。これを暗黙のreturn文と呼びます。しかし、ここで戻り値が無効である - それはthe parameter type of ForEachによって確立されています:

public void ForEach(
    Action<T> action 
) 

Action<T>、1つのパラメータなし戻り値の型を持っています。コンパイラが使用する推論規則は、ForEachに述語を与えようとしているのではなく、void lambdaを書くことを前提としています。

は、ここではそれを与えているラムダの本体です:コンパイラはその前に暗黙のreturnを供給せずに

e.Attribute(sc.Key).Value.ToUpper() == sc.Value.ToUpper() 

、それは声明ではありません。それは表現です。声明として、合法的なC#ではありません。これをコンパイルしてみてください:

1 != 2; 

同じエラーです。 CまたはPerlは気にしませんがC#は気にしません。検索条件のいずれかがその属性のいずれかに一致するeを返す、と言うことです

.Where(e => 
    SearchCriteria.Any(sc => 
     e.Attribute(sc.Key).Value.ToUpper() == sc.Value.ToUpper() 
    ) 
) 

私はあなたの代わりにForEachAnyをしたいかもしれないと思います。 Anyは述語を取り、boolを返し、両方のエラーを修正します。

+0

驚くばかりです。故障のためにありがとう - それは将来私を助けるでしょう。 – clogue

関連する問題