试图了解如何使用 LIINQToXML 有条件地写出 element/attributes

Trying to understand how to conditionally write out element/attributes with LIINQToXML

这是我第一次使用 LINQToXML 创建 XML 文档。 我想了解如何在创建文档时有条件地创建属性(或元素)?

在这个例子中,一辆给定的汽车 may/may 没有它的特征,所以在那种情况下我不想创建那个元素,我也可能在特征节点中有某些可能丢失的属性。

我该如何处理这些情况?

 XDocument xDoc = new XDocument(
                new XElement("root", 
                    new XElement("NodeA"),   
                    new XElement("Cars", 
                        from p in listCars
                        select new XElement("Car", new XAttribute("name", p.CarName),
                            new XElement("Feature", new XAttribute("door", p.Door), new XAttribute("model", p.Model))
                            )
                        )
                )
                );

期望结果 #1(给定汽车缺少所有功能):

<root>
    <NodeA />
    <Cars>
        <Car name="Honda">      
            <Feature door="4" model="Accord"  />
        </Car>
        <Car name="Ford" />     
    </Cars>
</root>

期望的结果 #2(可能存在一些特征)

<root>
    <NodeA />
    <Cars>
        <Car name="Honda">      
            <Feature door="4" model="Accord"  />
        </Car>
        <Car name="Ford">       
            <Feature model="Focus"  />
        </Car>
    </Cars>
</root>

这里有 2 个单独的解决方案。要么使用一种方法来创建功能节点,要么一次完成所有操作:

    static void Main(string[] args)
    {
        var listCars = new List<Car>();
        listCars.Add(new Car { CarName = "test 1", Door = "0", Model = "" });
        listCars.Add(new Car { CarName = "test 2", Door = "", Model = "" });
        listCars.Add(new Car { CarName = "test 3", Door = "0", Model = "0" });

        XDocument xDoc2 = new XDocument(
               new XElement("root",
                   new XElement("NodeA"),
                   new XElement("Cars",
                       from p in listCars
                       select new XElement("Car",
                           new XAttribute("name", p.CarName),
                           p.Door != "" || p.Model != "" ? 
                            new XElement("Feature",
                                p.Door != "" ? new XAttribute("door", p.Door) : null,
                                p.Model != "" ? new XAttribute("model", p.Model) : null) : null
                           )
                       )
               )
               );


        XDocument xDoc = new XDocument(
               new XElement("root",
                   new XElement("NodeA"),
                   new XElement("Cars",
                       from p in listCars
                       select new XElement("Car",
                           new XAttribute("name", p.CarName),
                           CreateFeature(p)
                           )
                       )
               )
               );
    }

    static XElement CreateFeature(Car p)
    {
        var el = new XElement("Feature",
            p.Door != "" ? new XAttribute("door", p.Door) : null,
            p.Model != "" ? new XAttribute("model", p.Model) : null);
        return !el.Attributes().Any() ? null : el;
    }

如果您提供 null 而不是元素,它将被忽略,因此您可以使用如下结构。

p.CarName != null ? new XAttribute("name", p.CarName) : null

如果您使用的是 C# 6,则可以使用 null 传播。