解析RSS 1.0与C#/ MVC 2

问题描述:

首先,我不相信任何人在2011年仍然使用RSS 1.0,猜你真的学到了新的东西。那么我试图解析他们的饲料,并把我的客户网站上的内容(我有权限,所以没有违法在这里)。正如你可以想象的,我的第一次尝试失败了(正在写代码2.0),所以我回到了绘图板,这就是我想出的。解析RSS 1.0与C#/ MVC 2

RssController

public virtual ActionResult Index() 
{ 
    List<RssFeedItem> rssList = new List<RssFeedItem>(); 
    XmlDocument doc = new XmlDocument(); 
    XmlNamespaceManager manager = new XmlNamespaceManager(doc.NameTable); 
    manager.AddNamespace("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); 
    manager.AddNamespace("rss", "http://purl.org/rss/1.0/"); 

    XmlTextReader reader = new XmlTextReader("http://wdfw.wa.gov/news/newsrss.php"); 

    doc.Load(reader); 

    XmlNodeList nodes = doc.SelectNodes("/rdf:RDF//rss:item",manager); 

     foreach(XmlNode node in nodes) 
     { 
      XmlNodeList aboutNode = node.SelectNodes("rss:about", manager); 
      XmlNodeList titleNode = node.SelectNodes("rss:title", manager); 
      XmlNodeList linkNode = node.SelectNodes("rss:link", manager); 

      var item = new RssFeedItem 
      { 
       Link = linkNode.Count == 0 ? "" : linkNode[0].InnerText, 
       Title = titleNode.Count == 0 ? "" : titleNode[0].InnerText, 
       About = aboutNode.Count == 0 ? "" : aboutNode[0].InnerText 


      }; 
      rssList.Add(item); 
     } 
     return View(rssList); 
} 

我试图做到这一点利用局部视图(ASCS)和看起来像这样

的Index.aspx

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<GodsCreationTaxidermy.Models.RssFeedItem>" %> 

<% 
    foreach (RssFeedItem item in (IEnumerable<RssFeedItem>)ViewData.Model) 
    { 
     Response.Write(string.Format("<div id={0}><a href={1} target=\"_blank\" /> <strong>{2}</strong></div>", 
      Model.About.Truncate(5), Model.Link, Model.Title.Truncate(25))); 
    } %> 

然后我在mySite.Master中尝试RenderPartial

<% Html.RenderPartial("Index");%> 

问题是,该网站从未加载,甚至给出某种错误,它只是与FF的litte加载图标旋转坐在一起。

编辑

嗯,我已经取得了从早期到我的代码一些重大的变化,同样的结果,没有错误,它不甚至加载网站(只是坐在&旋转)。下面是来自控制器

[MoveFormsScript] 
[CanonicalUrlAttribute("Rss")] 
public virtual ActionResult Index() 
{ 
    return View(new RssList()); 
} 

代码现在从RssList

[UIHint("Feeds")] 
public SelectList Feeds { get; private set; } 

[Required(ErrorMessage = "Rss Feeduired")] 
public string Feed { get; set; } 

public RssList() 
{ 
    this.Feeds = GetRssFeed(null); 
} 

public SelectList GetRssFeed(string selectedValue) 
{ 
    List<RssFeedItem> rssList = new List<RssFeedItem>(); 
    XmlDocument doc = new XmlDocument(); 
    XmlNamespaceManager manager = new XmlNamespaceManager(doc.NameTable); 
    manager.AddNamespace("rdf", "http://www.w3.org/1 999/02/22-rdf-syntax-ns#"); 
    manager.AddNamespace("rss", "http://purl.org/rss/1.0/"); 

    XmlTextReader reader = new XmlTextReader("http://wdfw.wa.gov/news/newsrss.php"); 

    doc.Load(reader); 

    XmlNodeList nodes = doc.SelectNodes("/rdf:RDF//rss:item", manager); 

    foreach (XmlNode node in nodes) 
    { 
     XmlNodeList aboutNode = node.SelectNodes("rss:about", manager); 
     XmlNodeList titleNode = node.SelectNodes("rss:title", manager); 
     XmlNodeList linkNode = node.SelectNodes("rss:link", manager); 

     var item = new RssFeedItem 
     { 
      Link = linkNode.Count == 0 ? "" : linkNode[0].InnerText, 
      Title = titleNode.Count == 0 ? "" : titleNode[0].InnerText, 
      About = aboutNode.Count == 0 ? "" : aboutNode[0].InnerText 


     }; 
     rssList.Add(item); 
    } 
    return new SelectList(rssList, "Link", "Title", selectedValue); 
} 

最后我的局部视图代码

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<GodsCreationTaxidermy.Helpers.BusinessDTO.RssList>" %> 

<% 
    foreach (var item in (IEnumerable<RssList>)ViewData.Model) 
    { 
     Response.Write(string.Format("<div id=\"{0}\"><a href=\"{1}\" target=\"_blank\" /> <strong>{2}</strong></div>", 
      item.Feed[0].ToString().Truncate(10), item.Feed[1], item.Feed[2].ToString().Truncate(100))); 

    } %> 

谁能帮助我?

更改的XmlNodeList的实例是RssList类:

XmlNodeList nodes = doc.SelectNodes("//rss:item[./rss:link]", manager); 

然后你ViewUserControl改成这样:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %><ul> 
<% 
    RssList viewModel = ViewData.Model as RssList; 

    if (viewModel.Feeds.Count() > 0) 
    { 
     foreach (SelectListItem item in viewModel.Feeds) 
     { %> 
<li> 
    <% 
      Response.Write(String.Format("<a href='{0}' target='_blank'>{1}</a>", item.Value, item.Text)); 
     }%> 
</li> 
<% 
    } 
%></ul> 

似乎为我工作。

+0

谢谢,我正在寻找 – PsychoCoder 2011-04-20 20:57:31

一个mod是否可以将此源与此MVC2 - Consume RSS feed with RDF and namespace http://www.w3.org/1999/02/22-rdf-syntax-ns#'合并。我忘了我已经问过

我不是很熟悉System.Web.Mvc.SelectList类,更不用说命名空间,但我注意到你使用了一个字符串作为selectedValue参数。它应该是一个RssFeedItem对象吗?

通过一些PowerShell障碍来运行您的xml代码部分,这里是我得到的。

$doc = New-Object Xml.XmlDocument; 
$manager = New-Object Xml.XmlNamespaceManager $doc.NameTable; 
$manager.AddNamespace("rdf", "http://www.w3.org/1 999/02/22-rdf-syntax-ns#"); 
$manager.AddNamespace("rss", "http://purl.org/rss/1.0/"); 

$reader = New-Object Xml.XmlTextReader("http://wdfw.wa.gov/news/newsrss.php"); 

$doc.Load($reader); 

#doesn't work 
"Doesn't work" 
$doc.SelectNodes("//rss:item[./rss:link./rss:title./rss:about]", $manager) | measure | select count 
#this is an invalid xpath query, there are no operators between the nodes specified in the []. 
#Also, in the xml document we're looking at, there is no node named "about". "about" is an attibute to the "item" node. 

#works 
"Works" 
$doc.SelectNodes("//rss:item[./rss:link and ./rss:title]", $manager) | measure | select count 
#Even though we only have the "link" and "title" nodes in the [], everything is returned. 
#That's because we're telling SelectNodes to return the "item" nodes themselves. 
+0

嘿snoj你怎么样了。不要字符串,因为列表中每个项目的值都是一个字符串 – PsychoCoder 2011-04-20 01:22:35

+0

一直不错,有一点在路上! – snoj 2011-04-20 01:37:30

+0

过得好,有一个人在路上!没有新的线?!?!任何人,但你有rssList作为“名单”?无论如何,我已经通过一些PowerShell运行你的XML代码,我发现你的第一个xpath不会返回任何东西。我稍微修改了一下,你可以试试吗? “//rss:item[./rss:link and ./rss:title]” – snoj 2011-04-20 01:59:41

对那些试图帮助我的人做了一些更改。这里的控制器代码

[MoveFormsScript] 
     [CanonicalUrlAttribute("Rss")] 
     public virtual ActionResult Index() 
     { 
      var viewModel = new RssList(); 
      return PartialView("Index", viewModel); 
     }  

然后,我创建了一个类(RssList),这其中的大部分工作是做

RssList

[UIHint("Feeds")] 
public SelectList Feeds { get; private set; } 

    [Required(ErrorMessage = "Rss Feed Required")] 
    public string Feed { get; set; } 

    public RssList() 
    { 
     this.Feeds = GetRssFeed(null); 
    } 



public SelectList GetRssFeed(string selectedValue) 
{ 
    List<RssFeedItem> rssList = new List<RssFeedItem>(); 
    XmlDocument doc = new XmlDocument(); 
    XmlNamespaceManager manager = new XmlNamespaceManager(doc.NameTable); 
    manager.AddNamespace("rdf", "http://www.w3.org/1 999/02/22-rdf-syntax-ns#"); 
    manager.AddNamespace("rss", "http://purl.org/rss/1.0/"); 

    XmlTextReader reader = new XmlTextReader("http://wdfw.wa.gov/news/newsrss.php"); 

    doc.Load(reader); 

    XmlNodeList nodes = doc.SelectNodes("/rdf:RDF//rss:item[./rss:link./rss:title./rss:about]", manager); 

    foreach (XmlNode node in nodes) 
    { 
     XmlNodeList aboutNode = node.SelectNodes("rss:about", manager); 
     XmlNodeList titleNode = node.SelectNodes("rss:title", manager); 
     XmlNodeList linkNode = node.SelectNodes("rss:link", manager); 

     var rssItem = new RssFeedItem 
     { 
      Link = linkNode.Count == 0 ? "" : linkNode[0].InnerText, 
      Title = titleNode.Count == 0 ? "" : titleNode[0].InnerText, 
      About = aboutNode.Count == 0 ? "" : aboutNode[0].InnerText 


     }; 
     rssList.Add(rssItem); 
    } 
    return new SelectList(rssList, "Link", "Title", selectedValue); 
} 

这是该指数。ASCX

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<GodsCreationTaxidermy.Helpers.BusinessDTO.RssList>" %> 

<%  
    foreach (RssList rssItem in ViewData.Model) 
    { 
     Response.Write(string.Format("<div id=\"{0}\"><a href=\"{1}\" target=\"_blank\" /> <strong>{2}</strong></div>", 
      rssItem.Feed[0].ToString().Truncate(10), rssItem.Feed[1], rssItem.Feed[2].ToString().Truncate(100))); 

    } %> 

和正常通话

<% Html.RenderPartial("Index");%> 

}

