经常上csdn的朋友肯定会感觉到发帖子后很快的就会把新帖子显示出来,并且它的帖子是xml文件,根据我的分析,csdn采用的这样一种方法,发表帖子的时候先将回复的内容写入数据库,同时检查指定目录例如xmfiles下有没有帖子id为文件名的xml文件,如果没有,建立新的xml文件,写入帖子id,当前用户id,帖子标题,作者等一些信息,然后利用一个xslt将这个xml文件显示出来,需要指出的是xslt并不是只显示了帖子的内容,它在在其中包含了一个iframe,里面就是发表回复内容的表单,用户发表回复其实就是打开指定的xml文件,增加新的接点,然后保存,保存后直接刷新主xml文件即可,这样一来读帖子显示的时候就不用根据id从数据库里找帖子内容,然后再将数据读出来,而是只打开一个本地文件,并且解释样式的工作是利用xslt交给浏览器来解释,所以速度会快很多,也减轻了服务器的压力。原理基本上是这样,下面列出几个关键问题并附上代码:
1如何将帖子id传递给iframe中的表单
将id写进xml文件,利用xstl将id的值写进一个hidden,在iframe中的表单中利用document.all("topicid").value = top.document.all("topicid").value;读出,原因是有可能用户会同时读几篇文章,所以不能用session,而是采用这种方式来保存状态。
2如何得到表单中的hidden的值
因为需要得到form里的值,所以在服务端处理前必须submit(),需要指出的是不能够在body onload里接受设置hidden的值,这样submit的值会是一个空值,而必须在提交窗体后执行段js取得hidden的值,接着马上submit!
3刷新xml文件的时候不能简单的用location.href=location.href之类的语句,而要用location.reload(),不然新增加的接点必须手动刷新后才能显示出来,原因是浏览器会认为是同一个文件,而输出的是缓存,csdn的做法是在location后面加一个变化的字符串,例如535.xml?temp=34557这样的形式,后面的34557是程序生成的一个随时间会变化的字符串,这样浏览器就会理解是不同的文件,而去重新载入。
4考虑浏览器对xml的支持
由于netscape等一些其他的浏览器对xml的支持不是很好,ie也只有5.5以上的版本才能很好的支持,所以必须检测浏览器,然后进行必要的服务器端转换!
1 showarticle.aspx接受请求的aspx页面:判断xml文件是否存在,浏览器类型等
1
using System;
2
using System.Collections;
3
using System.ComponentModel;
4
using System.Data;
5
using System.Drawing;
6
using System.Web;
7
using System.Web.SessionState;
8
using System.Web.UI;
9
using System.Web.UI.WebControls;
10
using System.Web.UI.HtmlControls;
11
using System.IO;
12
using Uptoec.Business ;
13
using Uptoec.Common ;
14
using Uptoec.DataAccess ;
15
using System.Data .SqlClient ;
16
using System.Xml.Xsl ;
17
using System.Xml ;
18
using System.Xml .XPath;
19
using System.Text ;
20
namespace ecArticle.BackWeb.test
21

