C# LINQ to XML query Where()函数不返回任何内容

C# LINQ to XML query Where()函数不返回任何内容,c#,linq,parsing,xml-parsing,linq-to-xml,C#,Linq,Parsing,Xml Parsing,Linq To Xml,我想使用LINQ解析一个XML文件,以便获得包含属性ID的所有节点。有了这个ID、节点名和祖父母名,我想在LINQ查询中创建一个新对象(类型为EveItem) 下面是我的XML文件的一部分,以举例说明如何构造它: <?xml version="1.0" encoding="UTF-8"?> <Eve_App> <Item_Types> <Ore> <Arkonor_Category>

我想使用LINQ解析一个XML文件,以便获得包含属性
ID
的所有节点。有了这个
ID
、节点名和祖父母名,我想在LINQ查询中创建一个新对象(类型为
EveItem

下面是我的XML文件的一部分,以举例说明如何构造它:

<?xml version="1.0" encoding="UTF-8"?>
<Eve_App>
    <Item_Types>
        <Ore>
            <Arkonor_Category>
                <Arkonor ID="22"/>
                <Compressed_Arkonor ID="28367"/>
                <Compressed_Crimson_Arkonor ID="28385"/>
                <Compressed_Prime_Arkonor ID="28387"/>
                <Crimson_Arkonor ID="17425"/>
                <Prime_Arkonor ID="17426"/>
            </Arkonor_Category>

            <Bistot_Category>
                <Bistot ID="1223"/>
                <Compressed_Bistot ID="28388"/>
                <Compressed_Monoclinic_Bistot ID="28389"/>
                <Compressed_Triclinic_Bistot ID="28390"/>
                <Monoclinic_Bistot ID="17429"/>
                <Triclinic_Bistot ID="17428"/>
            </Bistot_Category>

            <Crokite_Category>
                <Compressed_Crokite ID="28391"/>
                <Compressed_Crystalline_Crokite ID="28392"/>
                <Compressed_Sharp_Crokite ID="28393"/>
                <Crokite ID="1225"/>
                <Crystalline_Crokite ID="17433"/>
                <Sharp_Crokite ID="17432"/>
            </Crokite_Category>

            <Dark_Ochre_Category>
                <Compressed_Dark_Ochre ID="28394"/>
                <Compressed_Obsidian_Ochre ID="28395"/>
                <Compressed_Onyx_Ochre ID="28396"/>
                <Dark_Ochre ID="1232"/>
                <Obsidian_Ochre ID="17437"/>
                <Onyx_Ochre ID="17436"/>
            </Dark_Ochre_Category>
            ...
        </Ore>

        <Ice>
            <Ice>
                <Blue_Ice ID="16264"/>
                <CLear_Icicle ID="16262"/>
                <Compressed_Blue_Ice ID="28433"/>
                <Compressed_Clear_Icicle ID="28434"/>
                <Compressed_Dark_Glitter ID="28435"/>
                <Compressed_Enriched_Clear_Icicle ID="28436"/>
                <Compressed_Gelidus ID="28437"/>
                <Compressed_Glacial_Mass ID="28438"/>
                <Compressed_Glare_Crust ID="28439"/>
                <Compressed_Krystallos ID="28440"/>
                <Compressed_Pristine_White_Glaze ID="28441"/>
                <Compressed_Smooth_Glacial_Mass ID="28442"/>
                <Compressed_Thick_Blue_Ice ID="28443"/>
                <Compressed_White_Glaze ID="28444"/>
                <Dark_Glitter ID="16267"/>
                <Enriched_Clear_Icicle ID="17978"/>
                <Gelidus ID="16268"/>
                <Glacial_Mass ID="16263"/>
                <Glare_Crust ID="16266"/>
                <Krystallos ID="16269"/>
                <Pristine_White_Glaze ID="17976"/>
                <Smooth_Glacial_Mass ID="17977"/>
                <Thick_Blue_Ice ID="17975"/>
                <White_Glaze ID="16265"/>
            </Ice>
        </Ice>
        ...
当我在Visual Studio中调试此查询时,我可以看到
\u xmlFile.substands(itemType.ToString())
返回XML文件的良好子树,但
.Where(x=>x.Attribute(“ID”)!=null)
部分查询不会返回任何内容(因此
.Select(…)
不会对任何内容执行)。通过这个
Where(…)
子句,我试图得到的是所有实际声明了属性
ID
的节点

我在这个问题上做错了什么

编辑:

我已经尝试从调用
\u xmlFile.subjections()
中删除
itemType.ToString()
,现在它可以工作了,尽管我得到了所有具有
ID
属性的项,而不是仅位于右侧
itemType
节点(Ore、Ice等)下的项


为什么会这样?在调试中,我确实看到
\u xmlFile.subjections(itemType.ToString())
调用返回正确的XML结构

这是因为没有一个项目类型节点(Ore、Ice等)具有
ID
属性。该属性位于项类型节点的子代中,因此请尝试添加
.subjects()
方法调用,如下所示:

items = _xmlFile.Descendants(itemType.ToString())
                .Descendants()  //get descendants of current item type
                .Where(x => x.Attribute("ID") != null)
                .Select(x => new EveItem(
                                x.Name.LocalName,
                                (uint)x.Attributes().FirstOrDefault(a => a.Name.LocalName == "ID"), 
                                (EveItem.ItemTypes)itemType
                            )
                        )
                .ToList();

这很有效。虽然我仍然不明白为什么我必须添加另一个
.subjections()
.subjections()
是否会发回作为传递给它的节点的子节点的所有元素?是的,我的Ore、Ice等节点没有任何
ID
属性,但是它仍然应该检查它们的孩子、孙子等等,直到叶节点没有?这就是我对函数如何工作的理解,我错了吗?不,你一定是糊涂了。在这里,
.substands(itemType.ToString())
,substant是
\u xmlFile
的后代,它的名称是
itemType.ToString())
。你确实是对的。我刚刚查看了msdn文档,了解了两个函数调用(带参数和不带参数)之间的区别。谢谢你指出这一点!
items = _xmlFile.Descendants(itemType.ToString())
                .Descendants()  //get descendants of current item type
                .Where(x => x.Attribute("ID") != null)
                .Select(x => new EveItem(
                                x.Name.LocalName,
                                (uint)x.Attributes().FirstOrDefault(a => a.Name.LocalName == "ID"), 
                                (EveItem.ItemTypes)itemType
                            )
                        )
                .ToList();