如何有条件地读取 LINQ To XML 中的元素

How to conditionally read elements in LINQToXML

我将如何使用 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

  • 这将是return第一辆具有此功能的汽车。

    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

  • 这将 return 所有具有特征的汽车
  • 福特和起亚将失踪

    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
  • 福特,空,空
  • 起亚,null,null
  • 斯巴鲁,4,傲虎
  • 斯巴鲁,4,力狮

  • 您可以按照 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();