Linq to XML,选择给定节点的所有属性及其值

发布于 2024-09-11 13:29:55 字数 2409 浏览 4 评论 0原文

我有一个 xml 映射文件,看起来像这样,

<colourMappings>
    <model name="modelX">
        <mapping colour="White" configCode="1"></mapping>
        <mapping colour="Aluminium" configCode="2"></mapping>
        <mapping colour="Black" configCode="3"></mapping>
        <mapping colour="Blue" configCode="4"></mapping>
        <mapping colour="White Pearl" configCode="5"></mapping>
        <mapping colour="Graphite" configCode="6"></mapping>
        <mapping colour="Gunmetal" configCode="7"></mapping>
        <mapping colour="Indigo" configCode="8"></mapping>
        <mapping colour="Red" configCode="9"></mapping>
    </model>
    <model name="modelY">
        <mapping colour="White" configCode="1" stConfigCode= "xx" dgConfigCode="hj"></mapping>
        <mapping colour="Aluminium" configCode="2" stConfigCode= "xy" dgConfigCode="gh"></mapping>
        <mapping colour="Black" configCode="3" stConfigCode= "xt" dgConfigCode="fg"></mapping>
        <mapping colour="Blue" configCode="4" stConfigCode= "sd" dgConfigCode="fg"></mapping>
        <mapping colour="White Pearl" configCode="5" stConfigCode= "df" dgConfigCode="df"></mapping>
        <mapping colour="Graphite" configCode="6" stConfigCode= "xc" dgConfigCode="df"></mapping>
        <mapping colour="Gunmetal" configCode="7"  stConfigCode= "cv" dgConfigCode="cv"></mapping>
        <mapping colour="Indigo" configCode="8"  stConfigCode= "zx" dgConfigCode="vb"></mapping>
        <mapping colour="Red" configCode="9"  stConfigCode= "fg" dgConfigCode="cv"></mapping>
    </model>
</colourMappings>

我希望能够在给定模型名称和颜色的情况下提取所有属性及其值,

例如

给定 ModelY 和 White,我想得到 configCode="1" stConfigCode= "xx" dgConfigCode="hj" 这可以是任何结构 - 数组、列表,无论

我一直在使用 Linq to XML 但无法获得正确的语法,

XDocument mappings = XDocument.Load(@"D:\colour_mappings.xml");
var q = from c in mappings.Descendants("model")
                    where (string)c.Attribute("name") == "modelY" && (string)c.Descendants("mapping").Attributes("colour").FirstOrDefault() == "White"
                    select c.Attributes();

有人知道如何做到这一点吗?

乐意使用任何方法,不一定非得是 Linq

I have an xml mapping file that looks something like this

<colourMappings>
    <model name="modelX">
        <mapping colour="White" configCode="1"></mapping>
        <mapping colour="Aluminium" configCode="2"></mapping>
        <mapping colour="Black" configCode="3"></mapping>
        <mapping colour="Blue" configCode="4"></mapping>
        <mapping colour="White Pearl" configCode="5"></mapping>
        <mapping colour="Graphite" configCode="6"></mapping>
        <mapping colour="Gunmetal" configCode="7"></mapping>
        <mapping colour="Indigo" configCode="8"></mapping>
        <mapping colour="Red" configCode="9"></mapping>
    </model>
    <model name="modelY">
        <mapping colour="White" configCode="1" stConfigCode= "xx" dgConfigCode="hj"></mapping>
        <mapping colour="Aluminium" configCode="2" stConfigCode= "xy" dgConfigCode="gh"></mapping>
        <mapping colour="Black" configCode="3" stConfigCode= "xt" dgConfigCode="fg"></mapping>
        <mapping colour="Blue" configCode="4" stConfigCode= "sd" dgConfigCode="fg"></mapping>
        <mapping colour="White Pearl" configCode="5" stConfigCode= "df" dgConfigCode="df"></mapping>
        <mapping colour="Graphite" configCode="6" stConfigCode= "xc" dgConfigCode="df"></mapping>
        <mapping colour="Gunmetal" configCode="7"  stConfigCode= "cv" dgConfigCode="cv"></mapping>
        <mapping colour="Indigo" configCode="8"  stConfigCode= "zx" dgConfigCode="vb"></mapping>
        <mapping colour="Red" configCode="9"  stConfigCode= "fg" dgConfigCode="cv"></mapping>
    </model>
</colourMappings>

I want to be able to pull out all the attributes and their values given a model name and colour

e.g.

given ModelY and White, I'd like to get configCode="1" stConfigCode= "xx" dgConfigCode="hj"
This could be in any structure - array, list, whatever

I have been using Linq to XML but can't get the correct syntax

