Conditional Linq to XML select (nested select statements)
I'm trying to view all my friends from facebook who went to some school. I use FQL to get an xml file that contains all my friends with their education info. But i can't use FQL to select only those who went to the same school. Therefor, I'm trying to use Linq to XML to select only the users i want. I've tried some methods but those won't work for me.
Here is my linq query:
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)
;
EDIT: sample xml can be found here:sample XML
There's one more problem. The school name is not an direct attribute from the fbUser object. Also in the xml file the schoolname can only be found here
<user><education_history><education_info><name>
So here is my where statement:
where usr.Element("education_history").Element("education_info").Element(name").value == "schoolname"
Problem is that there is not always an education_history or education_info node in the xml.
So i also need a way to work around this..
Any help on this problem is very appreciated.
I hope you can help me!
Grtz
You're referring to a where
statement on users, which is not present in your sample. The top query (select new fbUser
) performs a select on all users. If you want to filter your user list, you need to insert a where
statement between the from
and select
, like this:
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
{
//...
}
Also, a common misconception made when stranslating data queries into LinQ is that the resulting LinQ query should be a single statement, which it doesn't have to be. In your case, the query isn't executed until you use the Take(5)
statement. So if you have trouble constructing your where
statement, you can postpone it until after you've created the select
part:
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);
精彩评论