简体   繁体   中英

How to filter a Linq Query from XML to IEnumerable of Objects

=I am writing a .NET page in C# to retrieve a feed from a WordPress blog and display it on the page. It works fine, until I try to filter the posts.

I declare an XDocument and load the feed from the URL. Then read the posts, based on the Post class, into a IEnumarable, as I say this all works. The problem is I, for some reason, don't understand how to filter by elements.

In the Query any attempt to filter gives an error. I've tried every iteration of syntax I can think of but they all give errors. Can anyone explain, so I can slap my head perhaps, how I can filter on the Category element? Because I can't get it to recognize anything like post.Category etc. All I get is an error that post.Category does not have a definition.

If I remove the where clause it works fine? What am I doing wrong? The where syntax I am using matches MSDN examples exactly? Edit to add: It's not the single equal sign. I have changed that but it was just a typo when copying to the web.

The error is always in the form of "post.Category" (or other element name) not being defined. I am missing something in how you address the elements in the where clause, but I can't figure out what it is and my code matches several MS examples exactly.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml.Linq;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

    // Load the blog posts and print the title of the blog
    string sURL2 = "http://myurl.com/?feed=rss2";
    XDocument ourBlog = XDocument.Load(sURL2);


    // Query the <item>s in the XML RSS data and select each one into a new Post()
    IEnumerable<Post> posts =
        from post in ourBlog.Descendants("item")
        where post.Category == "x"
        select new Post(post);
    postRepeater.DataSource = posts;
    postRepeater.DataBind();

  //  GridView1.DataSource = posts;
  //  GridView1.DataBind();


}
class Post
{
    public string Title { get; private set; }
    public DateTime? Date { get; private set; }
    public string Url { get; private set; }
    public string Description { get; private set; }
    public string Category { get; private set; }
    public string Creator { get; private set; }
    public string Content { get; private set; }

    private static string GetElementValue(XContainer element, string name)
    {
        if ((element == null) || (element.Element(name) == null))
            return String.Empty;
        return element.Element(name).Value;
    }

    public Post(XContainer post)
    {
        // Get the string properties from the post's element values
        Title = GetElementValue(post, "title");
        Url = GetElementValue(post, "guid");
        Description = GetElementValue(post, "description");
        Category = GetElementValue(post, "category");
        Creator = GetElementValue(post,
            "{http://purl.org/dc/elements/1.1/}creator");
      //  Content = GetElementValue(post,
       //    "{http://purl.org/dc/elements/1.0/modules/content/}encoded");
       // Content = GetElementValue(post, "content");
        Content = GetElementValue(post,
           "{http://purl.org/rss/1.0/modules/content/}encoded");
        // The Date property is a nullable DateTime? -- if the pubDate element
        // can't be parsed into a valid date, the Date property is set to null
        DateTime result;
        if (DateTime.TryParse(GetElementValue(post, "pubDate"), out result))
            Date = (DateTime?)result;
    }

    public override string ToString()
    {
        return String.Format("{0} by {1}", Title ?? "no title", Creator ?? "Unknown");
    }
}

}     

Your problem is, that the ourBlog.Descendants does not contain Posts but an IEnumerable<XElement>

You could try the following:

var posts = from post in ourBlog.Descendants("item")
            select new Post(post);
var filteredPosts = from post in posts
                    where post.Category == "x"
                    select post;

or

var posts = from post in ourBlog.Descendants("item")
            where Post.GetElementValue(post, "category") == "x"
            select new Post(post);

Hope it helps ...

I edited the second statement, so that it should work now, if you change the visibility of GetElementValue to public.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM