为了将博客导入到blogengine,需要将别的网站的博客rss转化成blogengine支持的博客xml文件blogML。
首先下载一个现成的blogML2.0生成源文件,包含两个文件,一个前台文件blogml.aspx,一个后台程序blogml.aspx.cs,从前台程序中看到主要结构是四个repeater控件:
1.<asp:Repeater id="tags" runat="server">
2.<asp:Repeater id="posts" OnItemDataBound="posts_ItemDataBound" runat="server">
3.<asp:Repeater id="postTags" runat="server">
4.<asp:Repeater id="comments" runat="server">
第一个是显示分类的,第二个实现每条博文的显示,第三第四个是嵌套在第二个Repeater中的Repeater。
后台程序就是实现这些Repeater控件的数据绑定,默认使用的数据是从数据库中提取,使用存储过程取得数据加入到dataset中,再将dataset绑定到Repeater上,实现数据罗列。
而我们需要的数据源是从rss取得,看下需要转化的RSS文件,结构为rss/channel/item,每个item就是一条博文记录,里面有标题、发布时间、分类、tag、内容、评论等信息。评论节点comment下又有子节点,记录了评论的时间、作者、内容等信息。
首先实现博文Repeater的绑定private void bindToPostRepeater(Repeater rpt),还是使用dataset作为绑定介质。首先创建dataset新表和xml文档,从xml文档中读出需要的rss数据装载到dataset表中,再绑定就OK了。思路很简单,但是对于没有一点技巧的新手来说完成这些还是查了不少资料,从头了解dataset,xml和Repeater的数据绑定原理。万事开头难,就是这个道理。
View Code
{
DataSet ds1 = new DataSet();
DataTable dt1 = new DataTable();
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(MapPath("wp2.xml"));
dt1.TableName = "post";
dt1.Columns.Add("originalID", Type.GetType("System.String"));
dt1.Columns.Add("id", Type.GetType("System.String"));
dt1.Columns.Add("title", Type.GetType("System.String"));
dt1.Columns.Add("content", Type.GetType("System.String"));
dt1.Columns.Add("datePublished",Type.GetType("System.DateTime"));
XmlNode postroot = xmldoc.DocumentElement;
int i = 0;
foreach (XmlNode post in postroot.ChildNodes[0])
{
dt1.Rows.Add(xmldoc.GetElementsByTagName("title")[i].ParentNode.Attributes[0].Value.ToString(), System.Guid.NewGuid().ToString(), xmldoc.GetElementsByTagName("title")[i].ChildNodes[0].Value.ToString(), xmldoc.GetElementsByTagName("content:encoded")[i].ChildNodes[0].Value.ToString(), xmldoc.GetElementsByTagName("post_date")[i].ChildNodes[0].Value.ToString());
i = i + 1;
}
ds1.Tables.Add(dt1);
rpt.DataSource = ds1;
rpt.DataBind();
}
第一步完成,接下来要绑定嵌套的Repeater,原理一样,但是如何在绑定大Repeater的时候同时绑定小Repeater是个问题,所幸Repeater中有一个protected void posts_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)的方法,就是在这里实现内嵌Repeater的绑定。
View Code
{
// Return for none data items
if(e.Item.DataItem == null)
{
return;
}
RepeaterItem item = e.Item;
string originalID=((DataRowView)e.Item.DataItem).Row["originalID"].ToString();//
bindToTagRepeater(item, "postTags", originalID); //绑定TagRepeater,参数item是当前项,postTags是tag Repeater的名称,originalID是另外加在原始rss的ITEM的属性值,用来唯一标识item项。
bindToCommentRepeater(item, "comments", originalID); //绑定CommentRepeater,原理同上。
}
看了源RSS,发现item节点中没有标识这个item唯一性的标记,就想到为这个item节点添加id属性,以便在程序中确定这个唯一的id。为了添加这个属性,颇费了些周折,主要是对于xml实在是不甚了解,为了实现这个操作,了解了节点、属性及创建、修改、删除节点,读写xml document的知识点。创建方法如下:
xmldoc.Load(MapPath("wp.xml"));
XmlNodeList xmlnodelist = xmldoc.GetElementsByTagName("item");
for (int i = 0; i < xmlnodelist.Count; i++)
{
XmlAttribute xmlatt = xmldoc.CreateAttribute("id");
xmlatt.Value = (i + 1).ToString();
xmlnodelist.Item(i).Attributes.Append(xmlatt);
}
xmldoc.Save("d:/project/repeater/wpaddid.xml");
其中wp.xml是原wp文件,注意原文件中的标记前有前缀wp:,可使用查找,替换去除再进行以下操作,添加了item的属性ID后将新xml文档保存在wpaddid.xml中,xmldoc.save后面的文件地址是绝对路径.
最后再通过xpath找到id为originalID的item项,绑定其中的tag和comment到tag Repeater和comment Repeater上。绑定原理同post Repeater。
View Code
{
Repeater rpt = (Repeater)item.FindControl(rptName);
DataSet ds1 = new DataSet();
DataTable dt1 = new DataTable();
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(MapPath("wp2.xml"));
dt1.TableName = "postTags";
dt1.Columns.Add("originalID", Type.GetType("System.String"));
dt1.Columns.Add("content", Type.GetType("System.String"));
XmlNodeList tagnodelist = xmldoc.SelectNodes("//item[@id='" + originalID + "']/child::category");
for (int i = 0; i < tagnodelist.Count; i++)
{
dt1.Rows.Add(originalID, tagnodelist[i].ChildNodes[0].Value.ToString());
}
ds1.Tables.Add(dt1);
rpt.DataSource = ds1;
rpt.DataBind();
}
前台的数据绑定代码形同“"<%#DataBinder.Eval(Container.DataItem, "content")%>”,日期格式使用“<%#DataBinder.Eval(Container.DataItem, "datePublished", "{0:s}")%>”,发现一个小问题,原始的rss中的tag每条都是重复显示,要解决这个问题也可以借助Repeater的特性,一隔一显示,只需要在Repeater中添加:
</AlternatingItemTemplate>
里面什么也不填,显示的时候就会一隔一显示,就能达到需要的效果了,这是意外发现的,一般都是用这个改变隔行样式,没想到在这里派上大用场了:)
至此,rss转化成blogML基本成功,还没整体导入,待续。

浙公网安备 33010602011771号