获取带有属性的最远xml子节点的LINQ请求

本文关键字:xml 子节点 LINQ 请求 属性 获取 | 更新日期: 2023-09-27 17:53:24

我有一个定义项目/位置类别的xml文件,它们的id如下:

<?xml version="1.0" encoding="UTF-8"?>
<Eve_App>
    <Item_Types>
        <Ore>
            <Arkonor>
                <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>
            <Bistot>
                <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>
            <Crokite>
                <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>
            ...
        </Ore>
        <Ice>
            <Blue_Ice ID="16264"/>
            <CLear_Icicle ID="16262"/>
            <Compressed_Blue_Ice ID="28433"/>
            ...
        </Ice>
        <Gas>
            <Booster_Gas_Clouds>
                <Amber_Cytoserocin ID="25268"/>
                <Amber_Mykoserocin ID="28694"/>
                <Azure_Cytoserocin ID="25279"/>
                <Azure_Mykoserocin ID="28695"/>
                <Celadon_Cytoserocin ID="25275"/>
                <Celadon_Mykoserocin ID="28696"/>
                ...
            </Booster_Gas_Clouds>
            <Fullerenes>
                <Fullerite_C28 ID="30375"/>
                <Fullerite_C32 ID="30376"/>
                ...
            </Fullerenes>
        </Gas>
        <Mineral>
            <Isogen ID="37"/>
            <Megacyte ID="40"/>
            <Mexallon ID="36"/>
            <Morphite ID=""/>
            <Nocxium ID="38"/>
            <Pyerite ID="35"/>
            <Tritanium ID="34"/>
            <Zydrine ID="39"/>
        </Mineral>
...

可以看到,包含ID的项不一定在同一层上。我想知道是否有一个LINQ请求可以让我获得与ID相关联的节点的名称,我想要独立于Item_Types节点中该项目的级别。

编辑:

下面的请求会在所有嵌套的子节点中迭代吗?

IEnumerable<string> ids =
       from el in xelement.Elements("Item_Types")
       where (int)el.Attribute("ID") == "22" // For example
       select (string)el.value;

EDIT2:

目前我有这个:

IEnumerable<String> names = _xmlFile.Descendants()
    .Where(x => x.Attributes().Any(a => a.Name.LocalName == "ID") && uint.Parse(x.Attributes().First(a => a.Name.LocalName == "ID").Value) == id)
    .Select(t => t.Name.LocalName);
if (names.Count() != 0) // Error here
{
    return names.ElementAt(0);
}
else
{
    return "";
}

不幸的是,我在调用Count()函数时得到以下错误:

Input string was not in a correct format.

当我查看names变量的值时,我可以在调试中看到这个错误。这不会发生,虽然当我只是return names.ElementAt(0);而不使用Count()(我能够正确地看到与ID相关的名称),但是如果ID不存在,当我尝试return names.ElementAt(0);时,我会得到另一个错误(因此为什么我这样做检查)。

为什么我得到提到的Parse()错误?

获取带有属性的最远xml子节点的LINQ请求

试试这个:

    IEnumerable<string> ids = xelement.Descendants()
.Where(x => x.Attributes().Any(a => a.Name.LocalName == "ID") && x.Attributes().First(a => a.Name.LocalName == "ID").Value == "28390")
.Select(t => t.Name.LocalName);

首先检查后代节点是否存在ID属性,如果存在,则检查所需ID的值

在问题中没有很清楚地说明(我认为预期输出的一个示例会澄清这一点),但是假设您想要获得ID属性等于某个值的元素名称,并且目标元素可以在XML文档中的任何层次深度,您可以使用Descendants()方法,如下所示:

IEnumerable<string> names =
       from el in xelement.Descendants()
       where (int)el.Attribute("ID") == "22"
       select (string)el.Name.LocalName;

(int)el.Attribute("ID")简单返回0 -而不是抛出异常-如果当前el中没有ID属性,那么您可以跳过检查ID属性的存在