2

これをLINQで書くことは可能ですか?LINQを使ってみました。ただし、2回ループする必要があると思いました。最初にa存在するかどうかを確認し、次にを繰り返しますqs

だから私はこのコードを思いついた。

public a Traverse(List<q> qs,string id)
    {

        foreach (var q in qs)
        {
            if (q.as.Any(a => a.Id == id))
            {
                return q.as.First(a => a.Id == id);

            }

            foreach (var a in q.as)
            {
                var result =Traverse(a.qs, id);
                if(result != null)
                  return result;
            }
        }
        return null;
    }  

「q」が「a」を持ち、「a」が「q」を再帰的に持つようなXMLから読んでいます。

に属する一意のIDを見つける必要がありますa

他のスレッドで議論があったことは知っていますが、役に立ちませんでした。

編集:これがXMLのスニペットです

  <qs xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <qs>
    <q>q 1</q>
    <Id>1</Id>
    <as>
      <a>
        <aprop>a</aprop>
        <Id>a 1.1</Id>
        <qs>
          <q>
            <q>q 1.1.1</q>
            <Id>1.1.1</Id>
            <as>
              <a>
                <a>a</a>
                <Id>a 1.1.1.1</Id>
                <qs />
                <type>1</type>
              </a>
              <a>
                <a>a</a>
                <Id>a 1.1.1.2</Id>
                <qs />
                <type>1</type>
              </a>
            </as>
          </q>
          <q>
            <q>q 1.1.2</q>
            <Id>1.1.2</Id>
            <as>
              <a>
                <a>a</a>
                <Id>a 1.1.2.1</Id>
                <qs />
                <type>1</type>
              </a>
              <a>
                <a>a</a>
                <Id>a 1.1.2.2</Id>
                <qs />
                <type>1</type>
              </a>
            </as>
          </q>
4

4 に答える 4

7

あなたが本当に何を達成しようとしているのかわかりません。それが私が問題を理解する方法です:

メソッドパラメータとして指定された 値と等しい値を持つ<a>名前の別のタグを含むタグを探しています。要素が見つからない場合、メソッドはを返す必要があります。<Id>idnull

Descendants()私はそれがメソッドを使用してXMLで行うことができると思います:

たとえば、クラスdocのインスタンスである、という変数にXMLをロードするとします。XDocument

var query= from a in doc.Descendants("a")
           let i = (string)a.Element("Id")
           where i == id
           select a;

return query.FirstOrDefault();
于 2013-02-20T21:10:27.083 に答える
3

LINQ to XMLが機能する場合は、MarcinJuraszekの答えが最適です。LINQ to Objectsの質問に対処するために、このようなものはどうですか?

    public a Traverse(IQueryable<q> qList, string id)
    {
        return this.GatherAs(qList).FirstOrDefault(a => a.Id == id);
    }

    public IQueryable<a> GatherAs(IQueryable<q> qList)
    {
        IQueryable<a> aList = qList.SelectMany(q => q.aList);

        if (aList.Count != 0)
            aList = aList.Union(this.GatherAs(aList.SelectMany(a => a.qList)));

        return aList;       
    }
于 2013-02-20T21:20:44.030 に答える
0

LINQを使用して相互に参照するものをトラバースすることは、私には非常に難しいように見えます。qとクラスが1つにマージされた方が簡単です。

ただし、最初に、関数は次のように簡略化できます。

public a Traverse(List<q> qs, string id)
{
    foreach (var q in qs)
    {
        foreach (var a in q._as)
        {
            if (a.Id == id)
                return a;
            else
                return Traverse(a.qs, id);
        }
    }
    return null;
}
于 2013-02-20T21:07:36.290 に答える
-1

XDocumentxmlのクエリを少し簡単に使用できるはずです

例:

  XDocument xdoc = XDocument.Load("c:\\MyXmlFile.xml");
  var results = xdoc.Descendants("a").Descendants("Id").Select(id => id.Value);

Id要素からすべての値を返しますa

于 2013-02-20T21:25:01.280 に答える