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





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

图4-13 试卷模块类图

首先 Question 对象包含分值、得分、学生答案和一个表示是否批改过的 IsScored 属性。并有一个对 QuestionContent 的引用。 Questioin 对象代表了某学生一张试卷上的一道题。 QuestionContainer 类表示的是试卷上的一个大题。比如单选题。一个大题也就是一个 QuestionContainer 对象,它是就是小题 Question 对象的集合。以此类推一张试卷也就是一个 Paper 对象,就是大题 QuestionContainer 对象的集合。注意 QuesitonContainer Paper Score( 得分 ) 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 ="width: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 ="width:100%" > 2 </ textarea ></ div >
      
</ div >
    
</ div >
  
</ body >
</ html >





转载于:https://www.cnblogs.com/xhan/archive/2008/05/20/1202966.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值