Условный выбор Linq to XML (вложенные операторы выбора)

Пытаюсь просмотреть всех своих друзей из фейсбука, которые ходили в какую-то школу. Я использую FQL, чтобы получить XML-файл, содержащий всех моих друзей с информацией об их образовании. Но я не могу использовать FQL, чтобы выбрать только тех, кто ходил в ту же школу. Поэтому я пытаюсь использовать Linq to XML для выбора только тех пользователей, которых я хочу. Я пробовал некоторые методы, но они не будут работать для меня.

Вот мой запрос linq:

XDocument doc = RemoveNamespace (XDocument.Load(url));

        string[] search = {"Katho", "katho", "kortrijk" , "vhti"};
       List<string> keys = new List<string>( search );



        var user = (from usr in doc.Descendants("user")

                                   select new fbUser
                                   {

                                       name = usr.Element("name").Value,

                                       email = usr.Element("email").Value,
                                       current_location = StringExtensions.checkNull(usr.Element("current_location").Value,""),
                                       hometown_location = usr.Element("hometown_location").Value,
                                       pic = StringExtensions.checkNull(usr.Element("pic_square").Value,"http://www.fox16.com/media/avatar/default.jpg"),
                                       education_history = (from edu in usr.Descendants("education_info")
                                                           //where usr.Element("education_history").HasElements
                                                           where keys.Contains(edu.Element("name").Value)
                                                           select new Education
                                                           {

                                                               name = StringExtensions.checkNull(edu.Element("name"),""),
                                                               year = StringExtensions.checkNull(edu.Element("year"),""),
                                                               school_type = StringExtensions.checkNull(edu.Element("school_type"),""),
                                                               concentrations = from conc in edu.Descendants("concentrations")
                                                                                where (edu.Element("concentrations").HasElements)
                                                                                select new Concentration
                                                                                {
                                                                                    name = StringExtensions.checkNull(conc.Element("concentration").Value, "")
                                                                                }
                                                           })

                                   }).Take(5)
                                   ;

РЕДАКТИРОВАТЬ: образец XML можно найти здесь: пример XML

Есть еще одна проблема. Название школы не является прямым атрибутом объекта fbUser. Также в файле xml название школы можно найти только здесь

<user><education_history><education_info><name>

Итак, вот мой оператор where:

where usr.Element("education_history").Element("education_info").Element(name").value == "schoolname"

Проблема в том, что в xml не всегда есть узел education_history или education_info.

Поэтому мне также нужен способ обойти это.

Любая помощь по этой проблеме очень ценится.

Я надеюсь, что вы можете помочь мне!

Грц


person ThdK    schedule 29.03.2011    source источник


Ответы (1)


Вы имеете в виду оператор where для пользователей, которого нет в вашем образце. Верхний запрос (select new fbUser) выполняет выбор всех пользователей. Если вы хотите отфильтровать свой список пользователей, вам нужно вставить оператор where между from и select, например:

    var user = (from usr in doc.Descendants("user")
            where usr.Element("education_history") != null
                && usr.Element("education_info").Element(name") != null
                && usr.Element("education_info").Element(name").value == "schoolname"

            select new fbUser
            {
                //...
            }

Кроме того, распространенное заблуждение, возникающее при переводе запросов данных в LinQ, состоит в том, что результирующий запрос LinQ должен быть одним оператором, что не обязательно должно быть. В вашем случае запрос не выполняется, пока вы не используете оператор Take(5). Поэтому, если у вас возникли проблемы с построением оператора where, вы можете отложить его до тех пор, пока не создадите часть select:

var query = (from usr in doc.Descendants("user")
             select new fbUser
                   //...

var user = query.where(u => 
    u.Element("education_history") != null
        && u.Element("education_info").Element(name") != null
        && u.Element("education_info").Element(name").value == "schoolname"
).Take(5);
person Prutswonder    schedule 29.03.2011
comment
Спасибо за быстрый ответ! Я не нашел его полностью, но я думаю, что сейчас очень близко. - person ThdK; 29.03.2011
comment
я отредактировал свой вопрос. Не могли бы вы взглянуть еще раз? Ваша помощь очень ценится! - person ThdK; 29.03.2011
comment
Обновлены операторы where в моих примерах кода на основе вашего редактирования. - person Prutswonder; 29.03.2011
comment
Большое спасибо! Ваш ответ нуждался лишь в небольшом исправлении. - person ThdK; 29.03.2011
comment
Какая была коррекция? Если вы разместите это в комментарии, я обновлю ответ для вас. - person Prutswonder; 29.03.2011
comment
где usr.Element(education_history).HasElements && usr.Element(education_history).Element(education_info).Element(name) != null && usr.Element(education_history).Element(education_info).Element(name).Value == SCHOOLNAME выберите нового пользователя fbUser - person ThdK; 29.03.2011