如何有条件地读取LINQToXML中的元素

时间:2016-02-10 18:50:15

标签: linq c#-4.0 linq-to-xml

如何使用LINQToXml创建所需的列表? 到目前为止,我对两次尝试都很接近。
我应该能够做到这一点,而不是创建单独的查询吗?

这是我的XML:

<main>
  <cars>
    <car name="Honda">
      <feature door="4" name="Accord" />
      <feature door="2" name="Civic"/>
      <feature door="4" name="CRV"/>
    </car>
    <car name="Ford"/>
    <car name="Kia"/>
    <car name="Subaru">
      <feature door="4" name="Outback"/>
      <feature door="4" name="Legacy"/>
    </car>
  </cars>
</main>

尝试#1

  • 这将返回第一辆带有功能的车。

    var listCars = (from c in doc.Root.Descendants("cars")
    select new Car
    {
       Model = (p.Element("car") != null) ? p.Element("car").Attribute("name").Value : null,
       Door = (p.Element("car") != null) ? p.Element("car").Attribute("door").Value : null,
       Name = p.Attribute("name").Value
    }).ToList();
    

    尝试#2

  • 这将返回所有具有功能的汽车
  • 福特和起亚将失踪

    var cars = from c in doc.Root.Descendants("cars")
    select c;
    
    var listPermissions = (from c in cars.Descendants("car")
    let cName = p.Parent.Attribute("name").Value
    select new Car
    {
      Model = p.Attribute("name").Value,
      Door = p.Attribute("door").Value,
      Name = pgn
    }).ToList();
    

    我要做的是创建一个汽车列表,如下所示:

  • 本田,4,雅阁
  • 本田,2,思域
  • 本田,4,CRV
  • Ford,null,null
  • Kia,null,null
  • 斯巴鲁,4岁,内陆
  • 斯巴鲁,4岁,遗产

  • 1 个答案:

    答案 0 :(得分:1)

    您可以使用101 LINQ Samples中列出的LINQ中的LEFT JOIN来完成此操作。

    var makes =
        (from doc in document.Root.Descendants("cars").Descendants("car")
         join f in document.Root.Descendants("cars").Descendants("car").Descendants("feature") 
           on doc.Attribute("name").Value.ToLowerInvariant() equals f.Parent.Attribute("name").Value.ToLowerInvariant() into ps
         from f in ps.DefaultIfEmpty()
       select new
            {
                Model = doc.Attribute("name").Value,
                Door = f == null ? string.Empty : f.Attribute("door").Value,
                Name = f == null ? string.Empty : f.Attribute("name").Value
            })
        .ToList();