{
22
/**//// <summary>
23
/// showarticlel 的摘要说明。
24
/// </summary>
25
public class showarticlel : System.Web.UI.Page
26
{
27
28
private string fileName;
29
private string id;
30
private string author;
31
private string postman;
32
private string title;
33
private string xsltFile;
34
private string xsltFile1;
35
private void InitializeComponent()
36
{
37
this.Load += new System.EventHandler(this.Page_Load);
38
39
}
40
41
42
private void Page_Load(object sender, System.EventArgs e)
43
{
44
//得到文章id
45
id =Request.QueryString ["id"].ToString ();
46
fileName ="xmlFiles\\" + id + ".xml";
47
fileName =System.Web .HttpContext.Current .Server .MapPath(fileName);
48
xsltFile = "xmlFiles\\message.xsl";
49
xsltFile =System.Web .HttpContext.Current .Server .MapPath(xsltFile);
50
51
xsltFile1 = "xmlFiles\\message1.xsl";
52
xsltFile1 =System.Web .HttpContext.Current .Server .MapPath(xsltFile1);
53
54
55
56
//得到用户名
57
postman =(string)Session["postman"];
58
59
//判断xml文件时候存在,否则创建xml文件
60
61
if(!File.Exists(fileName))
62
{
63
//创建xml文件;
64
65
FileStream fs =File.Create(fileName);
66
fs.Close ();
67
68
//从数据库得到文章的标题,作者,等一些信息
69
70
ArticleInfo article = new ArticleSystem().GetArticleById(Convert.ToInt32 (id));
71
author = article.Author ;
72
title = article.Title ;
73
74
XmlTextWriter writer = new XmlTextWriter((fileName), Encoding.UTF8);
75
76
//开始创建接点
77
writer.WriteStartDocument();
78
String PItext="type='text/xsl' href='message.xsl'";
79
writer.WriteProcessingInstruction("xml-stylesheet", PItext);
80
81
writer.WriteStartElement("replylist");
82
writer.WriteElementString("topicid",id);
83
writer.WriteElementString("author",author);
84
writer.WriteElementString("title",title);
85
writer.WriteEndElement();
86
writer.WriteEndDocument();
87
writer.Close ();
88
//结束建立xml文件
89
}
90
91
92
//检测浏览器是否支持xml
93
94
if(!(Convert.ToDouble(Request.Browser.Version)>=5.5))
95
{
96
XslTransform xslt = new XslTransform();
97
98
xslt.Load(xsltFile1);
99
XPathDocument xpathdocument = new
100
XPathDocument(fileName);
101
XmlTextWriter writer = new
102
XmlTextWriter(Response.OutputStream, Encoding.UTF8);
103
104
writer.Formatting=Formatting.Indented;
105
106
xslt.Transform(xpathdocument,null,writer,null);
107
108
}
109
else
{
110
111
this.Response.Redirect ("xmlFiles/" + id + ".xml");
112
113
114
}
115
116
117
}
118
Web 窗体设计器生成的代码#region Web 窗体设计器生成的代码
119
override protected void OnInit(EventArgs e)
120
{
121
//
122
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
123
//
124
this.Load += new System.EventHandler(this.Page_Load);
125
base.OnInit(e);
126
}
127
128
/**//// <summary>
129
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
130
/// 此方法的内容。
131
/// </summary>
132
133
#endregion
134
}
135
}
136
2iframe中发表留言的post.aspx
1
using System;
2
using System.Collections;
3
using System.ComponentModel;
4
using System.Data;
5
using System.Drawing;
6
using System.Xml;
7
using System.Web;
8
using System.Web.SessionState;
9
using System.Web.UI;
10
using System.Web.UI.WebControls;
11
using System.Web.UI.HtmlControls;
12
13
namespace ecArticle.BackWeb.test
14

