• ASP.NET中自动生成XML文件并通过XSLT显示在网页中的方法


    XML是一种很方便的描述数据的方法,其格式也比较接近HTML,因此就有了想把XML直接通过网页的形式显示在浏览器中的想法。但是直接打开XML文件,浏览器是无法解析的,只是把文档的结构原封不动地呈现出来而已。例如,我们有一个学生课程表的文档schedule.xml,用浏览器直接打开是这个样子的。(不过不知道为什么只能在IE中打开,在chrome中打开后无法显示,求教)

    那么如何将XML文档能够以比较容易看懂的方式显示在网页上呢?通过查找资料以后得知有一种XML文档叫做XSLT(EXtensible Stylesheet Language Transform,可扩展样式表语言转换)。详见http://www.w3school.com.cn/xsl/index.asp

    接着就是要选择我们比较容易看懂的形式了。由于是课程表,我们当然首选采用表格的形式展现。但是在确定展现的具体手段时却遇到了瓶颈。究竟是采用课程驱动、还是时间驱动的形式?经过反复试验和调试,终于确定以时间为驱动,采用逐单元格填充的方式进行转换。最终生成的XSLT代码如下(部分):

    1. <?xml version="1.0" encoding="gb2312"?>
    2.  
    3. <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    4.  
    5.   <xsl:template match="/">
    6.     <html>
    7.       <body>
    8.         <h2>我的课程表</h2>
    9.         <table border="1">
    10.           <tr bgcolor="#9acd32">
    11.             <th></th>
    12.             <th align="center">1</th>
    13.             <th align="center">2</th>
    14.             <th align="center">3</th>
    15.             <th align="center">4</th>
    16.             <th align="center">5</th>
    17.             <th align="center">6</th>
    18.             <th align="center">7</th>
    19.             <th align="center">8</th>
    20.             <th align="center">9</th>
    21.             <th align="center">10</th>
    22.             <th align="center">11</th>
    23.           </tr>
    24.           <tr>
    25.             <td>周一</td>
    26.             <xsl:for-each select="schedule/day">
    27.               <xsl:if test="week = '周一'">
    28.                 <td>
    29.                   <xsl:for-each select="course">
    30.                     <xsl:choose>
    31.                       <xsl:when test="time = 1">
    32.                         <xsl:value-of select="name"></xsl:value-of>
    33.                       </xsl:when>
    34.                       <xsl:otherwise>
    35.  
    36.                       </xsl:otherwise>
    37.                     </xsl:choose>
    38.                   </xsl:for-each>
    39.                 </td>
    40.                 ...
    41.             </xsl:if>
    42.             </xsl:for-each>
    43.           </tr>
    44.           ....
    45.           </table>
    46.       </body>
    47.     </html>
    48.   </xsl:template>
    49.  
    50. </xsl:stylesheet>

    接下来就是要将XML和XSLT结合起来了。

    XML输出有两种方式,一种是流的形式,另一种是文件的形式。采用流的方式其实并不适用,因为文档流默认是填充在一个文件的前面的,如果是采用HTML或者ASPX等文件,会影响整个文档的结构。因此采用文件的方法,即将所有XML节点写入一个文件,并保存在服务器上。当然,随着用户数量的增多,生成的XML文件必然会越来越多,所以还得增加一个定期删除的机制,这个不在我们讨论范围之内因此不再赘述。

    之前从数据库中读出数据并写入一个List的方法如下:

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Web;
    5. using System.Configuration;
    6. using System.Xml;
    7. using System.Web.UI;
    8. using System.Web.UI.WebControls;
    9.  
    10. namespace CampusSystem
    11. {
    12.     public enum Weekday { 周一, 周二, 周三, 周四, 周五 };
    13.  
    14.     public struct CourseToXML
    15.     {
    16.         public string course_id;
    17.         public string name;
    18.         public Weekday week;
    19.         public string[] times;
    20.     }
    21.  
    22.     public static class ScheduleMaker
    23.     {
    24.         static string connString = ConfigurationManager.ConnectionStrings["CampusConnectionString"].ConnectionString;
    25.         static CampusDBDataContext db = new CampusDBDataContext(connString);
    26.  
    27.         public static List<CourseToXML> MakeScheduleList(string uid)
    28.         {
    29.             string course_id = string.Empty;
    30.             string name = string.Empty;
    31.             string allTime = string.Empty;
    32.  
    33.             CourseToXML ctx = new CourseToXML();
    34.             List<CourseToXML> ctxl = new List<CourseToXML>();
    35.  
    36.             var mySchedule = from ms in db.Schedule where ms.student_id == uid select ms.course_id;
    37.             foreach (string cid in mySchedule)
    38.             {
    39.                 var courseInfo = from ci in db.Course where ci.course_id == cid select new { ci.course_id, ci.name, ci.time };
    40.                 foreach (var c in courseInfo)
    41.                 {
    42.                     course_id = c.course_id;
    43.                     name = c.name;
    44.                     allTime = c.time;
    45.                     string[] oneTimes = allTime.Split(';');
    46.                     foreach (string oneTime in oneTimes)
    47.                     {
    48.                         string[] weekAndTime = oneTime.Split(',');
    49.                         string week = weekAndTime[0];
    50.                         string[] times = weekAndTime[1].Split('.');
    51.  
    52.                         ctx.course_id = course_id;
    53.                         ctx.name = name;
    54.  
    55.                         ctx.times = times;
    56.                         switch (week)
    57.                         {
    58.                             case "周一":
    59.                                 ctx.week = Weekday.周一;
    60.                                 break;
    61.                             case "周二":
    62.                                 ctx.week = Weekday.周二;
    63.                                 break;
    64.                             case "周三":
    65.                                 ctx.week = Weekday.周三;
    66.                                 break;
    67.                             case "周四":
    68.                                 ctx.week = Weekday.周四;
    69.                                 break;
    70.                             case "周五":
    71.                                 ctx.week = Weekday.周五;
    72.                                 break;
    73.                             default:
    74.                                 break;
    75.                         }
    76.  
    77.                         ctxl.Add(ctx);
    78.                     }
    79.                 }
    80.             }
    81.             ctxl.Sort((CourseToXML ctxA, CourseToXML ctxB) =>
    82.             {
    83.                 if (ctxA.week == ctxB.week)
    84.                     return ctxA.times[0].CompareTo(ctxB.times[0]);
    85.                 else
    86.                     return ctxA.week.CompareTo(ctxB.week);
    87.             });
    88.  
    89.             return ctxl;
    90.  
    91.         }
    92.    }
    93. }

    需要查询的页面schedule.aspx如下:(前提是需要有一个存放生成后的html文档的html文件。)

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Web;
    5. using System.Web.UI;
    6. using System.Web.UI.WebControls;
    7. using System.Xml;
    8. using System.Xml.Xsl;
    9.  
    10. namespace CampusSystem
    11. {
    12.     public partial class schedule : System.Web.UI.Page
    13.     {
    14.         string uid;
    15.  
    16.         protected void Page_Load(object sender, EventArgs e)
    17.         {
    18.             uid = GetUID();
    19.             List<CourseToXML> list = ScheduleMaker.MakeScheduleList(uid); //读出数据库中数据
    20.             MakeScheduleXML(list, uid); //生成XML文档
    21.  
    22.             XslCompiledTransform xslt = new XslCompiledTransform();
    23.             xslt.Load(Server.MapPath("schedule.xsl"));
    24.             xslt.Transform(Server.MapPath("Schedule/schedule_" + uid + ".xml"), Server.MapPath("schedule.html"));
    25.        //这个方法就是将指定的XML文件通过指定的XSL文件转换以后生成到一个指定的html文件中。
    26.  
    27.             Response.Redirect("schedule.html");
    28.         }
    29.  
    30.         private string GetUID()
    31.         {
    32.             string uid = string.Empty;
    33.             HttpCookie cookie = Request.Cookies["LOGIN"];
    34.             if (cookie != null) // 若Cookie不为空,则采用cookie
    35.             {
    36.                 uid = cookie["uid"];
    37.             }
    38.             else // 否则采用Session
    39.             {
    40.                 uid = (string)Session["uid"];
    41.             }
    42.             return uid;
    43.         }
    44.  
    45.         protected void MakeScheduleXML(List<CourseToXML> list, string uid)
    46.         {
    47.             XmlDocument xmlDoc = new XmlDocument();
    48.             XmlDeclaration decl = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null);
    49.             xmlDoc.AppendChild(decl);
    50.  
    51.             XmlElement root = xmlDoc.CreateElement("schedule");
    52.             xmlDoc.AppendChild(root);
    53.  
    54.  
    55.             for (int weekday = 0; weekday < 5; weekday++)
    56.             {
    57.                 XmlNode nodeDay = xmlDoc.CreateElement("day");
    58.                 root.AppendChild(nodeDay);
    59.                 XmlNode week = null;
    60.                 switch (weekday)
    61.                 {
    62.                     case 0:
    63.                         week = xmlDoc.CreateElement("week");
    64.                         week.InnerText = Weekday.周一.ToString();
    65.                         break;
    66.                     case 1:
    67.                         week = xmlDoc.CreateElement("week");
    68.                         week.InnerText = Weekday.周二.ToString();
    69.                         break;
    70.                     case 2:
    71.                         week = xmlDoc.CreateElement("week");
    72.                         week.InnerText = Weekday.周三.ToString();
    73.                         break;
    74.                     case 3:
    75.                         week = xmlDoc.CreateElement("week");
    76.                         week.InnerText = Weekday.周四.ToString();
    77.                         break;
    78.                     case 4:
    79.                         week = xmlDoc.CreateElement("week");
    80.                         week.InnerText = Weekday.周五.ToString();
    81.                         break;
    82.                     default:
    83.                         break;
    84.                 }
    85.                 nodeDay.AppendChild(week);
    86.  
    87.                 foreach (CourseToXML ctx in list)
    88.                 {
    89.                     XmlNode course = null;
    90.                     if (weekday == (int)(ctx.week))
    91.                     {
    92.                         course = xmlDoc.CreateElement("course");
    93.                         foreach (string t in ctx.times)
    94.                         {
    95.                             XmlNode time = xmlDoc.CreateElement("time");
    96.                             time.InnerText = t;
    97.                             course.AppendChild(time);
    98.                         }
    99.                         XmlNode name = xmlDoc.CreateElement("name");
    100.                         name.InnerText = ctx.name;
    101.                         course.AppendChild(name);
    102.                         nodeDay.AppendChild(course);
    103.                     }
    104.  
    105.                 }
    106.             }
    107.  
    108.             xmlDoc.Save(Server.MapPath("Schedule/schedule_" + uid + ".xml"));
    109.         }
    110.     }
    111. }

    运行以后自动返回所生成的html文档,就能看到结果了。

    虽然还略显简陋就是了,当然,这个可以通过css来控制,这里也不再赘述。

    总结

    为了完成这个任务,采取了一切能想到的方法。包括XMLDocument,XSLT转换,LINQ,泛型,Lambda表达式,还有XML本身的设计等等,很多知识的大综合。也是对自己学习能力和综合应用能力一个提高。真正的成就感就是在这样不断解决问题的过程中产生的,也是给了我继续把项目做好的动力。

  • 相关阅读:
    WPF多语言支持
    解决 OpenCV with CUDA 编译提示缺少 nvcuvid.h 的问题
    ios adi ADBannerView 无法修改 宽度
    ios 判断横竖屏的方法
    Core data 数据同步
    常用的sql脚本(陆续更新)
    高晓松:不买房,买梦想
    (转贴)关于多线程执行显示进度条的实例!
    如何快速创建大文件
    利用Adobe Acrobat 7.0 Professional 自带的导出图片的功能(转)
  • 原文地址:https://www.cnblogs.com/ryuasuka/p/3105362.html
Copyright © 2020-2023  润新知