Linq to XML, select all attributes and their values for a given node

前端 未结 4 1260
时光说笑
时光说笑 2021-01-22 13:06

I have an xml mapping file that looks something like this


    
        

        
相关标签:
4条回答
  • 2021-01-22 13:37

    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();
    
    0 讨论(0)
  • 2021-01-22 13:48

    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);
    }
    
    0 讨论(0)
  • 2021-01-22 13:51

    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;
    
    0 讨论(0)
  • 2021-01-22 14:02

    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;
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题