{
15
/**//// <summary>
16
/// xml 的摘要说明。
17
/// </summary>
18
public class xml : System.Web.UI.Page
19
{
20
protected System.Web.UI.WebControls.TextBox content;
21
protected System.Web.UI.HtmlControls.HtmlForm form1;
22
protected System.Web.UI.HtmlControls.HtmlInputButton Button1;
23
private string replytext;
24
private string postman;
25
private string id;
26
private string posttime;
27
private string xFileName;
28
private void Page_Load(object sender, System.EventArgs e)
29
30
{
31
32
33
}
34
35
Web 窗体设计器生成的代码#region Web 窗体设计器生成的代码
36
override protected void OnInit(EventArgs e)
37
{
38
//
39
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
40
//
41
InitializeComponent();
42
base.OnInit(e);
43
}
44
45
/**//// <summary>
46
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
47
/// 此方法的内容。
48
/// </summary>
49
private void InitializeComponent()
50
{
51
this.Button1.ServerClick += new System.EventHandler(this.Button1_ServerClick);
52
this.Load += new System.EventHandler(this.Page_Load);
53
54
}
55
#endregion
56
57
58
59
60
private void Button1_ServerClick(object sender, System.EventArgs e)
61
{
62
//需要根据hidden的值取得对应的xml文件名和作者的信息
63
id =Request.Form["topicid"];
64
xFileName = "xmlFiles/" + id + ".xml";
65
//得到用户信息
66
67
replytext=content.Text ;
68
posttime =System.DateTime .Now .ToLongTimeString();
69
70
string waittext ="正在生成静态页面,请稍后!";
71
//写入节点
72
Response.Write (waittext);
73
74
AddNode(xFileName,replytext,postman,posttime);
75
76
string ll ="<script language ='javascript'>top.location.reload()";
77
78
ll +="</script>";
79
Response.Write (ll);
80
81
82
83
84
}
85
86
87
88
89
private void AddNode(string xmlFile,string content,string postman,string ptime)
90
91
{
92
//将数据写入数据库
93
94
XmlDocument xmldoc = new XmlDocument ();
95
string filePath= System.Web .HttpContext.Current .Server.MapPath(xmlFile);
96
xmldoc.Load(filePath);
97
XmlNode root = xmldoc.DocumentElement ;
98
//开始创建新节点
99
100
XmlNode reply =xmldoc.CreateElement("reply");
101
102
XmlNode contentNode = xmldoc.CreateElement ("content");
103
104
XmlNode postmanNode = xmldoc.CreateElement ("postman");
105
106
XmlNode posttimeNode = xmldoc.CreateElement ("posttime");
107
//给各子节点赋值
108
contentNode.InnerXml="<![CDATA[" + content + "]]>";
109
postmanNode.InnerText = Session["postman"].ToString ();
110
posttimeNode .InnerText =ptime;
111
112
//将3个子节点添加到回复父节点
113
reply.AppendChild (contentNode);
114
reply.AppendChild (postmanNode);
115
reply.AppendChild (posttimeNode);
116
root.AppendChild(reply);
117
xmldoc.Save (filePath);
118
119
120
}
121
122
}
123
}/**//*生成随机数------
124
* -----------------------------------
125
Random rdm1 = new Random(unchecked((int)DateTime.Now.Ticks));
126
string r1 =rdm1.Next(10).ToString ();
127
Random rdm2 = new Random(rdm1.Next(10));
128
string r2= rdm2.Next(10).ToString ();
129
130
string time = System.DateTime.Now.ToShortTimeString();
131
time = time.Replace (":","");
132
string sec = System.DateTime.Now.Second.ToString ();
133
time =r1 + time + sec + r2;//生成随机数完毕--------------------------------------
134
string ll ="<script language ='javascript'>top.location.href='1.xml?temp=.";
135
*/
136
137
3 post.aspx的html代码
1
<%@ Page CodeBehind="post.aspx.cs" Language="c#" AutoEventWireup="false" Inherits="ecArticle.BackWeb.test.xml" %>
2
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
3
<HTML>
4
<HEAD>
5
<title>帮助</title>
6
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
7
<LINK href="style.css" type="text/css" rel="stylesheet">
8
<script language="javascript">
9
function sethidden()
10
{
11
12
document.all("topicid").value = top.document.all("topicid").value;
13
form1.submit();
14
15
}
16
</script>
17
</HEAD>
18
<body aLink="#000000" link="#000000" topMargin="2" ms_positioning="GridLayout">
19
<TABLE height="186" cellSpacing="0" cellPadding="0" width="378" border="0" ms_2d_layout="TRUE">
20
<TR vAlign="top">
21
<TD width="10" height="2"></TD>
22
<TD width="368"></TD>
23
</TR>
24
<TR vAlign="top">
25
<TD height="184"></TD>
26
<TD>
27
<TABLE height="183" cellSpacing="0" cellPadding="0" width="367" border="0">
28
<form id="form1" name="form1" method="post" runat="server">
29
<TBODY>
30
<tr>
31
<td align="left"></td>
32
</tr>
33
<tr>
34
<td align="left"></td>
35
</tr>
36
<tr>
37
<td align="left"><asp:textbox id="content" runat="server" Width="360px" Height="96px" EnableViewState="False"></asp:textbox></td>
38
</tr>
39
<tr>
40
<INPUT type="hidden" name="topicid">
41
<td><input id="Button1" onclick="sethidden();" type="button" value="我要疯了" runat="server" Text="提交查询内容">
42
</td>
43
</tr>
44
</TR>
45
</FORM></TABLE>
46
</TD></TR></TBODY></TD></TR></TBODY></FORM></TD></TR></TBODY></TABLE></TABLE></TABLE>
47
</body>
48
</HTML>
49
4 xml文件和xslt文件
1
<?xml version="1.0" encoding="utf-8"?>
2
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
3
4
<xsl:template match="/">
5
<html>
6
<title>AAAAA</title>
7
<body>
8
<h1><xsl:value-of select="replylist/topicid"/></h1>
9
<h1><xsl:value-of select="replylist/title"/></h1>
10
<h1><xsl:value-of select="replylist/author"/></h1>
11
<table width="75%" height="85" border="0" align="center" cellpadding="0" cellspacing="1" bgcolor="#333333">
12
<tr>
13
<td height="20" bgcolor="#FFFFFF">name</td>
14
<td align="right" bgcolor="#FFFFFF">posttime</td>
15
</tr>
16
<xsl:apply-templates select="replylist/reply">
17
</xsl:apply-templates>
18
</table>
19
<xsl:element name="input">
20
<xsl:attribute name="type">hidden</xsl:attribute>
21
<xsl:attribute name="name">topicid</xsl:attribute>
22
<xsl:attribute name="value"><xsl:value-of select="replylist/topicid"/></xsl:attribute>
23
</xsl:element>
24
25
<iframe name="post" src="../post.aspx" scrolling="no" MARGINHEIGHT="0" width="75%" MARGINWIDTH="0" FRAMESPACING="0" align="center" height="500" FRAMEBORDER="0"/>
26
</body>
27
</html>
28
</xsl:template>
29
30
<xsl:template match="reply">
31
<tr>
32
<td height="20" bgcolor="#FFFFFF">
33
<xsl:value-of select="postman"/>
34
</td>
35
<td align="right" bgcolor="#FFFFFF">
36
<xsl:value-of select="posttime"/>
37
</td>
38
</tr>
39
<tr bgcolor="#FFFFFF">
40
<td height="41" colspan="2">
41
<xsl:value-of select="content"/>
42
</td>
43
</tr>
44
</xsl:template>
45
</xsl:stylesheet>
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type='text/xsl' href='message.xsl'?>
<replylist>
<topicid>251</topicid>
<author>yeqi</author>
<title>我爱你</title>
</replylist>