国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

.Net/C#: 利用反射編寫通用的 rss 2.0 的 reader

2024-07-10 13:00:13
字體:
供稿:網(wǎng)友
/*
.net/c#: 利用反射編寫通用的 rss 2.0 的 reader

最近在寫一個(gè) simple rss reader
網(wǎng)上找到現(xiàn)成代碼兩種:
1.代碼簡(jiǎn)單的,但不夠通用 (如: 本站的一些專用 rss reader)
2.代碼復(fù)雜的,但沒有足夠時(shí)間去消化 (如: rssbandit)

遂自己動(dòng)手:
由于 rss 的基本屬性大家都有!
但一些特殊不通用屬性,如:
slash:comments
wfw:comment
wfw:commentrss
trackbackping
不一定存在! 如何處理???
我想到了 reflection,就此提出以下解決方案:
1. class rssheader 用于表示 rss 的頭信息
你可以在為其添加新屬性,原則是:
成員變量 fieild 的名稱為 rss 的 xml 源對(duì)應(yīng)的屬性名稱前加下劃線,xml 屬性名稱含有 ":" 將其濾掉!
如: <dc:language>zh-chs</dc:language>
將其影射為:
private string _dclanguage
public string dclanguage
{
get
{
return this._dclanguage;
}
}

2. class rssitem 用于表示 rss 的 item
添加新屬性的原則同 rssheader!

3. 獲取 rss 的 xml 源后通過遞歸遍歷節(jié)點(diǎn) (class simplerssreader)
根據(jù)實(shí)際存在的 rss 屬性,通過反射,"構(gòu)造實(shí)例化" rssheader 和 rssitem!
請(qǐng)仔細(xì)參閱 class simplerssreader 的 travel 方法!

4. 數(shù)據(jù)庫 (本文使用了 micrshaoft data access application block 3.1)
表:
channels (主表)
channelsdetails (細(xì)表)
字段名稱及其數(shù)據(jù)類型嚴(yán)格按照 rss 的 xml 源對(duì)應(yīng)的屬性名稱,xml 屬性名稱含有 ":" 將其濾掉!
存儲(chǔ)過程:
sp_addchannel
sp_addchannelsdetails
參數(shù)名稱及其數(shù)據(jù)類型嚴(yán)格按照 rss 的 xml 源對(duì)應(yīng)的屬性名稱,xml 屬性名稱含有 ":" 將其濾掉!


命令行編譯:
csc simplersreader.cs /r:c:/windows/microsoft.net/framework/v1.1.4322/system.data.oracleclient.dll


全部代碼 simplerssreader.cs 在此下載
http://www.cnblogs.com/files/microshaoft/simplerssreader.rar


*/
namespace microshaoft
{
using system;
using system.xml;
using system.text;
using system.reflection;
using system.collections;
using system.text.regularexpressions;



全部代碼 simplerssreader.cs 在此下載
http://www.cnblogs.com/files/microshaoft/simplerssreader.rar


*/
namespace microshaoft
{
using system;
using system.xml;
using system.text;
using system.reflection;
using system.collections;
using system.text.regularexpressions;


public class rssheader
{
//feed url
public rssheader(string url)
{
this._url = url;
}

public string title
{
get
{
return this._title;
}
}

public string description
{
get
{
return this._description;
}
}

public string link
{
get
{
return this._link;
}
}

public string language
{
get
{
return this._language;
}
}

public string generator
{
get
{
return this._generator;
}
}

public string ttl
{
get
{
return this._ttl;
}
}

public string copyright
{
get
{
return this._copyright;
}
}

public datetime pubdate
{
get
{
return util.parsedatetime(this._pubdate);
}
}

public string category
{
get
{
return this._category;
}
}

public datetime lastbuilddate
{
get
{
return util.parsedatetime(this._lastbuilddate);
}
}
public string managingeditor
{
get
{
return this._managingeditor;
}
}

public string url
{
get
{
return this._url;
}
}

public string dclanguage
{
get
{
return this._dclanguage;
}
}

//下面私有 field 的值將 class simplerssreader 中通過反射賦值
private string _dclanguage; //dc:language
private string _url;
private string _managingeditor;
private string _lastbuilddate;
private string _title;
private string _description;
private string _link;
private string _language;
private string _generator;
private string _ttl;
private string _copyright;
private string _pubdate;
private string _category;


}
public class rssitem
{
private rssheader _header;

public rssheader header
{
get
{
return this._header;
}
}

//下面私有 field 的值將 class simplerssreader 中通過反射賦值
private string _title;
private string _link;
private string _description;
private string _category;
private string _author;
private string _pubdate;
private string _comments;
private string _guid;
private string _slashcomments;
private string _wfwcomment;
private string _wfwcommentrss;
private string _trackbackping;

public string trackbackping
{
get
{
return this._trackbackping;
}
}

public string wfwcommentrss
{
get
{
return this._wfwcommentrss;
}
}

public string wfwcomment
{
get
{
return this._wfwcomment;
}
}


public string slashcomments
{
get
{
return this._slashcomments;
}
}
public string title
{
get
{
return this._title;
}
}

public string link
{
get
{
return this._link;
}
}

public string description
{
get
{
return this._description;
}
}

public string category
{
get
{
return this._category;
}
}

public string author
{
get
{
return this._author;
}
}

public datetime pubdate
{
get
{
return util.parsedatetime(this._pubdate);
}
}

public string comments
{
get
{
return this._comments;
}
}

public string guid
{
get
{
return this._guid;
}
}
}
public class simplerssreader
{
//rssheader header 解析處理完畢事件
public delegate void rssheaderreceiveeventhandler(simplerssreader sender, rssheader header);
public event rssheaderreceiveeventhandler rssheaderreceive;

//某一個(gè) rssitem 解析處理完畢事件
public delegate void rssitemreceiveeventhandler(simplerssreader sender, rssitem item);
public event rssitemreceiveeventhandler rssitemreceive;

private type _trs; //typeof(rssheader)
private type _tri; //typeof(rssitem)

private arraylist _rssitemsal;

private rssheader _rs;
public rssheader rssheader
{
get
{
return this._rs;
}
}

//用于存儲(chǔ)所有的 rssitem
private rssitem[] _rssitems;

public rssitem[] rssitems
{
get
{
return this._rssitems;
}
}

public void rss(string url)
{
xmldocument xd = new xmldocument();
//如果效率不高可采用 webrequest 替代
xd.load(url);
xmlnodelist xnl = xd.selectnodes("/rss/channel");

this._rs = new rssheader(url);

this._trs = typeof(rssheader);
this._tri = typeof(rssitem);

this._rssitemsal = new arraylist();

foreach (xmlnode xn in xnl)
{
//遞歸遍歷
this.travel(xn, 0);
}

if (this._rssitemsal.count > 0)
{
this._rssitems = new rssitem[this._rssitemsal.count];
int i = 0;
foreach (object o in this._rssitemsal)
{
this._rssitems[i++] = (rssitem) o;
}
}
}

/// <header>
/// 遞歸遍歷
/// </header>
/// <param name="xn">節(jié)點(diǎn)</param>
/// <param name="i">項(xiàng)目數(shù)</param>
private void travel(xmlnode xn, int i)
{
if (xn.haschildnodes)
{
foreach (xmlnode x in xn.childnodes)
{
if (x.parentnode != null)
{
if (x.parentnode.name == "channel")
{
if (x.name == "item")
{
i ++;
if (i >= 1)
{
xmlnode node = null;
bool b = false; //是否是 rss item
rssitem ri = null;
if (i == 1) //header
{
node = xn;
b = false;
}
else if (i > 1) //item
{
node = x;
b = true;
ri = new rssitem();
}

foreach (xmlnode n in node.childnodes)
{
if (n.name != "item")
{
if (!b) //rss header header
{
//根據(jù) xml 實(shí)際存在的屬性,利用反射為 rssheader 實(shí)例的私有成員賦值
fieldinfo fi = this._trs.getfield("_" + n.name.replace(":","") ,bindingflags.nonpublic | bindingflags.instance | bindingflags.public);
if (fi != null)
{
fi.setvalue(this._rs,n.innertext);
}
}
else //rss item
{
//根據(jù) xml 實(shí)際存在的屬性,利用反射為 rssitem 實(shí)例的私有成員賦值
fieldinfo fi = this._tri.getfield("_" + n.name.replace(":",""),bindingflags.nonpublic | bindingflags.instance | bindingflags.public);
if (fi != null)
{
fi.setvalue(ri,n.innertext);
}
}

}
}
if (!b)
{
//觸發(fā) rssheaderreceive 事件
if (this.rssheaderreceive != null)
{
this.rssheaderreceive(this,this._rs);
}
}
else
{
//制定 rssitem 實(shí)例的 header/header
fieldinfo fi = this._tri.getfield("_header",bindingflags.nonpublic | bindingflags.instance | bindingflags.public);
if (fi != null)
{
fi.setvalue(ri,this._rs);
}

//觸發(fā) rssitemreceive 事件
if (this.rssitemreceive != null)
{
this.rssitemreceive(this,ri);
}
this._rssitemsal.add(ri);
}
}
}
}
}
if (!x.haschildnodes)
{
this.travel(x, i);
}
}
}
}
}

public class util
{
public static datetime parsedatetime(string s)
{
datetime dt;
if (s == null || s.tostring().length <= 0)
{
dt = datetime.now;
}
else
{
try
{
dt = datetime.parse(s);
}
catch
{
dt = datetime.now;
}
}
return dt;
}
/// <header>
/// 去除 html tag
/// </header>
/// <param name="html">源</param>
/// <returns>結(jié)果</returns>
public static string striphtml(string html) //google "striphtml" 得到
{
string[] regexs =
{
@"<script[^>]*?>.*?</script>",
@"<(///s*)?!?((/w+:)?/w+)(/w+(/s*=?/s*(([""'])(//[""'tbnr]|[^/7])*?/7|/w+)|.{0})|/s)*?(///s*)?>",
@"([/r/n])[/s]+",
@"&(quot|#34);",
@"&(amp|#38);",
@"&(lt|#60);",
@"&(gt|#62);",
@"&(nbsp|#160);",
@"&(iexcl|#161);",
@"&(cent|#162);",
@"&(pound|#163);",
@"&(copy|#169);",
@"&#(/d+);",
@"-->",
@"<!--.*/n"
};

string[] replaces =
{
"",
"",
"",
"/"",
"&",
"<",
">",
" ",
"/xa1", //chr(161),
"/xa2", //chr(162),
"/xa3", //chr(163),
"/xa9", //chr(169),
"",
"/r/n",
""
};

string s = html;
for (int i = 0; i < regexs.length; i++)
{
s = new regex(regexs[i], regexoptions.multiline | regexoptions.ignorecase).replace(s, replaces[i]);
}
s.replace("<", "");
s.replace(">", "");
s.replace("/r/n", "");
return s;
}
}
}

//測(cè)試程序
namespace test
{
using system;
using system.data;
using system.reflection;
using system.data.sqlclient;

using microshaoft;
using microshaoft.data;

class consoleapplication
{
private sqlconnection _connection;
public string _channel;

public sqlconnection connection
{
set
{
this._connection = value;
}
get
{
return this._connection;
}
}

static void main()
{

string s = "http://www.ccw.com.cn/rss/news2/1.xml";
s = "http://dzh.mop.com/topic/rss.jsp?type=28";
s = "http://www.ccw.com.cn/rss/news2/15.xml";
s = "http://www.cnblogs.com/rss.aspx?id=-1";
s = "http://localhost/rss.xml";
//s = "http://weblog.siliconvalley.com/column/dangillmor/index.xml";
//s= "http://www.skyone.com.cn/sub/rss/list_jjsc.xml";

consoleapplication a = new consoleapplication();

a.connection = new sqlconnection("server=server//psqlke;user id=sa;password=;database=rss");
a.connection.open();

simplerssreader srr = new simplerssreader();

srr.rssheaderreceive += new microshaoft.simplerssreader.rssheaderreceiveeventhandler(a.srr_rssheaderreceive);
srr.rssitemreceive +=new microshaoft.simplerssreader.rssitemreceiveeventhandler(a.srr_rssitemreceive);

system.console.writeline("waiting ....");
srr.rss(s); //以后改成多線程或異步

system.console.writeline("print all rss header and items ....");
system.console.readline();
system.console.writeline("header: "+ srr.rssheader.title);
foreach (rssitem ri in srr.rssitems)
{
system.console.writeline("item: " + ri.title);
}
system.console.readline();

}

private void srr_rssheaderreceive(simplerssreader sender, rssheader header)
{
system.console.writeline("header:" + header.link);
system.console.writeline("header:" + header.title);

this.savetodatabase("sp_addchannel",typeof(rssheader),header);

}

private void srr_rssitemreceive(simplerssreader sender, rssitem item)
{
system.console.writeline("item: " + item.title);
system.console.writeline("item: " + item.link);
system.console.writeline("item: " + util.striphtml(item.description));

this.savetodatabase("sp_addchannelsdetails",typeof(rssitem),item);

}
private void savetodatabase(string sp, type t,object instance)
{
//獲取 sp 所有參數(shù)
sqlparameter[] spa = sqlhelperparametercache.getspparameterset(this.connection, sp);
system.collections.hashtable ht = new system.collections.hashtable();

for (int i = 0; i < spa.length; i++)
{
//保存 參數(shù)名稱與其位置(次序) 的關(guān)系
ht.add(spa[i].parametername.tolower().replace("@", ""), i);

//相當(dāng)于為存儲(chǔ)過程的所有參數(shù)賦初值
spa[i].value = null;
}

//得到所有的屬性
propertyinfo[] pi = t.getproperties();
foreach (propertyinfo x in pi)
{
if (ht.containskey( x.name.tolower()))
{
//根據(jù)參數(shù)(屬性)名稱得到參數(shù)的次序!
int i = (int) ht[x.name.tolower()];
if (spa[i].direction == system.data.parameterdirection.input || spa[i].direction == system.data.parameterdirection.inputoutput)
{
object o;
if (x.propertytype.name == "string")
{
o = x.getvalue(instance,null);
if (o != null)
{
string s = util.striphtml((string) o);
o = s;
}
}
else
{
o = x.getvalue(instance,null);
}

spa[i].value = o;
}
}

}

if (t == typeof(rssitem))
{
spa[0].value = ((rssitem) instance).header.url;
}

sqlhelper.executenonquery(this.connection, commandtype.storedprocedure, sp, spa);
if (spa[spa.length - 1].value != system.dbnull.value)
{
system.console.writeline("save to id: {0} successful!", spa[spa.length - 1].value);
}
else
{
system.console.writeline("save failed! may be duplicate!");
}
}
}
}

//==========================================================================================================
/*
--sql script
if exists (select * from dbo.sysobjects where id = object_id(n'[dbo].[sp_addchannel]') and objectproperty(id, n'isprocedure') = 1)
drop procedure [dbo].[sp_addchannel]
go

if exists (select * from dbo.sysobjects where id = object_id(n'[dbo].[sp_addchannelsdetails]') and objectproperty(id, n'isprocedure') = 1)
drop procedure [dbo].[sp_addchannelsdetails]
go

if exists (select * from dbo.sysobjects where id = object_id(n'[dbo].[channels]') and objectproperty(id, n'isusertable') = 1)
drop table [dbo].[channels]
go

if exists (select * from dbo.sysobjects where id = object_id(n'[dbo].[channelsdetails]') and objectproperty(id, n'isusertable') = 1)
drop table [dbo].[channelsdetails]
go

create table [dbo].[channels] (
[id] [int] identity (1, 1) not null ,
[url] [varchar] (1000) collate chinese_prc_ci_as null ,
[channel] [varchar] (100) collate chinese_prc_ci_as null ,
[title] [varchar] (100) collate chinese_prc_ci_as null ,
[description] [varchar] (1000) collate chinese_prc_ci_as null ,
[link] [varchar] (500) collate chinese_prc_ci_as null ,
[language] [varchar] (10) collate chinese_prc_ci_as null ,
[generator] [varchar] (100) collate chinese_prc_ci_as null ,
[ttl] [varchar] (100) collate chinese_prc_ci_as null ,
[copyright] [varchar] (100) collate chinese_prc_ci_as null ,
[pubdate] [datetime] null ,
[category] [varchar] (100) collate chinese_prc_ci_as null ,
[dclanguage] [varchar] (100) collate chinese_prc_ci_as null
) on [primary]
go

create table [dbo].[channelsdetails] (
[id] [int] identity (1, 1) not null ,
[channelid] [int] null ,
[title] [varchar] (8000) collate chinese_prc_ci_as null ,
[link] [varchar] (8000) collate chinese_prc_ci_as null ,
[description] [varchar] (8000) collate chinese_prc_ci_as null ,
[category] [varchar] (8000) collate chinese_prc_ci_as null ,
[author] [varchar] (8000) collate chinese_prc_ci_as null ,
[pubdate] [datetime] null ,
[comments] [varchar] (8000) collate chinese_prc_ci_as null ,
[guid] [varchar] (8000) collate chinese_prc_ci_as null ,
[trackbackping] [varchar] (8000) collate chinese_prc_ci_as null
) on [primary]
go

set quoted_identifier on
go
set ansi_nulls on
go


create proc sp_addchannel
@url varchar(8000)
,@link varchar(8000)
,@channel varchar(8000)
,@title varchar(8000)
,@image varchar(8000)
,@description varchar(7999)
,@language varchar(8000)
,@generator varchar(8000)
,@ttl varchar(8000)
,@copyright varchar(8000)
,@pubdate datetime
,@category varchar(8000)
,@docs varchar(8000)
,@managingeditor varchar(8000)
,@dclanguage varchar(8000)
,@ int out
as
set @ = 0
insert into channels ([url],[channel],[title],[description],[link],[language],[generator],[ttl],[copyright],[pubdate],[category],[dclanguage])
select @url,@channel,@title,@description,@link,@language,@generator,@ttl,@copyright,@pubdate,@category,@dclanguage
where not exists(select 1 from channels where [url] = @url)
select @ = scope_identity()
go
set quoted_identifier off
go
set ansi_nulls on
go

set quoted_identifier on
go
set ansi_nulls on
go



create proc sp_addchannelsdetails
@url varchar(8000)
,@title varchar(8000)
,@description varchar(7000)
,@link varchar(8000)
,@pubdate datetime
,@category varchar(8000)
,@comments varchar(8000)
,@guid varchar(8000)
,@trackbackping varchar(8000)
,@ int out
as
set @ = 0
insert into channelsdetails ([channelid],[title],[description],[link],[pubdate],[category],[comments],[guid],[trackbackping])
select id,@title,@description,@link,@pubdate,@category,@comments,isnull(@guid,@link),@trackbackping
from channels
where not exists (select 1 from channelsdetails where guid = isnull(@guid,@link)) and url = @url
select @ = scope_identity()
go
set quoted_identifier off
go
set ansi_nulls on
go
*/


商業(yè)源碼熱門下載www.html.org.cn

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 廉江市| 郁南县| 聂拉木县| 栾川县| 中方县| 遂昌县| 武隆县| 巢湖市| 宣武区| 吉安市| 万年县| 健康| 永兴县| 铜山县| 达州市| 祁门县| 普兰县| 平和县| 库尔勒市| 三门县| 长沙市| 汉阴县| 西青区| 平罗县| 虹口区| 内丘县| 个旧市| 昆明市| 新干县| 泽库县| 嘉祥县| 磴口县| 隆昌县| 屏南县| 疏勒县| 安达市| 辉南县| 南京市| 深水埗区| 大洼县| 紫金县|