XDocument mappings = XDocument.Load(@"D:\colour_mappings.xml");
var q = from c in mappings.Descendants("model")
                    where (string)c.Attribute("name") == "modelY" && (string)c.Descendants("mapping").Attributes("colour").FirstOrDefault() == "White"
                    select c.Attributes();

anyone know how to do this?

Happy to use any method, doesn't necessarily need to be Linq

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

能否归途做我良人 2024-09-18 13:29:55

更新

总结为一个方法:

public IEnumerable<XAttribute> GetAttributes(string modelName, string colour)
{
    XDocument mappings = XDocument.Load(@"D:\colour_mappings.xml");

    var q1 =
        from elm in mappings.Descendants("model")
        where (string)elm.Attribute("name") == "modelY"
        select elm;

    var q2 =
        from elm in q1.Descendants("mapping")
        where (string)elm.Attribute("colour") == "White"
        select elm.Attributes().Where(a => a.Name != "colour");


    foreach (IEnumerable<XAttribute> attributeList in q2)
    {
        foreach (XAttribute attribute in attributeList)
        {
            yield return attribute;
        }
    }
}

Update

Summarized in a method:

public IEnumerable<XAttribute> GetAttributes(string modelName, string colour)
{
    XDocument mappings = XDocument.Load(@"D:\colour_mappings.xml");

    var q1 =
        from elm in mappings.Descendants("model")
        where (string)elm.Attribute("name") == "modelY"
        select elm;

    var q2 =
        from elm in q1.Descendants("mapping")
        where (string)elm.Attribute("colour") == "White"
        select elm.Attributes().Where(a => a.Name != "colour");


    foreach (IEnumerable<XAttribute> attributeList in q2)
    {
        foreach (XAttribute attribute in attributeList)
        {
            yield return attribute;
        }
    }
}
复古式 2024-09-18 13:29:55

由于时间紧迫,我将使用两阶段流程,

但有兴趣了解这是否可以在一个查询中实现

var matchingModelXml = from c in mappings.Descendants("model")
                               where (string)c.Attribute("name") == "modelY"
                               select c;

var mappingAttributes = from b in matchingModelXml.Descendants("mapping")
                        where (string)b.Attribute("colour") == "White"
                        select b.Attributes();

as I am pushed for time I will use a 2 stage process

But would be interested to hear if this is possible in one query

var matchingModelXml = from c in mappings.Descendants("model")
                               where (string)c.Attribute("name") == "modelY"
                               select c;

var mappingAttributes = from b in matchingModelXml.Descendants("mapping")
                        where (string)b.Attribute("colour") == "White"
                        select b.Attributes();
北渚 2024-09-18 13:29:55

只是因为我喜欢挑战,所以它在一个查询中:

XDocument test = XDocument.Parse("<colourMappings>    <model name=\"modelX\">        <mapping colour=\"White\" configCode=\"1\"></mapping>        <mapping colour=\"Aluminium\" configCode=\"2\"></mapping>        <mapping colour=\"Black\" configCode=\"3\"></mapping>        <mapping colour=\"Blue\" configCode=\"4\"></mapping>        <mapping colour=\"White Pearl\" configCode=\"5\"></mapping>        <mapping colour=\"Graphite\" configCode=\"6\"></mapping>        <mapping colour=\"Gunmetal\" configCode=\"7\"></mapping>        <mapping colour=\"Indigo\" configCode=\"8\"></mapping>        <mapping colour=\"Red\" configCode=\"9\"></mapping>    </model>    <model name=\"modelY\">        <mapping colour=\"White\" configCode=\"1\" stConfigCode= \"xx\" dgConfigCode=\"hj\"></mapping>        <mapping colour=\"Aluminium\" configCode=\"2\" stConfigCode= \"xy\" dgConfigCode=\"gh\"></mapping>        <mapping colour=\"Black\" configCode=\"3\" stConfigCode= \"xt\" dgConfigCode=\"fg\"></mapping>        <mapping colour=\"Blue\" configCode=\"4\" stConfigCode= \"sd\" dgConfigCode=\"fg\"></mapping>        <mapping colour=\"White Pearl\" configCode=\"5\" stConfigCode= \"df\" dgConfigCode=\"df\"></mapping>        <mapping colour=\"Graphite\" configCode=\"6\" stConfigCode= \"xc\" dgConfigCode=\"df\"></mapping>        <mapping colour=\"Gunmetal\" configCode=\"7\"  stConfigCode= \"cv\" dgConfigCode=\"cv\"></mapping>        <mapping colour=\"Indigo\" configCode=\"8\"  stConfigCode= \"zx\" dgConfigCode=\"vb\"></mapping>        <mapping colour=\"Red\" configCode=\"9\"  stConfigCode= \"fg\" dgConfigCode=\"cv\"></mapping>    </model></colourMappings>");

