论文部分内容阅读
摘 要:本文主要讨论在基于XML的试题库系统中,通过XSL转换方便快速地输出试卷的方法和实现过程。通过此方法,不仅可以很好地控制试卷的版面设计,而且使程序、试卷数据和样式分离,在输出试卷时具有很大的灵活性,可以输出多种格式的试卷。
关键词:试卷 输出 格式 XML XSL FOP
中图分类号:G434 文献标识码:A 文章编号:1673-8454(2007)10-0070-03
一、引言
随着计算机技术在教学中的应用越来越广泛,试题库系统的建设也越来越重要。在试题库系统中,很重要的一个功能是试卷输出。由于Office等软件具备所见即所得、易于操作等特点,许多试题库系统基于这类软件对试卷进行版面设计及输出。[1] 这种方式虽然易于实现,但在使用时不能脱离软件独立运行,在没有安装这类软件的计算机上无法使用或是不能输出试卷,而且输出试卷的格式也受限于其依赖的编辑软件。另一方面,随着Internet的广泛应用,基于XML的网络试题库系统越来越多,这些系统更多地关注于试题的存储与传输,对所生成试卷的输出问题很少提及。[2] 而在实际试题库应用中,对试卷输出并打印是有很大需求的。
由此,我们在研发大学英语试题库系统时对试卷输出进行了有益的尝试,实现了基于XML的试题库试卷的快速灵活的输出。本文主要讨论XML试题库试卷的输出过程及具体实现。
二、XML格式转换的流程
由于XML格式不仅可扩展性强、内容与样式分离、以文本格式进行存储和传输、具有良好的开放性、跨平台性和可操作性[3],而且与Word格式相比,采用XML格式来表示试卷、试题、参考答案文件有很多优点,更适合试题库的网络应用的需求。[4] 所以我们采用XML作为试题库系统中试题和试卷的存储格式。这样,试卷输出的关键是将由XML表示的试卷文档转换成其他格式的文档供修改或打印。其转换过程如图1所示:
图1 XML格式转换过程
XML源文档以XML格式存储了要转换输出的试卷内容。可扩展标记语言XML,可以使用自己创建的标记存储数据。在我们所开发的试题库系统中,试题和试卷都是基于XML存储的,其中音频和图片也可以编码后以XML格式存储。[5]
XSL样式表定义了输出的版面设计和对输出内容的选取。可扩展样式表语言XSL由XSLT、XPath和XSL-FO组成。[6] 可扩展样式表语言转换XSLT提供一套规则,用于将一组元素描述的XML数据转换为另一组元素描述的文档,或者将该数据转换为一种自定义的文本格式。在这里,我们通过XSLT,将用XML表示的试卷转换为由XSL-FO表示的格式化对象。XPath是XML路径语言,用于对XML文档中的元素进行定位,由XSLT使用。格式化对象的可扩展样式表语言XSL-FO定义了在屏幕或纸张或其他媒介上如何显示数据。在我们的试题库系统中,输出的试卷排版布局由XSL-FO表示。
处理器读取XML源文档和XSL样式表,并转换输出PDF、RTF、HTML等格式的文档。在多种转换处理工具中,我们选择了FOP。FOP是Apache XML Project提供的一种转换工具,使用它可以便捷地将XML文档转换为PDF、RTF等格式。[7] 但是由于FOP对于PDF和RTF的支持不完全相同,所在要针对PDF和RTF对样式表分别作修改,才能输出美观的文档。
由图1可以看出,整个转换过程就是将表示内容的XML文档和表示样式的XSL文档提交给处理器,经处理器转换得到输出结果为PDF、RTF等格式的文档。
三、基于XML的试卷输出实现
在输出试卷时,我们首先将试题库组卷模块中生成的试卷保存为XML文档,然后根据要输出的试卷格式选择相应的样式表,把XML文档和样式表交给处理程序FOP处理后将试卷输出为PDF或RTF格式。本节先介绍我们采用的试卷结构,然后介绍对应的样式表,最后就实现过程中遇到的问题给出解决方案。
1.试卷结构
在本试题库系统中,试题和试卷都存储为XML结构。通过扩展XML标记,定义了适合本题库系统的试题和试卷XML结构。试卷的具体结构为:
<paper name="Test Paper" score="100">
<part type="Listening" id="1">
<section direction="Section Direction" type="Statements" id="1">
<assessmentItem id="1">
……
</assessmentItem>
<assessmentItem id="2">
……
</assessmentItem>
</section>
<section direction="Section Direction" type="Short Conversations" id="2">
<assessmentItem type="SentenceListening" id="1" />
……
</section>
<part type="Reading Comprehension" id="2">
……
</part>
……
</paper>
试卷(Paper)由几个部分(Part)组成,每个部分由一节或几节(Section)组成,每一节由若干试题(Item)组成。对于试题,由于题型的不同,包含不同的元素。基本的试题结构为:
<assessmentItem type="ReadingChoice" id="2">
<content >
<question id="36">
<prompt>The passage is meant to ______.</prompt>
<choices>
<choice id="A" />
<choice id="B" />
<choice id="C" />
<choice id="D" />
</choices>
<answer><value>A</value></answer>
</question>
<question id="37">
</question>
</assessmentItem>
试题的主要元素有题干、问题、答案。对于听力题,需要有声音文件和听力脚本。
2.样式表
与试卷对应的XSLT样式表结构为:
<xsl:stylesheet>
<xsl:template match="/">
<fo:root >
<fo:layout-master-set>
<fo:simple-page-master master-name="TestBanks">
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="TestBanks">
<fo:flow flow-name="xsl-region-body">
<fo:block>
<xsl:call-template name="paper_test"/>
</fo:block>
<fo:block>
<xsl:call-template name="paper_answersheet"/>
</fo:block>
<fo:block>
<xsl:call-template name="paper_key"/>
</fo:block>
<fo:block>
<xsl:call-template name="paper_Script_of_Listening"/>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
在试卷的XML文档中,题目内容、答案以及听力原文是在一起的,但在输出的试卷中,要将其分成三个不同的部分,而且试卷输出的同时要输出答题纸,所以要对输入的XML试卷进行四遍扫描,每一遍分别应用不同的模板,取出所需要处理的信息进行转换输出。
试题册模板首先输出试卷名称和注意事项等内容,然后遍历试卷中的每一部分节点,根据每部分的名称来应用对应的部分模板。每部分的模板先输出标题,然后遍历本部分中的所有节,对不同的节应用对应的节模板。节模板先输出节标题和本节的答题要求,然后遍历本节的所有试题,应用对应的试题模板对试题内容进行输出。对于不同的试题,根据其所具有的元素,选择要在试题册上显示的内容输出。
答题卡模板、答案模板和听力脚本模板同样采用上面按层次调用的方法,逐步应用部分、节和试题模板,输出自己所需要呈现的内容。所有的内容都输出到fo:block内容块中。
3.转换过程中遇到的问题及解决办法
设计好样式表以后,就可以使用FOP对XML试卷进行转换输出了。在输出过程中,笔者在字体、试卷中的特殊格式等方面遇到以下主要问题需要解决。
(1)字体设置
由于试卷上大部分内容是英文,需要用英文字体来显示,但是也会出现一些汉字,需要用汉字字体来显示,而由于FOP的PDF输出不支持多字体,所以采用英文字体输出后应该是汉字的内容就成了“#”号。为了解决这一问题,需要自定义字体。我们制作了新的字体文件TestBank,将英文字体和汉字字体组合在一起形成一种新的字体。制作好字体文件后,还要生成字体映射文件TestBank.xml,并在FOP的配置文件中进行注册。这样,在样式表中设置字体为我们新建的字体就可以同时处理英文与汉字,满足了本试题库系统中对输出试卷的字体的要求。
(2)下划线等特殊格式的处理
试题内容中包含有许多特殊格式,如斜体和下划线等,需要在输出时做特殊处理。这就需要用到fo:block块中的fo:inline内联元素。通过XSLT对嵌套有斜体和下划线的内容作递归处理,把其中有特殊格式的部分放入内联元素中,并设置内联元素的font-style=“italic”和text-decoration=“underline”属性后,可以把内容按要求的格式输出。对于加下划线的内容,为了显示更加清晰,最好在加下划线的内容前后各加一个空格,但是由于在处理过程中不支持对空白字符加下划线,所以需要找一个不可打印的非空白字符来代替空格。在这里可以采用插入转义字符的方式实现,通过尝试“
关键词:试卷 输出 格式 XML XSL FOP
中图分类号:G434 文献标识码:A 文章编号:1673-8454(2007)10-0070-03
一、引言
随着计算机技术在教学中的应用越来越广泛,试题库系统的建设也越来越重要。在试题库系统中,很重要的一个功能是试卷输出。由于Office等软件具备所见即所得、易于操作等特点,许多试题库系统基于这类软件对试卷进行版面设计及输出。[1] 这种方式虽然易于实现,但在使用时不能脱离软件独立运行,在没有安装这类软件的计算机上无法使用或是不能输出试卷,而且输出试卷的格式也受限于其依赖的编辑软件。另一方面,随着Internet的广泛应用,基于XML的网络试题库系统越来越多,这些系统更多地关注于试题的存储与传输,对所生成试卷的输出问题很少提及。[2] 而在实际试题库应用中,对试卷输出并打印是有很大需求的。
由此,我们在研发大学英语试题库系统时对试卷输出进行了有益的尝试,实现了基于XML的试题库试卷的快速灵活的输出。本文主要讨论XML试题库试卷的输出过程及具体实现。
二、XML格式转换的流程
由于XML格式不仅可扩展性强、内容与样式分离、以文本格式进行存储和传输、具有良好的开放性、跨平台性和可操作性[3],而且与Word格式相比,采用XML格式来表示试卷、试题、参考答案文件有很多优点,更适合试题库的网络应用的需求。[4] 所以我们采用XML作为试题库系统中试题和试卷的存储格式。这样,试卷输出的关键是将由XML表示的试卷文档转换成其他格式的文档供修改或打印。其转换过程如图1所示:

图1 XML格式转换过程
XML源文档以XML格式存储了要转换输出的试卷内容。可扩展标记语言XML,可以使用自己创建的标记存储数据。在我们所开发的试题库系统中,试题和试卷都是基于XML存储的,其中音频和图片也可以编码后以XML格式存储。[5]
XSL样式表定义了输出的版面设计和对输出内容的选取。可扩展样式表语言XSL由XSLT、XPath和XSL-FO组成。[6] 可扩展样式表语言转换XSLT提供一套规则,用于将一组元素描述的XML数据转换为另一组元素描述的文档,或者将该数据转换为一种自定义的文本格式。在这里,我们通过XSLT,将用XML表示的试卷转换为由XSL-FO表示的格式化对象。XPath是XML路径语言,用于对XML文档中的元素进行定位,由XSLT使用。格式化对象的可扩展样式表语言XSL-FO定义了在屏幕或纸张或其他媒介上如何显示数据。在我们的试题库系统中,输出的试卷排版布局由XSL-FO表示。
处理器读取XML源文档和XSL样式表,并转换输出PDF、RTF、HTML等格式的文档。在多种转换处理工具中,我们选择了FOP。FOP是Apache XML Project提供的一种转换工具,使用它可以便捷地将XML文档转换为PDF、RTF等格式。[7] 但是由于FOP对于PDF和RTF的支持不完全相同,所在要针对PDF和RTF对样式表分别作修改,才能输出美观的文档。
由图1可以看出,整个转换过程就是将表示内容的XML文档和表示样式的XSL文档提交给处理器,经处理器转换得到输出结果为PDF、RTF等格式的文档。
三、基于XML的试卷输出实现
在输出试卷时,我们首先将试题库组卷模块中生成的试卷保存为XML文档,然后根据要输出的试卷格式选择相应的样式表,把XML文档和样式表交给处理程序FOP处理后将试卷输出为PDF或RTF格式。本节先介绍我们采用的试卷结构,然后介绍对应的样式表,最后就实现过程中遇到的问题给出解决方案。
1.试卷结构
在本试题库系统中,试题和试卷都存储为XML结构。通过扩展XML标记,定义了适合本题库系统的试题和试卷XML结构。试卷的具体结构为:
<paper name="Test Paper" score="100">
<part type="Listening" id="1">
<section direction="Section Direction" type="Statements" id="1">
<assessmentItem id="1">
……
</assessmentItem>
<assessmentItem id="2">
……
</assessmentItem>
</section>
<section direction="Section Direction" type="Short Conversations" id="2">
<assessmentItem type="SentenceListening" id="1" />
……
</section>
<part type="Reading Comprehension" id="2">
……
</part>
……
</paper>
试卷(Paper)由几个部分(Part)组成,每个部分由一节或几节(Section)组成,每一节由若干试题(Item)组成。对于试题,由于题型的不同,包含不同的元素。基本的试题结构为:
<assessmentItem type="ReadingChoice" id="2">
<content >
<question id="36">
<prompt>The passage is meant to ______.</prompt>
<choices>
<choice id="A" />
<choice id="B" />
<choice id="C" />
<choice id="D" />
</choices>
<answer><value>A</value></answer>
</question>
<question id="37">
</question>
</assessmentItem>
试题的主要元素有题干、问题、答案。对于听力题,需要有声音文件和听力脚本。
2.样式表
与试卷对应的XSLT样式表结构为:
<xsl:stylesheet>
<xsl:template match="/">
<fo:root >
<fo:layout-master-set>
<fo:simple-page-master master-name="TestBanks">
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="TestBanks">
<fo:flow flow-name="xsl-region-body">
<fo:block>
<xsl:call-template name="paper_test"/>
</fo:block>
<fo:block>
<xsl:call-template name="paper_answersheet"/>
</fo:block>
<fo:block>
<xsl:call-template name="paper_key"/>
</fo:block>
<fo:block>
<xsl:call-template name="paper_Script_of_Listening"/>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
在试卷的XML文档中,题目内容、答案以及听力原文是在一起的,但在输出的试卷中,要将其分成三个不同的部分,而且试卷输出的同时要输出答题纸,所以要对输入的XML试卷进行四遍扫描,每一遍分别应用不同的模板,取出所需要处理的信息进行转换输出。
试题册模板首先输出试卷名称和注意事项等内容,然后遍历试卷中的每一部分节点,根据每部分的名称来应用对应的部分模板。每部分的模板先输出标题,然后遍历本部分中的所有节,对不同的节应用对应的节模板。节模板先输出节标题和本节的答题要求,然后遍历本节的所有试题,应用对应的试题模板对试题内容进行输出。对于不同的试题,根据其所具有的元素,选择要在试题册上显示的内容输出。
答题卡模板、答案模板和听力脚本模板同样采用上面按层次调用的方法,逐步应用部分、节和试题模板,输出自己所需要呈现的内容。所有的内容都输出到fo:block内容块中。
3.转换过程中遇到的问题及解决办法
设计好样式表以后,就可以使用FOP对XML试卷进行转换输出了。在输出过程中,笔者在字体、试卷中的特殊格式等方面遇到以下主要问题需要解决。
(1)字体设置
由于试卷上大部分内容是英文,需要用英文字体来显示,但是也会出现一些汉字,需要用汉字字体来显示,而由于FOP的PDF输出不支持多字体,所以采用英文字体输出后应该是汉字的内容就成了“#”号。为了解决这一问题,需要自定义字体。我们制作了新的字体文件TestBank,将英文字体和汉字字体组合在一起形成一种新的字体。制作好字体文件后,还要生成字体映射文件TestBank.xml,并在FOP的配置文件中进行注册。这样,在样式表中设置字体为我们新建的字体就可以同时处理英文与汉字,满足了本试题库系统中对输出试卷的字体的要求。
(2)下划线等特殊格式的处理
试题内容中包含有许多特殊格式,如斜体和下划线等,需要在输出时做特殊处理。这就需要用到fo:block块中的fo:inline内联元素。通过XSLT对嵌套有斜体和下划线的内容作递归处理,把其中有特殊格式的部分放入内联元素中,并设置内联元素的font-style=“italic”和text-decoration=“underline”属性后,可以把内容按要求的格式输出。对于加下划线的内容,为了显示更加清晰,最好在加下划线的内容前后各加一个空格,但是由于在处理过程中不支持对空白字符加下划线,所以需要找一个不可打印的非空白字符来代替空格。在这里可以采用插入转义字符的方式实现,通过尝试“