FeedItemCass 使用系统; using System.Collections.Generic;使用System.Linq的 ; using System.Web;

namespace GodsCreationTaxidermy.Models 
{ 
    public class RssFeedItem 
    { 
     public string Link { get; set; } 
     public string Title { get; set; } 
     public string About { get; set; } 
    } 
} 

我在这里看到几个问题。你的控件需要一个RssList,控制器正在返回一个选择列表,并且你的foreach正在枚举它认为是一个IEnumerable <RssList>。此外,你正在部分视图中做手动response.writes。如果你不这样做,标记会更清晰。

让我们先从RssList类开始。看起来你的第一种方法实际上就是你想要的,问题就是你在局部视图中所做的。

public class RssList 
{ 
    [UIHint("Feeds")] 
    public IEnumerable<RssFeedItem> Feeds { get; private set; } 

    [Required(ErrorMessage = "Rss Feed Required")] 
    public string Feed { get; set; } 

    public RssList() 
    { 
    this.Feeds = GetRssFeed(null); 
    } 

    public IEnumerable<RssFeedItem> GetRssFeed(string selectedValue) 
    { 
    List<RssFeedItem> rssList = new List<RssFeedItem>(); 
    XmlDocument doc = new XmlDocument(); 
    XmlNamespaceManager manager = new XmlNamespaceManager(doc.NameTable); 
    manager.AddNamespace("rdf", "http://www.w3.org/1 999/02/22-rdf-syntax-ns#"); 
    manager.AddNamespace("rss", "http://purl.org/rss/1.0/"); 
    XmlTextReader reader = new XmlTextReader("http://wdfw.wa.gov/news/newsrss.php"); 
    doc.Load(reader); 
    XmlNodeList nodes = doc.SelectNodes(
     "/rdf:RDF//rss:item[./rss:link./rss:title./rss:about]", manager); 

    foreach (XmlNode node in nodes) 
    { 
     XmlNodeList aboutNode = node.SelectNodes("rss:about", manager); 
     XmlNodeList titleNode = node.SelectNodes("rss:title", manager); 
     XmlNodeList linkNode = node.SelectNodes("rss:link", manager); 
     var rssItem = new RssFeedItem 
     { 
     Link = linkNode.Count == 0 ? "" : linkNode[0].InnerText, 
     Title = titleNode.Count == 0 ? "" : titleNode[0].InnerText, 
     About = aboutNode.Count == 0 ? "" : aboutNode[0].InnerText 
     }; 
     rssList.Add(rssItem); 
    } 
    return rssList; 
    } 
} 

现在不是一个的SelectList,我们返回一个IEnumerable < RssFeedItem>。如果可能,最好不要从代码中操作UI。所以让我们看看我们是否需要在控制器上施加任何魔法。我看到有唯一的事情是,你可以排除“指数”,从取景功能(它暗示,因为这是控制器操作的名称。

return PartialView(viewModel); 

现在到视图...让我们来看看,如果我们,可以使更好看

<%@ Control Language="C#" 
    Inherits="System.Web.Mvc.ViewUserControl<GodsCreationTaxidermy.Helpers.BusinessDTO.RssList>" %> 

<%  
    foreach (var rssItem in ViewData.Model.Feeds) 
    { 
%> 
    <div id="<%=rssItem.Title%>"> 
    <a href="<%=rssItem.Link%>" target="_blank"> 
    <strong><%=rssItem.Title%></strong> 
    </a> 
<% 
    } 
%> 

在那里,我觉得应该为你做...让我知道如果你遇到任何问题

+0

注意我保持完全相同的逻辑作为显示rssItem的原始文件...根据情况进行更改。 – 2011-04-20 20:33:10