【发布时间】:2015-06-08 03:08:34
【问题描述】:
我有一个想要使用 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>
...
我尝试了以下查询来做我想做的事情,但不幸的是,它不起作用:
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()) 返回了我的 XML 文件的好子树,但查询的 .Where(x => x.Attribute("ID") != null) 部分没有返回任何内容(所以 .Select(..) 没有不会在任何事情上被执行)。我试图通过这个Where(..) 子句得到的是所有实际上在其中声明了ID 属性的节点。
我在这个查询中做错了什么?
编辑:
我尝试从对_xmlFile.Descendants() 的调用中删除itemType.ToString(),它现在可以工作了,尽管我得到了所有具有ID 属性的项目,而不是那些仅在正确的itemType 节点下的项目(矿石、冰等)。
为什么会这样呢?在调试中,我确实看到 _xmlFile.Descendants(itemType.ToString()) 调用返回了正确的 XML 结构。
【问题讨论】:
标签: c# linq parsing xml-parsing linq-to-xml