var maps = from model in test.Root.Elements("model")
           from attr in model.Attributes("name")
           from mapping in model.Elements("mapping")
           where attr.Value == "modelY" && mapping.Attribute("colour").Value == "White"
           select new
           {
                 configCode = mapping.Attribute("configCode").Value
               , stConfigCode = mapping.Attribute("stConfigCode").Value
               , dgConfigCode = mapping.Attribute("dgConfigCode").Value
           };

foreach (var map in maps)
{
    Console.Write("configCode: ");
    Console.WriteLine(map.configCode);
    Console.Write("stConfigCode: ");
    Console.WriteLine(map.stConfigCode);
    Console.Write("dgConfigCode: ");
    Console.WriteLine(map.dgConfigCode);
}

Just because I like a challenge, here it is in one query:

XDocument test = XDocument.Parse("<colourMappings>    <model name=\"modelX\">        <mapping colour=\"White\" configCode=\"1\"></mapping>        <mapping colour=\"Aluminium\" configCode=\"2\"></mapping>        <mapping colour=\"Black\" configCode=\"3\"></mapping>        <mapping colour=\"Blue\" configCode=\"4\"></mapping>        <mapping colour=\"White Pearl\" configCode=\"5\"></mapping>        <mapping colour=\"Graphite\" configCode=\"6\"></mapping>        <mapping colour=\"Gunmetal\" configCode=\"7\"></mapping>        <mapping colour=\"Indigo\" configCode=\"8\"></mapping>        <mapping colour=\"Red\" configCode=\"9\"></mapping>    </model>    <model name=\"modelY\">        <mapping colour=\"White\" configCode=\"1\" stConfigCode= \"xx\" dgConfigCode=\"hj\"></mapping>        <mapping colour=\"Aluminium\" configCode=\"2\" stConfigCode= \"xy\" dgConfigCode=\"gh\"></mapping>        <mapping colour=\"Black\" configCode=\"3\" stConfigCode= \"xt\" dgConfigCode=\"fg\"></mapping>        <mapping colour=\"Blue\" configCode=\"4\" stConfigCode= \"sd\" dgConfigCode=\"fg\"></mapping>        <mapping colour=\"White Pearl\" configCode=\"5\" stConfigCode= \"df\" dgConfigCode=\"df\"></mapping>        <mapping colour=\"Graphite\" configCode=\"6\" stConfigCode= \"xc\" dgConfigCode=\"df\"></mapping>        <mapping colour=\"Gunmetal\" configCode=\"7\"  stConfigCode= \"cv\" dgConfigCode=\"cv\"></mapping>        <mapping colour=\"Indigo\" configCode=\"8\"  stConfigCode= \"zx\" dgConfigCode=\"vb\"></mapping>        <mapping colour=\"Red\" configCode=\"9\"  stConfigCode= \"fg\" dgConfigCode=\"cv\"></mapping>    </model></colourMappings>");

var maps = from model in test.Root.Elements("model")
           from attr in model.Attributes("name")
           from mapping in model.Elements("mapping")
           where attr.Value == "modelY" && mapping.Attribute("colour").Value == "White"
           select new
           {
                 configCode = mapping.Attribute("configCode").Value
               , stConfigCode = mapping.Attribute("stConfigCode").Value
               , dgConfigCode = mapping.Attribute("dgConfigCode").Value
           };

foreach (var map in maps)
{
    Console.Write("configCode: ");
    Console.WriteLine(map.configCode);
    Console.Write("stConfigCode: ");
    Console.WriteLine(map.stConfigCode);
    Console.Write("dgConfigCode: ");
    Console.WriteLine(map.dgConfigCode);
}
零崎曲识 2024-09-18 13:29:55

我知道这现在已经很古老了,但我认为在不进行不必要的处理的情况下解决这个问题的方法看起来像这样:

mappings.Root.Elements()
        .Where(cm => cm.Attribute("name").Value == "modelY")
        .SelectMany(cm => cm.Elements()
                            .Where(m => m.Attribute("colour").Value == "White")
                            .SelectMany(m => m.Attributes()));

在查询格式中,它将是:

from cm in doc.Root.Elements()
where cm.Attribute("name").Value == "modelY"
from m in cm.Elements()
where m.Attribute("colour").Value == "White"
from att in m.Attributes()
select att;

I know this is ancient now, but I think the way to solve this problem without doing more processing than neccessary looks something like this:

mappings.Root.Elements()
        .Where(cm => cm.Attribute("name").Value == "modelY")
        .SelectMany(cm => cm.Elements()
                            .Where(m => m.Attribute("colour").Value == "White")
                            .SelectMany(m => m.Attributes()));

In query format, it would be:

from cm in doc.Root.Elements()
where cm.Attribute("name").Value == "modelY"
from m in cm.Elements()
where m.Attribute("colour").Value == "White"
from att in m.Attributes()
select att;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文