본문 바로가기

프로그래밍/ASP/PHP

RSS READER

public partial class _Default : System.Web.UI.Page
{
    
    protected void Page_Load(object sender, EventArgs e)
    {
        // 여기에 사용자 코드를 배치하여 페이지를 초기화합니다.
        RssReader reader = new RssReader();
        reader.LoadFromHttp("주소");

        RssChannel head = reader.Channel;

        Response.Write("Title : " );
        Response.Write("<a href=" + head.Link.ToString()+">");
        Response.Write(head.Title);
        Response.Write ("</a><br>");
        Response.Write("Language : " + head.Language + "<BR>");
        Response.Write("lastBuildDate : " + head.LastBuildDate + "<BR>");
        Response.Write("Description : " + head.Description + "<BR><BR>");
    
        for (int i = 0; i < reader.Items.Count; i++)
        {
            RssItem item = reader.Items[i];
            Response.Write("TITLE : ");
            Response.Write("<a href="+ item.Link+">");
            Response.Write(item.Title);
            Response.Write("</a>");
            Response.Write("<br>Author : " + item.Author);
            Response.Write("<br>Category : " + item.Category);
            Response.Write("<br>pubDate : " + item.Pubdate + "<br><br>");
        }

    }
        
    public class RssChannel
    {
        private string title;
        private Uri link;
        private string description;
        private string language;
        private string copyright;
        private DateTime lastBuildDate;

        public string Title
        {
            get { return title; }
            set { title = value; }
        }

        public Uri Link
        {
            get { return link; }
            set { link = value; }
        }
        public string Description
        {
            get { return description; }
            set { description = value; }
        }

        public string Language
        {
            get { return language; }
            set { language = value; }
        }

        public string Copyright
        {
            get { return copyright; }
            set { copyright = value; }
        }

        public DateTime LastBuildDate
        {
            get { return lastBuildDate; }
            set { lastBuildDate = value; }
        }
    }

    public class RssItem
    {
        public string Author;
        public string Category;
        public string Title;
        public Uri Link;
        public DateTime Pubdate;
        public string Description;

        public RssItem() { }

    }

    public class RssItems : CollectionBase
    {

        public RssItem this[int index]
        {
            get { return (RssItem)List[index]; }

            set { List[index] = value; }
        }

        public int Add(RssItem value)
        {
            return List.Add(value);
        }

        public int IndexOf(RssItem value)
        {
            return List.IndexOf(value);
        }

        public void Remove(RssItem value)
        {
            List.Remove(value);
        }

        public bool Contains(RssItem value)
        {
            return List.Contains(value);
        }


    }

    public class RssReader
    {
        private XmlDocument Document;
        private XmlNode DocumentRoot;
        private RssItems rssItems;
        private RssChannel rssChannel;

        // 생성자. XmlDocument 개체 생성 및 RssItems 컬렉션 생성
        public RssReader()
        {
            Document = new XmlDocument();
            rssItems = new RssItems();
        }

        #region [공개 속성들]
        // RssItems 컬렉션을 속성으로써 노출한다
        public RssItems Items
        {
            get { return rssItems; }
            set { rssItems = value; }
        }

        // RssChannel 개체를 속성으로써 노출한다
        public RssChannel Channel
        {
            get { return rssChannel; }
            set { rssChannel = value; }
        }
        #endregion

        #region [공개 메서드들]
        // 외부 공개 메서드. 내부적으로 로컬 XML 파일을 로드하는 LoadFromFile 메서드를 호출하고,
        // 로드된 XML 데이트를 가지고, RssReader 개체를 채우는 PopulateRssData 메서드를 호출한다
        public void Load(string filename)
        {
            LoadFromFile(filename);
            PopulateRssData();
        }

        // 외부 공개 메서드. 내부적으로 원격 XML 파일을 로드하는 LoadFromUrl 메서드를 호출하고,
        // 로드된 XML 데이트를 가지고, RssReader 개체를 채우는 PopulateRssData 메서드를 호출한다
        public void LoadFromHttp(string Url)
        {
            LoadFromUrl(Url);
            PopulateRssData();
        }

