Skip to content

Serialise a QTI item's language as xml:lang and run the item schema's Schematron rules - #6099

Open
rtibblesbot wants to merge 2 commits into
learningequality:unstablefrom
rtibblesbot:issue-6098-751e59
Open

Serialise a QTI item's language as xml:lang and run the item schema's Schematron rules#6099
rtibblesbot wants to merge 2 commits into
learningequality:unstablefrom
rtibblesbot:issue-6098-751e59

Conversation

@rtibblesbot

@rtibblesbot rtibblesbot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Summary

  • QTI 3.0 defines no language attribute; an item's language now serialises as xml:lang.
  • validate_qti_item now runs the item schema's own Schematron rules, which etree.XMLSchema never executes.

References

Fixes #6098. Read-side tolerance: #6095.

Reviewer guidance

  • Every item is now stricter, not only the ones this branch changes: tripping a Schematron rule means rejected on save, dropped from the package at publish.
  • Stored raw_data written before this can carry an attribute the XSD's wildcard used to admit.
  • The Schematron surfaced one such violation in-tree — srcset on <img> in a viewset test's sample item. I corrected the sample rather than loosen the validator.
  • Conversion and ingest tests validate every item they generate, so the Schematron runs against real output, not only hand-written samples.
  • The seven files under tests/utils/qti/fixtures/ are golden expected output compared verbatim by test_convert.py, not assertion-free tests. Mutating one attribute in each fails a distinct test_convert.py case.

AI usage

Used Claude Code to implement both changes test-first from the plan on the issue. Verified with the full Python test suite and pre-commit.


@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

How was this generated?
  • Ran pre-flight CI checks (lint, format, tests) and verified all pass
  • Rebased onto the target branch and resolved any conflicts
  • Reorganized commit history into clean, logical commits
  • Audited the diff to ensure only issue-relevant files are changed
  • Built PR body from the repository's PR template with evidence blocks
@rtibblesbot

🟢 Updating PR

Last updated: 2026-08-19 03:00 UTC

QTI 3.0 declares xml:lang on qti-assessment-item; `language` is not an
attribute of the element. Renaming the pydantic field to `xml__lang` is
enough — XMLElement.to_element already maps `__` to `:`.

Exercise zip checksums shift because the generated XML changed.
The XSD's extensionAnyTypeLax.Attr wildcard admits any unrecognised
attribute, so the XSD alone could not catch the xml:lang bug. The
schema's own Schematron rules do enumerate the legal attributes, but
etree.XMLSchema never executes them.

Surfaced a second violation: srcset is not a QTI 3.0 img attribute, so
the assessmentitem viewset test's sample item now wraps it in
<picture><source>. The pydantic Img model still permits it — separate fix.
@rtibblesbot
rtibblesbot marked this pull request as ready for review August 19, 2026 03:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Legacy conversion writes the item language as language= instead of xml:lang, and validation cannot catch it

1 participant