• 4.4 试卷的设计和实现(xml+xlst生成html试卷)






    前面介绍了题库的实现。有了题库就可以出题考试了。下面介绍试卷部分的设计和实现。首先看下这部分的详细类图4-13

    图4-13 试卷模块类图

    首先Question对象包含分值、得分、学生答案和一个表示是否批改过的IsScored属性。并有一个对QuestionContent的引用。Questioin对象代表了某学生一张试卷上的一道题。QuestionContainer类表示的是试卷上的一个大题。比如单选题。一个大题也就是一个QuestionContainer对象,它是就是小题Question对象的集合。以此类推一张试卷也就是一个Paper对象,就是大题QuestionContainer对象的集合。注意QuesitonContainerPaperScore(得分)ScoreValue(分值)都是通过对他们所有子对象Question对象的得分和分值计算得来的。Paper类的AutoScore方法是用来自动改卷的。该方法检查客观题学生答案和标准答案。根据分值给每个Question子对象自动打分。另外注意每个试卷相关的类都有一个GetxxxXML的方法。该方法就是返回对象自身的XML格式字符串。如QuestionContent类的GetContentXML实现如下

    public virtual string GetContentXML()
    {
           StringBuilder builder 
    = new StringBuilder(500);
           builder.Append(
    "<" + QuestionType+ ">");
           builder.Append(
    "<Content><![CDATA[" + Content + "]]></Content>"); 
             builder.Append(
    "<Answer><![CDATA[" + Answer + "]]></Answer>");
            builder.Append(GetChoicesXML());
            builder.Append(
    "</" + QuestionType + ">");

             
    return builder.ToString();
    }

    下面是Question类的GetQuestionXML方法实现
            
    public string GetQuestionXML()
            
    {
                StringBuilder builder 
    = new StringBuilder(500);
                builder.Append(
    "<Question ID=\"" + ID + "\" ScoreValue=\"" + ScoreValue + "\"  Score=\"" + Score + "\" IsScored=\""+IsScored+"\">");
                builder.Append(
    "<StudentAnswer><![CDATA[" + StudentAnswer + "]]></StudentAnswer>");
                builder.Append(Content.GetContentXML());
    //Content为QuestionContent对象
                builder.Append("</Question>");
                
    return builder.ToString();
            }


    注意注释部分说明了对象生成自己的XML格式时候,又是如何包含子对象XML内容。与此类似,QuestionContainerXML生成方法包含了对Question对象的XML的添加。Paper则包含了QuestionContainerXML内容的添加。最后看看调用Paper对象的GetPaperXML方法返回的整张试卷的XML格式内容。为了简化这里假设Paper对象只有一个大题QuestionContainer,单选题。该大题只有一个Question对象。Question对象引用的是一个JianDaContent对象。由此可以看出一个Paper对象是怎样生成自己的XML格式的。先来看看这个Paper对象和其相关子对象的对象图4-14

    图4-14 试卷对象图

    下面是这些对象调用paper对象的GetPaperXML方法返回的XML。注意格式是经过修改过的。这里加上了换行。如果没加的话就会只有一行。

    <Paper PaperId="14" Score="1" ScoreValue="0">
      
    <QuestionContainer Title="单选题" ScoreValue="1" Score="0" Count="1">
        
    <Question ID="61" ScoreValue="1"  Score="0" IsScored="True">
          
    <StudentAnswer><![CDATA[3]]></StudentAnswer>
          
    <JianDa>
            
    <Content><![CDATA[1+1=?]]></Content>
            
    <Answer><![CDATA[2]]></Answer>
          
    </JianDa>
        
    </Question>
      
    </QuestionContainer>
    </Paper>

    为什么要让Paper生成XML格式呢?就是为了下一个目标生成html。在线考试系统是基于web的,最终的试卷要在学生的浏览器中显示。而浏览器能够只能显示html。所以我们必须将Paper对象格式化成html才能显示给学生。当然也可以利用Asp.net的控件绑定来实现,或者直接用Response.Write来向浏览器输出html格式的Paper内容。但是这两种方法都十分的繁琐和难于调试。利用xslt这门专门用来转换文档格式的语言处理这种转换将更简洁灵活。因为XML是平台独立的。所以我们可以先将我们的Paper对象转换成XML格式。下一步就可以利用xlstXML转换成想要的其他的格式。这里对xlst的基础知识不做过多的介绍。来看一个简单的例子来说明试卷是如何从XMLhtml的。还是利用上面已经有的一小段XML。下面给出用到的xslt的实现代码Paper.xsl

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0"
        xmlns:xsl
    ="http://www.w3.org/1999/XSL/Transform">
        
    <xsl:output method="html"/>
        
    <xsl:template match="Paper">
          
    <html>
            
    <body>
               
    <xsl:apply-templates select="QuestionContainer"/>
            
    </body>
          
    </html>
         
        
    </xsl:template>
      
    <xsl:template match="QuestionContainer">
        
    <div class="Title">
          
    <xsl:value-of select="@Title"/>
        
    </div>
        
    <xsl:number format="1."/>
        
    <xsl:apply-templates select="Question"/>
      
    </xsl:template>
      
    <xsl:template match="Question">
        
    <div class="Question">
          
    <xsl:apply-templates select="JianDa"/>
        
    </div> 
      
    </xsl:template>
        
    <xsl:template match="JianDa">
          
    <div class="JianDa">
            
    <div class="Content">
              
    <pre>
                
    <xsl:value-of select="Content"/>
              
    </pre>
            
    </div>
            
    <div class="Input">
              
    <textarea name="{@ID}"  rows="8" style="100%">
                
    <xsl:value-of select="Answer"/>
              
    </textarea>
            
    </div>
          
    </div>
        
    </xsl:template>
      
    </xsl:stylesheet>
    下面代码说明了我们是如何生成html的
        
    public static string TranslateXMLToHtmlString(string XML, string xslFilePath)
        
    {
            XMLReader reader 
    = XMLReader.Create(new StringReader(XML));
            XPathDocument xpathDoc 
    = new XPathDocument(reader);
            XslCompiledTransform xslt 
    = new XslCompiledTransform();
            XsltSettings setting 
    = new XsltSettings();
            setting.EnableScript 
    = true;
            xslt.Load(HttpContext.Current.Server.MapPath(xslFilePath), setting, 
    new XMLUrlResolver());
            StringWriter writer 
    = new StringWriter();
            xslt.Transform(xpathDoc, 
    null, writer);
            
    return writer.ToString();
        }

    该方法有两个参数一个是XML片段字符串。另一个是xsl文件的站点路径。将上面出现的Paper对象的XML片段和Paper.xsl文件的路径作为参数就可以获得生成的html字符串。

    下面是生成的html代码

    <html>
      
    <body>
        
    <div class="Title">单选题</div>1.<div class="Question">
          
    <div class="JianDa">
            
    <div class="Content">
              
    <pre>1+1=?</pre>
            
    </div>
            
    <div class="Input"><textarea name="" rows="8" style="100%">2</textarea></div>
          
    </div>
        
    </div>
      
    </body>
    </html>





  • 相关阅读:
    正则表达式常用收集
    IIS 部署nodejs
    借助svn进行半自动多台服务器上线部署
    快速开发window服务器程序
    sql server 存储过程解密
    EF 剥坑
    测试常规需要测试的东西
    html5本次存储几种方式
    log4net 写日志配置
    js 获取定位信息
  • 原文地址:https://www.cnblogs.com/xhan/p/1202966.html
Copyright © 2020-2023  润新知