0

(最初の投稿、優しくしてください!)

私は、LINQ to XMLの栄光と弱さをすべて学び、自分がやりたいことを実行するためにそれをハックしようとしています。

このようなXMLファイルが与えられた場合-

<list>
<!-- random data, keys, values, etc.-->

  <key>FIRST_WANTED_KEY</key>
  <value>FIRST_WANTED_VALUE</value>

  <key>SECOND_WANTED_KEY</key>
  <value>SECOND_WANTED_VALUE</value> <!-- wanted because it's first -->

  <key>SECOND_WANTED_KEY</key>
  <value>UNWANTED_VALUE</value>  <!-- not wanted because it's second -->

  <!-- nonexistent <key>THIRD_WANTED_KEY</key> -->
  <!-- nonexistent <value>THIRD_WANTED_VALUE</value> -->

<!-- more stuff-->
</list>

既知の「必要なキー」のセットの値を堅牢な方法で抽出したい。つまり、SECOND_WANTED_KEY2回表示された場合は、だけが必要SECOND_WANTED_VALUEであり、は必要ないUNWANTED_VALUE。さらに、THIRD_WANTED_KEY表示される場合と表示されない場合があるため、クエリはそれも処理できる必要があります。それは他のキーの前に表示されると想定FIRST_WANTED_KEYできますが、他のキーの順序については何も想定できません。キーが2回表示される場合、その値は重要ではなく、最初のキーのみが必要です。文字列で構成される匿名データ型で問題ありません。

私の試みは、これらの線に沿った何かを中心にしています。

var z = from y in x.Descendants()
        where y.Value == "FIRST_WANTED_KEY"
        select new
        {
          first_wanted_value = ((XElement)y.NextNode).Value,
         //...
        }

私の質問はそれがどうあるべきかという...ことです。たとえば、私は試しました(醜い、私は知っています)

second_wanted_value = ((XElement)y.ElementsAfterSelf()
                      .Where(w => w.Value=="SECOND_WANTED_KEY")
                      .FirstOrDefault().NextNode).Value

.NextNodeこれにより、キーがどこにでも存在するか、存在しないようになるはずですが、nullでは機能しないように見えるため、うまくいきXElementませんでした。

私も追加しようとしました

.Select(t => { 
    if (t==null) 
        return new XElement("SECOND_WANTED_KEY",""); 
    else return t;
})

whereの後に節がありますが、それも機能していません。

私は提案、(建設的な)批判、リンク、参照、またはGoogleへのフレーズの提案などを受け入れます。私はグーグルとSOの周りをチェックすることをかなりの割合で行ったので、助けていただければ幸いです。

ありがとう!

編集: これに複雑さの層を追加しましょう-そもそもこれを含めるべきでした。XMLドキュメントが次のようになっているとしましょう。

<lists>
    <list>
      <!-- as above -->
    </list>
    <list>
      <!-- as above -->
    </list>
</lists>

そして、これらのキーと値のペアの複数のセットを抽出したいと思います。質問/注意:SECOND_WANTED_KEY最初の<list>要素には表示されないが、2番目の要素には表示される場合、誤って2番目のリスト要素を取得したくありませんSECOND_WANTED_KEY

編集#2:

別のアイデアとして、私HashSetが探しているキーをいくつか作成して、これを実行してみました。

HashSet<string> wantedKeys = new HashSet<string>();
wantedKeys.Add("FIRST_WANTED_KEY");
//...add more keys here
var kvp = from a in x.Descendants().Where(a => wantedKeys.Contains(a.Value))
          select new KeyValuePair<string,string>(a.value,
             ((XElement)a.NextNode).Value);

これにより、すべてのキーと値のペアが取得されますが、ペアを親の`'要素に適切に「関連付ける」ことが保証されるかどうかはわかりません。これら2つのアプローチの考えや比較は役に立ちます。

ステータスアップデート2010年4月9日

今のところ、私はまだハッシュセットアプローチが最も好ましいと考えています。.NETによって実行されるXML処理のほとんどは、ドキュメントの順序で実行されるようです。これまでのところ、すべてのテストケースが機能しています。

報奨金や賛成の回答を提供しますが、そのための十分な担当者ポイントがありません。今日は答えを決めますので、どうぞ!ありがとう。

4

2 に答える 2

0

これは、次を含む最初<value>の要素の後の最初の要素の値を取得します。<key>"SECOND_WANTED_KEY"

XDocument doc;

string result = (string)doc.Root
                           .Elements("key")
                           .First(node => (string)node == "SECOND_WANTED_KEY")
                           .ElementsAfterSelf("value")
                           .First();

必要に応じて null チェックを追加します。

于 2010-04-07T16:35:50.990 に答える
0
XDocument doc = ...

var wantedKeyValuePairs =
    from keyElement in doc.Root.Elements("key")
    let valueElement = keyElement.ElementsAfterSelf("value").First()
    select new { Key = keyElement.Value, Value = valueElement.Value } into kvp
    group kvp by kvp.Key into g
    select g.First();

説明 : このクエリは、各<key>要素とそれに続く<value>要素を取得し、これらの要素とキーと値のペアを作成します。次に、キーと値のペアをキーごとにグループ化し、各キーの最初のキーと値のペアのみを取得します

于 2010-04-07T16:38:16.667 に答える