        // 로컬 XML 파일을 XmlDocument에 로드한다
        private void LoadFromFile(string filename)
        {
            Document.Load(filename);
        }

        // 원격 XML 파일을 HttpWebRequest, HttpWebResponse를 이용하여 XmlDocument에 로드한다
        private void LoadFromUrl(string Url)
        {
            HttpWebRequest request;
            string responseText = "";

            request = (HttpWebRequest)WebRequest.Create(Url);
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream stream = response.GetResponseStream();

            StreamReader reader = new StreamReader(stream, System.Text.Encoding.GetEncoding(949));
            responseText = reader.ReadToEnd();

            response.Close();
            reader.Close();

            Document.LoadXml(responseText);
        }

        #endregion

        // 지정된 XmlNodeList에서 특정 이름의 노드를 찾아서 반환한다
        private XmlNode getNode(XmlNodeList list, string nodeName) 
    { 
        for(int i = 0;i<=list.Count-1; i++) 
        { 
            if (list.Item(i).Name == nodeName) 
            { 
                return list.Item(i); 
            }
        } 

        return null;
    }

        // XmlDocument에서 데이터를 추출하여 RssReader 개체를 채운다
        private void PopulateRssData() 
        { 
            XmlNode node; 
            XmlNode itemNode; 



            //헤더 초기화
            rssChannel = new RssChannel();
            rssChannel.Copyright = ""; 
            rssChannel.Description = ""; 
            rssChannel.Language = ""; 
            rssChannel.Title = ""; 
            DocumentRoot = getNode(Document.ChildNodes, "rss"); 
            DocumentRoot = getNode(DocumentRoot.ChildNodes, "channel"); 

            // 헤더값들을 설정하는 부분
            node = getNode(DocumentRoot.ChildNodes, "title");
            if (node != null) rssChannel.Title = node.InnerText; 
            node = getNode(DocumentRoot.ChildNodes, "link");
            if (node != null) rssChannel.Link = new Uri(node.InnerText); 
            
            node = getNode(DocumentRoot.ChildNodes, "description");
            if (node != null) rssChannel.Description = node.InnerText; 

            node = getNode(DocumentRoot.ChildNodes, "language");
            if (node != null) rssChannel.Language = node.InnerText; 
            node = getNode(DocumentRoot.ChildNodes, "copyright");
            if (node != null) rssChannel.Copyright = node.InnerText; 

            node = getNode(DocumentRoot.ChildNodes, "lastBuildDate");
            if (node != null) rssChannel.LastBuildDate= DateTime.Parse(node.InnerText);

            rssItems.Clear(); 

            for (int i = 0;i<= DocumentRoot.ChildNodes.Count - 1; i++) 
            { 
                // item 노드를 루프 돌면서 데이터를 가져온다
                if (DocumentRoot.ChildNodes[i].Name == "item") 
                { 
                    itemNode = DocumentRoot.ChildNodes[i]; 
                    RssItem item = new RssItem(); 

                    node = getNode(itemNode.ChildNodes, "author"); 
                    if (node != null) item.Author = node.InnerText; 

                    node = getNode(itemNode.ChildNodes, "category"); 
                    if (node != null) item.Category = node.InnerText; 

                    node = getNode(itemNode.ChildNodes, "title"); 
                    if (node != null) item.Title = node.InnerText; 

                    node = getNode(itemNode.ChildNodes, "link"); 
                    if (node != null) item.Link = new Uri(node.InnerText);

                    node = getNode(itemNode.ChildNodes, "pubDate");
                    if (node != null)
                    {
                        try
                        {
                            item.Pubdate = DateTime.Parse(node.InnerText);
                        }
                        catch (FormatException)
                        {
                            Console.WriteLine("{0}, {1}", node.Name, node.InnerText);
                            node.InnerText = "0001-01-01T00:00:00-06:00";
                        }

                    }
                    node = getNode(itemNode.ChildNodes, "description"); 
                    if (node != null) item.Description = node.InnerText;

                    rssItems.Add(item); 
                }
            }
        }
    }
}