从不同的 XML 元素创建相同的 LINQ 匿名类型

Posted

技术标签:

【中文标题】从不同的 XML 元素创建相同的 LINQ 匿名类型【英文标题】:Create same LINQ anonymous type from different XML element 【发布时间】:2018-11-05 01:51:25 【问题描述】:

我有一个这样的 XML 文件:-

请注意,每个<Field></Field> 可以有不同的元素,例如突出显示的<I32><String>。我想在这样的数据网格视图中显示元素名称,其中类型是元素的名称(I32 或字符串或<Field> 的其他子元素):-

到目前为止,我已经尝试过这段代码,但它返回 An unhandled exception of type 'System.NullReferenceException'

XDocument doc = XDocument.Load("GetLotDetails.xml");
var data = doc.Descendants("Document").Where(x => (String)x.Attribute("name") == "DATA").SelectMany(x => x.Elements("Field"));
var query = from d in data
            let str = d.Element("String").Name
            let other = d.Element("I32").Name
            select new
            
                 Name = d.Attribute("name").Value,
                 Type = str.Equals("String") ? "String" : (other.Equals("I32") ? "I32" : null),        
                 Value = d.Value,
            ;
dataGridView1.DataSource = query.ToList();

所以想法是让匿名Type = *whatever element name under field*。如何在 LINQ select 语句中提取不同的元素名称并将其赋予相同的未知类型变量?

【问题讨论】:

【参考方案1】:

它与匿名类型无关。你错过了一个空检查

var query = 
    from d in data
    let element = d.Element("String") ?? d.Element("I32")
    select new
    
        Name = d.Attribute("name").Value,
        Type = element?.Name,
        d.Value
    ;

在您的原始查询中,您无条件地从两个可能的节点读取Name,但对于任何给定的d,其中一个节点将是null。我本可以使用空条件运算符d.Element("String")?.Name 编写它,但在这种情况下,上面的内容更具可读性,因为原始查询中的附加投影会增加噪音和潜在的混乱。

【讨论】:

谢谢。现在可以了。我应该更好地理解null 的逻辑。 (-.-)"

以上是关于从不同的 XML 元素创建相同的 LINQ 匿名类型的主要内容,如果未能解决你的问题,请参考以下文章

Linq to XML的基本操作

Linq XML to Object,其中 xml 节点具有嵌套元素

具有匿名类型和用户定义类型的 LINQ 选择查询

LINQ:不同的值

使用 LINQ 从选定的 XML 元素填充 DataGridView

LINQ to XML - 从文件加载 XML 片段