LINQ to XML 查询 Where() 函数不返回任何内容
LINQ to XML query Where() function not returning anything
我有一个 XML 文件,我想使用 LINQ 解析它以获得包含属性 ID
的所有节点。使用此 ID
、节点名称和祖父母的名称,我想在 LINQ 查询中创建一个新的 object(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>
...
我试过以下查询来做我想做的事,但不幸的是,它不起作用:
items = _xmlFile.Descendants(itemType.ToString())
.Where(x => x.Attribute("ID") != null) // This part returns nothing
.Select(x => new EveItem(x.Name.LocalName,
(uint)x.Attributes().FirstOrDefault(a => a.Name.LocalName == "ID"),
(EveItem.ItemTypes)itemType)).ToList();
当我在 Visual Studio 中调试此查询时,我可以看到 _xmlFile.Descendants(itemType.ToString())
return 是我的 XML 文件的良好子树,但是 .Where(x => x.Attribute("ID") != null)
查询的一部分没有 return 任何东西(所以 .Select(..)
不会在任何东西上执行)。我试图通过此 Where(..)
子句获得的是所有实际具有在其中声明的属性 ID
的节点。
我在这个查询中做错了什么?
编辑:
我已经尝试从对 _xmlFile.Descendants()
的调用中删除 itemType.ToString()
现在它可以工作了,尽管我得到了所有具有 ID
属性的项目而不是仅具有 ID
属性的项目在右侧 itemType
节点(矿石、冰等)下。
为什么会这样?在调试中,我确实看到 _xmlFile.Descendants(itemType.ToString())
调用了 return 正确的 XML 结构。
那是因为您的物品类型节点(矿石、冰等)的 none 具有 ID
属性。该属性是项目类型节点的后代,因此尝试添加 .Descendants()
方法调用,如下所示:
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();
我有一个 XML 文件,我想使用 LINQ 解析它以获得包含属性 ID
的所有节点。使用此 ID
、节点名称和祖父母的名称,我想在 LINQ 查询中创建一个新的 object(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>
...
我试过以下查询来做我想做的事,但不幸的是,它不起作用:
items = _xmlFile.Descendants(itemType.ToString())
.Where(x => x.Attribute("ID") != null) // This part returns nothing
.Select(x => new EveItem(x.Name.LocalName,
(uint)x.Attributes().FirstOrDefault(a => a.Name.LocalName == "ID"),
(EveItem.ItemTypes)itemType)).ToList();
当我在 Visual Studio 中调试此查询时,我可以看到 _xmlFile.Descendants(itemType.ToString())
return 是我的 XML 文件的良好子树,但是 .Where(x => x.Attribute("ID") != null)
查询的一部分没有 return 任何东西(所以 .Select(..)
不会在任何东西上执行)。我试图通过此 Where(..)
子句获得的是所有实际具有在其中声明的属性 ID
的节点。
我在这个查询中做错了什么?
编辑:
我已经尝试从对 _xmlFile.Descendants()
的调用中删除 itemType.ToString()
现在它可以工作了,尽管我得到了所有具有 ID
属性的项目而不是仅具有 ID
属性的项目在右侧 itemType
节点(矿石、冰等)下。
为什么会这样?在调试中,我确实看到 _xmlFile.Descendants(itemType.ToString())
调用了 return 正确的 XML 结构。
那是因为您的物品类型节点(矿石、冰等)的 none 具有 ID
属性。该属性是项目类型节点的后代,因此尝试添加 .Descendants()
方法调用,如下所示:
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();