Linq to XML, выберите все атрибуты и их значения для данного узла - PullRequest
2 голосов
/ 26 июля 2010

У меня есть файл сопоставления 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 для 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

Ответы [ 4 ]

6 голосов
/ 26 июля 2010

Обновление

Суммировано по методу:

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;
        }
    }
}
1 голос
/ 26 июля 2010

Просто потому, что мне нравится вызов, вот в одном запросе:

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);
}
1 голос
/ 26 июля 2010

так как у меня мало времени, я буду использовать двухэтапный процесс

Но было бы интересно узнать, возможно ли это в одном запросе

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 голосов
/ 19 сентября 2014

Я знаю, что это древнее сейчас, но я думаю, что способ решить эту проблему, не выполняя больше обработки, чем необходимо, выглядит примерно так:

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...