XML是一种很方便的描述数据的方法,其格式也比较接近HTML,因此就有了想把XML直接通过网页的形式显示在浏览器中的想法。但是直接打开XML文件,浏览器是无法解析的,只是把文档的结构原封不动地呈现出来而已。例如,我们有一个学生课程表的文档schedule.xml,用浏览器直接打开是这个样子的。(不过不知道为什么只能在IE中打开,在chrome中打开后无法显示,求教)
接着就是要选择我们比较容易看懂的形式了。由于是课程表,我们当然首选采用表格的形式展现。但是在确定展现的具体手段时却遇到了瓶颈。究竟是采用课程驱动、还是时间驱动的形式?经过反复试验和调试,终于确定以时间为驱动,采用逐单元格填充的方式进行转换。最终生成的XSLT代码如下(部分):
<?xml version="1.0" encoding="gb2312"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template
match="/">
<html>
<body>
<h2>我的课程表</h2>
<table
border="1">
<tr
bgcolor="#9acd32">
<th></th>
<th
align="center">1</th>
<th
align="center">2</th>
<th
align="center">3</th>
<th
align="center">4</th>
<th
align="center">5</th>
<th
align="center">6</th>
<th
align="center">7</th>
<th
align="center">8</th>
<th
align="center">9</th>
<th
align="center">10</th>
<th
align="center">11</th>
</tr>
<tr>
<td>周一</td>
<xsl:for-each
select="schedule/day">
<xsl:if
test="week = '周一'">
<td>
<xsl:for-each
select="course">
<xsl:choose>
<xsl:when
test="time = 1">
<xsl:value-of
select="name"></xsl:value-of>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</td>
...
</xsl:if>
</xsl:for-each>
</tr>
....
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
XML输出有两种方式,一种是流的形式,另一种是文件的形式。采用流的方式其实并不适用,因为文档流默认是填充在一个文件的前面的,如果是采用HTML或者ASPX等文件,会影响整个文档的结构。因此采用文件的方法,即将所有XML节点写入一个文件,并保存在服务器上。当然,随着用户数量的增多,生成的XML文件必然会越来越多,所以还得增加一个定期删除的机制,这个不在我们讨论范围之内因此不再赘述。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Configuration;
using System.Xml;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace CampusSystem
{
public
enum Weekday { 周一, 周二, 周三, 周四, 周五 };
public
struct CourseToXML
{
public
string course_id;
public
string name;
public Weekday week;
public
string[] times;
}
public
static
class ScheduleMaker
{
static
string connString = ConfigurationManager.ConnectionStrings["CampusConnectionString"].ConnectionString;
static CampusDBDataContext db = new CampusDBDataContext(connString);
public
static List<CourseToXML> MakeScheduleList(string uid)
{
string course_id = string.Empty;
string name = string.Empty;
string allTime = string.Empty;
CourseToXML ctx = new CourseToXML();
List<CourseToXML> ctxl = new List<CourseToXML>();
var mySchedule = from ms in db.Schedule where ms.student_id == uid select ms.course_id;
foreach (string cid in mySchedule)
{
var courseInfo = from ci in db.Course where ci.course_id == cid select new { ci.course_id, ci.name, ci.time };
foreach (var c in courseInfo)
{
course_id = c.course_id;
name = c.name;
allTime = c.time;
string[] oneTimes = allTime.Split(';');
foreach (string oneTime in oneTimes)
{
string[] weekAndTime = oneTime.Split(',');
string week = weekAndTime[0];
string[] times = weekAndTime[1].Split('.');
ctx.course_id = course_id;
ctx.name = name;
ctx.times = times;
switch (week)
{
case "周一":
ctx.week = Weekday.周一;
break;
case "周二":
ctx.week = Weekday.周二;
break;
case "周三":
ctx.week = Weekday.周三;
break;
case "周四":
ctx.week = Weekday.周四;
break;
case "周五":
ctx.week = Weekday.周五;
break;
default:
break;
}
ctxl.Add(ctx);
}
}
}
ctxl.Sort((CourseToXML ctxA, CourseToXML ctxB) =>
{
if (ctxA.week == ctxB.week)
return ctxA.times[0].CompareTo(ctxB.times[0]);
else
return ctxA.week.CompareTo(ctxB.week);
});
return ctxl;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using System.Xml.Xsl;
namespace CampusSystem
{
public partial class schedule : System.Web.UI.Page
{
string uid;
protected
void Page_Load(object sender, EventArgs e)
{
uid = GetUID();
List<CourseToXML> list = ScheduleMaker.MakeScheduleList(uid); //读出数据库中数据
MakeScheduleXML(list, uid); //生成XML文档
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(Server.MapPath("schedule.xsl"));
xslt.Transform(Server.MapPath("Schedule/schedule_" + uid + ".xml"), Server.MapPath("schedule.html"));
//这个方法就是将指定的XML文件通过指定的XSL文件转换以后生成到一个指定的html文件中。
Response.Redirect("schedule.html");
}
private
string GetUID()
{
string uid = string.Empty;
HttpCookie cookie = Request.Cookies["LOGIN"];
if (cookie != null) // 若Cookie不为空,则采用cookie
{
uid = cookie["uid"];
}
else
// 否则采用Session
{
uid = (string)Session["uid"];
}
return uid;
}
protected
void MakeScheduleXML(List<CourseToXML> list, string uid)
{
XmlDocument xmlDoc = new XmlDocument();
XmlDeclaration decl = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null);
xmlDoc.AppendChild(decl);
XmlElement root = xmlDoc.CreateElement("schedule");
xmlDoc.AppendChild(root);
for (int weekday = 0; weekday < 5; weekday++)
{
XmlNode nodeDay = xmlDoc.CreateElement("day");
root.AppendChild(nodeDay);
XmlNode week = null;
switch (weekday)
{
case 0:
week = xmlDoc.CreateElement("week");
week.InnerText = Weekday.周一.ToString();
break;
case 1:
week = xmlDoc.CreateElement("week");
week.InnerText = Weekday.周二.ToString();
break;
case 2:
week = xmlDoc.CreateElement("week");
week.InnerText = Weekday.周三.ToString();
break;
case 3:
week = xmlDoc.CreateElement("week");
week.InnerText = Weekday.周四.ToString();
break;
case 4:
week = xmlDoc.CreateElement("week");
week.InnerText = Weekday.周五.ToString();
break;
default:
break;
}
nodeDay.AppendChild(week);
foreach (CourseToXML ctx in list)
{
XmlNode course = null;
if (weekday == (int)(ctx.week))
{
course = xmlDoc.CreateElement("course");
foreach (string t in ctx.times)
{
XmlNode time = xmlDoc.CreateElement("time");
time.InnerText = t;
course.AppendChild(time);
}
XmlNode name = xmlDoc.CreateElement("name");
name.InnerText = ctx.name;
course.AppendChild(name);
nodeDay.AppendChild(course);
}
}
}
xmlDoc.Save(Server.MapPath("Schedule/schedule_" + uid + ".xml"));
}
}
}
为了完成这个任务,采取了一切能想到的方法。包括XMLDocument,XSLT转换,LINQ,泛型,Lambda表达式,还有XML本身的设计等等,很多知识的大综合。也是对自己学习能力和综合应用能力一个提高。真正的成就感就是在这样不断解决问题的过程中产生的,也是给了我继续把项目做好的动力。
请发表评论