2

是否可以在 LINQ 中编写此代码?我尝试使用 LINQ。但是,我认为它必须循环两次;首先验证是否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;
    }  

我正在从 XML 中读取它,就像“q”有“a”,“a”有“q”以递归方式。

我需要找到属于的唯一 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>标签,它包含另一个名为value 的标签,其<Id> 值等于给id定的方法参数。如果未找到元素,则方法应返回null

我认为它可以使用Descendants()方法在 XML 上完成:

假设我们将您的 XML 加载到一个名为 的变量doc中,该变量是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 和 a 类合并到一个类中会更容易。

但是,作为开始,您的功能可以这样简化:

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

您应该能够XDocument更轻松地查询您的 xml

例子:

  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 回答