从RSS解析信息

时间:2014-02-14 22:04:06

标签: c# parsing rss

我认为这是一项相对简单的任务,这给我带来了很多麻烦。我要进入雅虎!天气RSS提要并尝试获取lastBuildDate并将该值存储在标签中。但是,在启动时,我得到Data at the root level is invalid. Line 1, position 1.来引用GetBuild()中的最后一行:

var lastBuild = XDocument.Parse(query).Root.Element("channel").Element("lastBuildDate").Value;

我确定我错误地引用了lastBuildDate的位置,但我只是不确定如何修复错误。在解析和获取外部信息方面,我是新手。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;

namespace WeatherApp
{
    public partial class frmWeather : Form
    {
        string lastBuild;
        public frmWeather()
        {
            InitializeComponent();
        }
        private void getBuild()
        {
            string query = string.Format("http://weather.yahooapis.com/forecastrss?w=2357473");
            var lastBuild = XDocument.Parse(query).Root.Element("channel").Element("lastBuildDate").Value;
        }
        private void frmWeather_Load(object sender, EventArgs e)
        {
            getBuild();
            lblLastBuild.Text = lastBuild;
        }
    }
}

以下是RSS Feed的格式:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 
<rss version="2.0" xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
    <channel>
        <title>Yahoo! Weather - Aurora, CO</title> 
        <link>http://us.rd.yahoo.com/dailynews/rss/weather/Aurora__CO/*http://weather.yahoo.com/forecast/USCO0019_f.html</link> 
        <description>Yahoo! Weather for Aurora, CO</description> 
        <language>en-us</language> 
        <lastBuildDate>Fri, 14 Feb 2014 1:54 pm MST</lastBuildDate>

4 个答案:

答案 0 :(得分:1)

这里:

 var lastBuild = XDocument.Parse(query).Root.Element("channel").Element("lastBuildDate").Value;

您正在尝试解析Url而不是 XML内容 .Parse方法需要解析XML个内容。而是使用XDocument.Load(query)

先下载内容然后解析:

using (var client = new WebClient())
{
      string content = client.DownloadString("http://weather.yahooapis.com/forecastrss?w=2357473");
      var lastBuild = XDocument.Parse(content).Root
                     .Element("channel")
                     .Element("lastBuildDate").Value;
}

为了避免NullReferenceException使用显式转换而不是直接访问Value属性。这是带有空检查的更好版本:

using (var client = new WebClient())
{
      string content = client.DownloadString("http://weather.yahooapis.com/forecastrss?w=2357473");
      var rootElement = XDocument.Parse(content).Root;
      if (rootElement != null)
      {
           var lastBuild = (string)rootElement.Element("channel")
                                  .Element("lastBuildDate");
           if (lastBuild != null)
           {
                 // display value in the label
           }
       }
}

答案 1 :(得分:0)

据我所知,你将网址本身传递给XDocument.Parse,而不是通过HTTP GET返回的结果。

所以你需要这样的东西;

        private void getBuild()
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://weather.yahooapis.com/forecastrss?w=2357473");

            // make request and get string
            string responseBody = inputStream.ReadToEnd();
            var lastBuild = XDocument.Parse(responseBody).Root.Element("channel").Element("lastBuildDate").Value;
        }

为了简洁起见,我省略了更多的HTTP代码。到这里来看一个完整的例子; http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.getresponse(v=vs.110).aspx

答案 2 :(得分:0)

我找到了一个旧的测试项目:

  static void Main (string[] args)
  {

        XmlDocument doc = new XmlDocument ();

        doc.Load ("http://xml.weather.yahoo.com/forecastrss?p=GMXX1791&u=c"); 
        //doc.Save ("test.xml");


        XmlNamespaceManager ns = new XmlNamespaceManager (doc.NameTable);
        ns.AddNamespace ("yweather", "http://xml.weather.yahoo.com/ns/rss/1.0");


        XmlNodeList lastBuildDate = doc.SelectNodes ("//rss/channel/lastBuildDate", ns);
        Console.WriteLine (lastBuildDate[0].InnerText);

        XmlNodeList nodescity = doc.SelectNodes ("//rss/channel/title", ns);
        foreach (XmlNode xnCity in nodescity)
        {
            Console.WriteLine (xnCity.InnerText);
        }

        XmlNodeList nodes = doc.SelectNodes ("//rss/channel/item/yweather:forecast", ns);

        foreach (XmlNode node in nodes)
        {
            Console.WriteLine ("{0}: {1}, {2}C - {3}C",
            node.Attributes["day"].InnerText,
            node.Attributes["text"].InnerText,
            node.Attributes["low"].InnerText,
            node.Attributes["high"].InnerText);
        }
    }

答案 3 :(得分:0)

string lastBuildDate = XDocument.Parse(query).Descendants("channel").Select(x => x.Element("lastBuildDate").Value).FirstOrDefault();