0
<Nodes>
  <Node>
    <ID>1</ID>
    <TIDS>
      <TID>2</TID>
      <TID>3</TID>
    </TIDS>
  </Node>
  <Node>
    <ID>2</ID>
    <TIDS>
      <TID>4</TID>
    </TIDS>
  </Node>
  <Node>
    <ID>3</ID>
    <TIDS>
      <TID>7</TID>
    </TIDS>
  </Node>
  <Node>
    <ID>4</ID>
    <TIDS>
      <TID>7</TID>
    </TIDS>
  </Node>
  <Node>
    <ID>5</ID>
    <TIDS>
      <TID>7</TID>
    </TIDS>
  </Node>
  <Node>
    <ID>6</ID>
    <TIDS>
      <TID>7</TID>
    </TIDS>
  </Node>
  <Node>
    <ID>7</ID>
  </Node>
</Nodes>

fselect TID を選択し、再度 xml をクエリして TID を選択するクエリを作成したい where 条件が ID が 1 に等しい場合、where 条件に 2,3,4,7 を出力したい ID が 5 に等しい場合、put put を入力します7 再帰的なlinqの書き方

4

3 に答える 3

1
 var result = xml.Elements()
   // Find element with <ID>1</ID>
   .Where(x => x.Elements().Any(d => d.Name == "ID" && d.Value == "1"))
   // Find element <TIDS>
   .Elements().Where(x => x.Name == "TIDS")
   // Find elements <TID>
   .Elements().Where(x => x.Name == "TID")
   // Select values
   .Select(x => x.Value);

注、私は次のxmlように変数を作成しました:

   XElement xml = XElement.Parse (@"<Nodes>
  <Node>
    <ID>1</ID>
    <TIDS>
      <TID>2</TID>
      <TID>3</TID>
    </TIDS>
  </Node>
  <Node>
    <ID>2</ID>
    <TIDS>
      <TID>4</TID>
    </TIDS>
  </Node>
  <Node>
    <ID>3</ID>
    <TIDS>
      <TID>7</TID>
    </TIDS>
  </Node>
  <Node>
    <ID>4</ID>
    <TIDS>
      <TID>7</TID>
    </TIDS>
  </Node>
  <Node>
    <ID>5</ID>
    <TIDS>
      <TID>7</TID>
    </TIDS>
  </Node>
  <Node>
    <ID>6</ID>
    <TIDS>
      <TID>7</TID>
    </TIDS>
  </Node>
  <Node>
    <ID>7</ID>
  </Node>
</Nodes>");
于 2013-07-25T20:23:02.163 に答える
0

この関数は、渡されGetTidsた のリストを返しますTIDsIDイニシャルIDが渡されると、リスト ( tidIndex) が返されます。次にループが実行され、各TID値が XML のクエリに使用され、tidList.

List<string> TidList()
{
    var xml = XDocument.Load(@"C:\PathToXml\File.xml");

    var tidIndex = GetTids(xml, "1").ToList();
    var tidList = new List<string>(tidIndex);

    foreach (var tid in tidIndex)
        tidList.AddRange(GetTids(xml, tid));

    return tidList;
}

static IEnumerable<string> GetTids (XDocument xml, string id)
{
    return xml.Descendants("Node")
        .Where(x => x.Element("ID").Value == id)
        .Descendants("TID")
        .Select (s => s.Value);
}

これは以下を返します:

ここに画像の説明を入力

于 2013-07-26T02:06:11.427 に答える
0

再帰的な LINQ は、本番環境のコードで実際に使用したいものというよりも、パーティ トリックのようなものですが、これを行う 1 つの方法を次に示します。

XElement nodes = /* load your xml */;

Func<XElement, int, IEnumerable<int>> query = null;

/* BAD CODE, DO NOT USE! */
query = (x,id) => 
   x.Elements("Node")
     .Where (node => (int)node.Element("ID") == id) // find our node
     .Descendants("TID")      // this will be empty in the base case
     .Select (tid => (int)tid)
     .SelectMany(tid => 
       query(x,tid)           // recurse
       .Concat(new[]{tid})    // keep the current TID if its node had no TIDs
     )
     .Distinct();

var resultOf7423 = query(nodes, 1);
var resultOf7 = query(nodes, 5);
/* END BAD CODE (I HOPE) */

これは不可解で脆弱なコードであり、ほぼ確実に使用すべきではありません。代わりに、次の拡張メソッドを作成できますXElement

public static IEnumerable<int> SelectRelatedIds(this XElement element, int id)
{
    if(element == null) throw new ArgumentNullException("element");
    return SelectRelatedIdsIterator(element, id)
                .Where(i => i != id)
                .Distinct();
}

private static IEnumerable<int> SelectRelatedIdsIterator(XElement element, int id)
{
    yield return id;

    var tids = element.Elements("Node")
                .Where (node => (int)node.Element("ID") == id)
                .Descendants("TID");

    foreach (int tid in tids)
        foreach(var i in  SelectRelatedIdsIterator(element, tid))
            yield return i;
}

これにより、再帰が含まれ、非常に理解しやすくなります (少なくともイテレータ ブロックに頭を悩ませると)。また、LINQ に対応しており、最初の方法では不可能な方法で構成可能になる可能性があります。

于 2013-07-26T01:04:46.533 に答える