Linq Вопрос: комбинированные предложения - PullRequest
3 голосов
/ 17 апреля 2009

Grettings!

У меня есть какой-то XML, который выглядит следующим образом:

<Root>
    <SectionA>
        <Item id="111">
            <Options>
                <Option val="a" cat="zzz">
                    <Package value="apple" />
                    <Feature value="avacado" />
                </Option>
                <Option val="b" cat="yyy">
                    <Package value="banana" />
                    <Feature value="blueberry" />
                </Option>
            </Options>
        </Item>
        <Item id="222">
            <Options>
                <Option val="c" cat="xxx">
                    <Package value="carrot" />
                    <Feature value="cucumber" />
                </Option>
                <Option val="d" cat="www">
                    <Package value="dairy" />
                    <Feature value="durom" />
                </Option>
            </Options>
        </Item>
    </SectionA>
    <SectionB>
    .
    .
    .
    </SectionB>
</Root>

Я хотел бы получить значения PACKAGE и FEATURE на основе атрибута ID элемента, равного 111, и атрибута VAL в OPTION, равного a.

Я не уверен, с чего начать. Я могу выбрать узел ITEM, используя where, но я не уверен, как объединить это с предложением where на узле OPTION. Есть идеи?

Ответы [ 4 ]

7 голосов
/ 17 апреля 2009

Это работает для меня.

var doc = XDocument.Parse(s);

var items = from item in doc.Descendants("Item")
            where item.Attribute("id").Value == "111"
            from option in item.Descendants("Option")
            where option.Attribute("val").Value == "a"
            let package = option.Element("Package").Attribute("value")
            let feature = option.Element("Feature").Attribute("value")
            select new { Package = package.Value, Feature = feature.Value };

items.First().Feature; // = "avacado"
items.First().Package; // = "apple"

Вы можете опустить let детали, если хотите, они только уменьшают анонимный тип.

var items = from item in doc.Descendants("Item")
            where item.Attribute("id").Value == "111"
            from option in item.Descendants("Option")
            where option.Attribute("val").Value == "a"
            select new
            {
               Package = option.Element("Package").Attribute("value").Value,
               Feature = option.Element("Feature").Attribute("value").Value
            };

На самом деле мне больше нравится второй.


И стиль Linq без запроса.

var items = doc.Descendants("Item")
               .Where(item => item.Attribute("id").Value == "111")
               .SelectMany(item => item.Descendants("Option"))
               .Where(option => option.Attribute("val").Value == "a")
               .Select(option => new
               {
                Package = option.Element("Package").Attribute("value").Value,
                Feature = option.Element("Feature").Attribute("value").Value
               });
4 голосов
/ 17 апреля 2009

альтернативная реализация с использованием SelectMany

var doc = XDocument.Parse(xml);
var items = from i in doc.Descendants("Item")
            from o in i.Descendants("Option")
            where i.Attribute("id").Value == "111"
               && o.Attribute("val").Value == "a"
         select new {
             Package = i.Descendants("Package").Attribute("value").Value,
             Feature = i.Descendants("Feature").Attribute("value").Value                     
         };
0 голосов
/ 17 апреля 2009

А вот версия VB (VB действительно качается ++ в XML-материале):

Module Module1

    Sub Main()
        Dim xml As XElement = <Root>
                                  <SectionA>
                                      <Item id="111">
                                          <Options>
                                              <Option val="a" cat="zzz">
                                                  <Package value="apple"/>
                                                  <Feature value="avacado"/>
                                              </Option>
                                              <Option val="b" cat="yyy">
                                                  <Package value="banana"/>
                                                  <Feature value="blueberry"/>
                                              </Option>
                                          </Options>
                                      </Item>
                                      <Item id="222">
                                          <Options>
                                              <Option val="c" cat="xxx">
                                                  <Package value="carrot"/>
                                                  <Feature value="cucumber"/>
                                              </Option>
                                              <Option val="d" cat="www">
                                                  <Package value="dairy"/>
                                                  <Feature value="durom"/>
                                              </Option>
                                          </Options>
                                      </Item>
                                  </SectionA>
                                  <SectionB>                                      
                                  </SectionB>
                              </Root>

        Dim data = From x In xml...<Option> _
                   Where x.Ancestors("Item").@id = "111" AndAlso x.@val = "a" _
                   Select Package = x.<Package>.@value, _
                          Feature = x.<Feature>.@value

        For Each item In data
            Console.WriteLine("Package: {0}, Feature: {1}", item.Package, item.Feature)
        Next
        Stop
    End Sub

End Module
0 голосов
/ 17 апреля 2009

Вот подход снизу вверх:

var items = xdoc
            .Descendants("Option")
            .Where(o => (string)o.Attribute("val") == "a" && (int)o.Ancestors("Item").Single().Attribute("id") == 111)
            .Select(o => new { 
              Package = o.Element("Package"), 
              Feature= o.Element("Feature") 
            });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...