Skip to content

Published QTI item with a single-quoted xml:lang is written as malformed XML #6230

Description

@rtibblesbot

❌ This issue is not open for contribution. Visit Contributing guidelines to learn about the contributing process and how to find suitable issues.

Target branch: unstable

Observed behavior

set_qti_item_language (utils/assessment/qti/media.py) only recognises xml:lang="..." in double quotes.
On an item whose root declares xml:lang='en', it appends a second xml:lang="fr" instead of replacing the first.
Schema validation runs before language stamping, so the malformed item is written into the package.

Errors and logs

lxml parsing the packaged item: Attribute xml:lang redefined, line 1, column 147.

Expected behavior

The item root carries one xml:lang, set to the node's language, whichever quote style the item used.

User-facing consequences

A channel with such an item publishes a QTI package containing an unparseable item file.

Steps to reproduce

  1. Store a type == qti item whose root has xml:lang='en' (single quotes), e.g. written by ricecooker.
  2. Publish a node with a language set.
  3. Read items/<id>.xml from the QTI zip: the root has both xml:lang='en' and xml:lang="fr".

Context

  • XML_LANG_ATTRIBUTE_REGEX in media.py matches double quotes only.
  • A root written with a namespace prefix (<q:qti-assessment-item) is never matched by ITEM_ROOT_START_TAG_REGEX, so it gets no language.
  • Found while reviewing Multi-answer text-entry QTI items saved before #6223; reproduced on upstream/unstable.

AI usage

I used Claude Code to review the #6223 branch. It found this and reproduced it on upstream/unstable with set_qti_item_language directly.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions