3.2. IMS Question and Test Interoperability (version 1.2)

The IMS Question and Test Interoperability (QTI) specification version 1.2 was finalized in 2002. After a gap of 1-2 years work started on a major revision, culminating in version 2 of the specification, published first in 2005. For information about the history of the specification see http://en.wikipedia.org/wiki/QTI - official information about the specification is available from the IMS GLC: http://www.imsglobal.org/question/index.html

The purpose of this module is to allow documents in QTI v1 format to be parsed and then transformed into objects representing the QTI v2 data model where more sophisticated processing can be performed. Effectively, the native model of assessment items in Pyslet (and in the PyAssess package it supersedes) is QTI v2 and this module simply provides an import capability for legacy data marked up as QTI v1 items.

Class methods or functions with names beginning MigrateV2 use a common pattern for performing the conversion. Errors and warnings are logged during conversion to a list passed in as the log parameter.

class pyslet.imsqtiv1p2p1.QTIDocument(**args)

Bases: pyslet.xml20081126.structures.Document

Class for working with QTI documents.

We turn off the parsing of external general entities to prevent a missing DTD causing the parse to fail. This is a significant limitation as it is possible that some sophisticated users have used general entities to augment the specification or to define boiler-plate code. If this causes problems then you can turn the setting back on again for specific instances of the parser that will be used with that type of data.

XMLParser(entity)

Adds some options to the basic XMLParser to improve QTI compatibility.

get_element_class(name)

Returns the class to use to represent an element with the given name.

This method is used by the XML parser. The class object is looked up in the classMap, if no specialized class is found then the general pyslet.xml20081126.Element class is returned.

RegisterMatThing(matThing)

Registers a MatThing instance in the dictionary of matThings.

FindMatThing(linkRefID)

Returns the mat<thing> element with label matching the linkRefID.

The specification says that material_ref should be used if you want to refer a material object, not matref, however this rule is not universally observed so if we don’t find a basic mat<thing> we will search the material objects too and return a Material instance instead.

RegisterMaterial(material)

Registers a Material instance in the dictionary of labelled material objects.

FindMaterial(linkRefID)

Returns the material element with label matching linkRefID.

Like FindMatThing() this method will search for instances of MatThingMixin if it can’t find a Material element to match. The specification is supposed to be strict about matching the two types of reference but errors are common, even in the official example set.

MigrateV2(cp)

Converts the contents of this document to QTI v2

The output is stored into the content package passed in cp. Errors and warnings generated by the migration process are added as annotations to the resulting resource objects in the content package.

The function returns a list of 4-tuples, one for each object migrated.

Each tuple comprises ( <QTI v2 Document>, <LOM Metadata>, <log>, <Resource> )

3.2.3. QuesTestInterop Elements

class pyslet.imsqtiv1p2p1.QuesTestInterop(parent)

Bases: pyslet.qtiv1.common.QTICommentContainer

The <questestinterop> element is the outermost container for the QTI contents i.e. the container of the Assessment(s), Section(s) and Item(s):

<!ELEMENT questestinterop (qticomment? , (objectbank | assessment | (section | item)+))>
MigrateV2()

Converts this element to QTI v2

Returns a list of tuples of the form: ( <QTIv2 Document>, <Metadata>, <List of Log Messages> ).

One tuple is returned for each of the objects found. In QTIv2 there is no equivalent of QuesTestInterop. The baseURI of each document is set from the baseURI of the QuesTestInterop element using the object identifier to derive a file name.

3.2.4. Object Bank Elements

class pyslet.imsqtiv1p2p1.ObjectBank(parent)

Bases: pyslet.qtiv1.common.MetadataContainerMixin, pyslet.qtiv1.common.QTICommentContainer

This is the container for the Section(s) and/or Item(s) that are to be grouped as an object-bank. The object-bank is assigned its own unique identifier and can have the full set of QTI-specific meta-data:

<!ELEMENT objectbank (qticomment? , qtimetadata* , (section | item)+)>
<!ATTLIST objectbank  ident CDATA  #REQUIRED >

3.2.5. Assessment Elements

class pyslet.imsqtiv1p2p1.Assessment(parent)

Bases: pyslet.qtiv1.common.QTICommentContainer

The Assessment data structure is used to contain the exchange of test data structures. It will always contain at least one Section and may contain meta-data, objectives, rubric control switches, assessment-level processing, feedback and selection and sequencing information for sections:

<!ELEMENT assessment (qticomment? ,
        duration? ,
        qtimetadata* ,
        objectives* ,
        assessmentcontrol* ,
        rubric* ,
        presentation_material? ,
        outcomes_processing* ,
        assessproc_extension? ,
        assessfeedback* ,
        selection_ordering? ,
        reference? ,
        (sectionref | section)+
        )>
<!ATTLIST assessment  ident CDATA  #REQUIRED
                                           %I_Title;
                                           xml:lang CDATA  #IMPLIED >
MigrateV2(output)

Converts this assessment to QTI v2

For details, see QuesTestInterop.MigrateV2.

class pyslet.imsqtiv1p2p1.AssessmentControl(parent)

Bases: pyslet.qtiv1.common.QTICommentContainer

The control switches that are used to enable or disable the display of hints, solutions and feedback within the Assessment:

<!ELEMENT assessmentcontrol (qticomment?)>
<!ATTLIST assessmentcontrol
        hintswitch  (Yes | No )  'Yes'
        solutionswitch  (Yes | No )  'Yes'
        view        (All | Administrator | AdminAuthority | Assessor | Author |
                        Candidate | InvigilatorProctor | Psychometrician | Scorer |
                        Tutor ) 'All'
        feedbackswitch  (Yes | No )  'Yes' >
class pyslet.imsqtiv1p2p1.AssessProcExtension(parent, name=None)

Bases: pyslet.qtiv1.core.QTIElement

This is used to contain proprietary alternative Assessment-level processing functionality:

<!ELEMENT assessproc_extension ANY>
class pyslet.imsqtiv1p2p1.AssessFeedback(parent)

Bases: pyslet.qtiv1.common.QTICommentContainer, pyslet.qtiv1.common.ContentMixin

The container for the Assessment-level feedback that is to be presented as a result of Assessment-level processing of the user responses:

<!ELEMENT assessfeedback (qticomment? , (material+ | flow_mat+))>
<!ATTLIST assessfeedback
        view        (All | Administrator | AdminAuthority | Assessor | Author |
                        Candidate | InvigilatorProctor | Psychometrician | Scorer |
                        Tutor ) 'All'
        ident CDATA  #REQUIRED
        title CDATA  #IMPLIED >