RSS читалка в виде CLR-сборки

by Admin 16. ноября 2009 23:08

RSS — семейство XML-форматов, предназначенных для описания лент новостей, анонсов статей, изменений в блогах и т. п.

Информация из различных источников, представленная в формате RSS, может быть собрана, обработана и представлена пользователю в удобном для него виде специальными программами-агрегаторами. Появилась необходимость "собирать" базу знаний с разных RSS-каналов и сохранять её на сервере БД. Тут же родилась CLR-сборка, которую я запускаю через JOB раз в N-времени.

Таким образом у меня уже пару дней база наполняется информацией на автомате.

Код сборки на C#:

using System;
using Microsoft.SqlServer.Server;
using System.Collections;
using System.Xml;

public class CLRRss
{

    [SqlFunction(FillRowMethodName = "FillRow"
        , TableDefinition = "Title nvarchar(128), Link nvarchar(128), PubDate nvarchar(50), Creator nvarchar(128), Description nvarchar(max)")
    ]

    public static IEnumerable RSSReader(string txtUrl)
    {
        XmlNode nodeRss = null;
        XmlNode nodeChannel = null;
        XmlNode nodeItem;

        ArrayList rows = new ArrayList();

        XmlTextReader rssReader = new XmlTextReader(txtUrl);
        XmlDocument rssDoc = new XmlDocument();

        rssDoc.Load(rssReader);

        // 
        for (int i = 0; i < rssDoc.ChildNodes.Count; i++)
        {
            if (rssDoc.ChildNodes[i].Name == "rss")
            {
                nodeRss = rssDoc.ChildNodes[i];
            }
        }

        // 
        for (int i = 0; i < nodeRss.ChildNodes.Count; i++)
        {
            // If it is the channel tag
            if (nodeRss.ChildNodes[i].Name == "channel")
            {
                //  tag found
                nodeChannel = nodeRss.ChildNodes[i];
            }
        }

        // 

Регистрируем сборку:

CREATE ASSEMBLY AssemblyRSS
FROM 'C:\CLR\CLRRss.dll'
WITH PERMISSION_SET = UNSAFE
GO

--Создаём функцию
CREATE FUNCTION RssReader(@txtUrl nvarchar(128))
RETURNS TABLE
(
Title NVARCHAR(128),
Link NVARCHAR(128),
PubDate NVARCHAR(50),
Creator NVARCHAR(128),
Decription NVARCHAR(max)
)
EXTERNAL NAME AssemblyRSS.CLRRss.RSSReader;

Ну и пример её использования (читаем RSS-канал нашего сообщества RussianSqlServerClub):

SELECT * FROM RssReader('http://feeds2.feedburner.com/RussianSqlServerClub')

Результат:

Но этот вариант будет работать, если ваш сервер БД "смотрит" в интерент, ниже вариант для чтение RSS-каналов через Proxy:

Текст CLR-сборки:

using System;
using Microsoft.SqlServer.Server;
using System.Collections;
using System.Xml;
using System.Net;
using System.IO;

public class CLRRss
{

    [SqlFunction(FillRowMethodName = "FillRow"
        , TableDefinition = "Title nvarchar(128), Link nvarchar(128), PubDate nvarchar(50), Creator nvarchar(128), Description nvarchar(max)")
    ]

    public static IEnumerable RSSReader(string txtUrl, string ProxyServer, string DomainName, string UserAccount, string Password))
    {
        XmlNode nodeRss = null;
        XmlNode nodeChannel = null;
        XmlNode nodeItem;

        ArrayList rows = new ArrayList();

            HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(txtUrl);

            if (UserAccount != "")
            {
                wr.Credentials = new NetworkCredential(UserAccount, Password, DomainName);
            }

            if (ProxyServer != "")
            {
                wr.Proxy = new WebProxy(ProxyServer, true, new string[] { }, wr.Credentials);
            }

            WebResponse resp = wr.GetResponse();
            Stream stream = resp.GetResponseStream();

            XmlTextReader rssReader = new XmlTextReader(stream);
        XmlDocument rssDoc = new XmlDocument();

        rssDoc.Load(rssReader);

        // 
        for (int i = 0; i < rssDoc.ChildNodes.Count; i++)
        {
            if (rssDoc.ChildNodes[i].Name == "rss")
            {
                nodeRss = rssDoc.ChildNodes[i];
            }
        }

        // 
        for (int i = 0; i < nodeRss.ChildNodes.Count; i++)
        {
            // If it is the channel tag
            if (nodeRss.ChildNodes[i].Name == "channel")
            {
                //  tag found
                nodeChannel = nodeRss.ChildNodes[i];
            }
        }

        // 

Регистрируем сборку, а далее создаём SQL-функцию:

CREATE FUNCTION RssReader
(
@txtUrl nvarchar(128),
@ProxyServer nvarchar(128)=null,
@DomainName nvarchar(128)=null,
@UserAccount nvarchar(128)=null,
@Password nvarchar(128)=null
)
RETURNS TABLE
(
title NVARCHAR(128),
link NVARCHAR(128),
pubDate NVARCHAR(50),
creator NVARCHAR(128),
decription NVARCHAR(max)
)
EXTERNAL NAME AssemblyRSS.CLRRss.RSSReader;

Сам вызов будет выглядить в зависимости от того, как мы подключаемся к и-нету. Чтение RSS-канала на прямую:

SELECT * FROM RssReader('http://feeds2.feedburner.com/RussianSqlServerClub', default, default, default, default))

либо через Proxy:

SELECT * FROM RssReader('http://feeds2.feedburner.com/RussianSqlServerClub', 192.168.1.1:3128, MyDomain, UserName, UserPassword))

Tags: , ,

SQL Server

Комментарии (3) -

Alexey Knyazev
Alexey Knyazev Russia
18.03.2010 23:19:37 #

Не забываем про:

1) SP_CONFIGURE ‘clr enabled’, 1
RECONFIGURE

2) ALTER DATABASE [Ваша база] SET TRUSTWORTHY ON

3) Сервер БД должен смотреть в инет на прямую(если доступ не через прокси)

Reply

pxg
pxg Russia
24.02.2011 16:50:24 #

Чисто практический вопрос: а чем/как ты потом просматриваешь собранное?

Reply

Alexey Knyazev
Alexey Knyazev Russia
01.03.2011 0:11:03 #

Да чем угодно...например на своем веб-сайте

Reply

Добавить комментарий

  Country flag

biuquote
  • Комментарий
  • Предпросмотр
Loading