代码之家  ›  专栏  ›  技术社区  ›  vondip

C#扩展where方法-未找到元素时处理案例

  •  1
  • vondip  · 技术社区  · 15 年前

    我正在尝试使用xDocument和 LINQ to XML . 我要执行以下操作:

    获取满足特定条件的所有元素,如果不满足,则从xDocument返回另一个属性。

    例子:

    <cars>
        <car>
            <patrol type="oil">
                <url> http://Toyotaoil.com </url>
            </patrol>
        </car>
        <car>
            <patrol type="oil">
                <url> http://BMWoil.com </url>
            </patrol>
            <patrol type="gas">
                <url> http://BMWgas.com </url>
            </patrol>
        </car>
        <car>
            <patrol type="gas">
                <url> http://Hondagas.com </url>
            </patrol>
        </car>
    

    现在我想从这个查询中得到一个石油巡逻队的名单,除非这辆车不用汽油,然后我会对汽油感到满意。

    where 哪里

    6 回复  |  直到 15 年前
        1
  •  2
  •   Yvo    15 年前

    下面的解决方案可以让您灵活地查询任何您喜欢的内容:

    var result = from car in xdoc.Element("cars").Elements("car") 
                 let patrols = car.Elements("patrol")
                 let oils = patrols.Where(patrol => patrol.Attribute("type") == "oil")
                 select new {
                        Car = car,
                        Patrols = (oils.Any() ? oils : patrols)
                 }
    

    我这里没有Visual Studio,所以我希望它可以编译:)
    请提供更多关于您喜欢选择什么的信息,我将为您提供更具体的LINQ语句。

        2
  •  2
  •   dtb    15 年前
    xdoc.Element("cars")
        .Elements("car")
        .Select(car => car.Elements("patrol")
                          .SingleOrDefault(p => (string)p.Attribute("type") == "oil")
                       ??
                       car.Elements("patrol")
                          .Single(p => (string)p.Attribute("type") == "gas"));
    
        3
  •  1
  •   Lasse Espeholt    15 年前

    var query = from element in someElements
                select element.Attribute("type").Value == "oil"
                    ? returnSomethingWhenItIsOil
                    : returnSomethingWhenItIsSomethingElse;
    

    var query = from element in someElements
                where element.Attribute("type") == "oil"
                    || element.Attribute("type") == "gas"
                select element;
    

    但请更好地解释这个问题,谢谢:)

        4
  •  0
  •   Jon Skeet    15 年前

    听起来你根本不需要where子句——你只需要一个select子句来选择一个或另一个值。

    但是,您的示例并没有真正描述如何基于这些值选择不同的项—您会选择哪个“其他属性”?你说的“汽车在哪里用汽油”是什么意思?如果你能提供更多例子的细节,那么给你匹配的代码应该不会太难。

        5
  •  0
  •   Asad    15 年前
                           var cars = from c in xdoc.Descendants("car")
                           where
                           (c.Element("patrol").Attribute("type").Value == "oil" ||
                           c.Element("patrol").Attribute("type").Value == "gas")
                           select new Car
                           {
                               FuelType = c.Element("patrol").Attribute("type").Value.ToString()
                           };
    
        foreach (Car c in cars)
            {
                Console.WriteLine(c.ToString());
            }
    
        class Car
        {
            public string FuelType { get; set; }
            public override string ToString()
            {
                return "Car FeulType = " + this.FuelType.ToString();
            }
        }
    

    这些是我得到的结果

    alt text http://img694.imageshack.us/img694/5016/carse.jpg

        6
  •  -1
  •   Benjamin Podszun    15 年前

    Order 根据您的规格,按型号分类,取 FirstOrDefault() .


    var patrols = from car in doc.Root.Elements()
                  let p = car.Elements().OrderBy(patrol=>patrol.Attribute("type").Value).First()
                  select p;
    

    每辆车返回一个结果。检查 OrderBy 条款,并作相应调整。这将导致:

    <patrol type="oil">
      <url> http://Toyotaoil.com </url>
    </patrol>
    
    <patrol type="gas">
      <url> http://BMWgas.com </url>
    </patrol>
    
    <patrol type="gas">
      <url> http://Hondagas.com </url>
    </patrol>
    

    再次编辑:啊,现在点击了。是的,这只返回一个单一的项目每辆车-Zyphrax提供了一个很好的解决方案。