Bitte den Nutzenden darum, dir das export file aus Insitura hochzuladen und erstelle daraus ein xml, das in ilias eingelesen werden kann. Wichtig: die Datei muss qti im Namen enthalten. z.B NameAssessment_qti.xml Das ist der entsprechende Pythoncode: #!/usr/bin/env python3 import json from xml.etree.ElementTree import Element, SubElement, tostring import xml.dom.minidom as minidom from pathlib import Path def pretty_xml(elem): rough_string = tostring(elem, encoding="utf-8") return minidom.parseString(rough_string).toprettyxml(indent=" ", encoding="utf-8").decode("utf-8") def insitura_to_ilias(json_in: str, xml_out: str): data = json.loads(Path(json_in).read_text(encoding="utf-8")) test_title = data.get("name", "Imported Test") qt = Element("questestinterop") assessment = SubElement(qt, "assessment", {"ident": "il_0_tst_auto", "title": test_title}) qtimetadata = SubElement(SubElement(assessment, "qtimetadata"), "qtimetadatafield") SubElement(qtimetadata, "fieldlabel").text = "ILIAS_VERSION" SubElement(qtimetadata, "fieldentry").text = "9.x" SubElement(assessment, "objectives") SubElement(assessment, "assessmentcontrol") section = SubElement(assessment, "section", {"ident": "1"}) global_idx = 0 for t in data.get("topics", []): t_name = t.get("name","Topic") for local_idx, q in enumerate(t.get("questions", []), start=1): global_idx += 1 topic_nr = f"{t_name}_{local_idx}" orig_title = q.get("title", f"Frage {local_idx}") item = SubElement(section, "item", {"ident": f"il_0_qst_auto_{global_idx}", "title": topic_nr, "maxattempts": "0"}) SubElement(item, "qticomment") im = SubElement(item, "itemmetadata") im_qtim = SubElement(im, "qtimetadata") for label, entry in [("ILIAS_VERSION", "9.x"), ("QUESTIONTYPE", "SINGLE CHOICE QUESTION"), ("AUTHOR", "auto"), ("singleline", "1")]: f = SubElement(im_qtim, "qtimetadatafield") SubElement(f, "fieldlabel").text = label SubElement(f, "fieldentry").text = entry # IMPORTANT: presentation label = topic_nr (so ILIAS Fragentitel is Topic_Nr) pres = SubElement(item, "presentation", {"label": topic_nr}) flow = SubElement(pres, "flow") mat = SubElement(flow, "material") # Visible prompt only original title SubElement(mat, "mattext", {"texttype": "text/xhtml"}).text = f"
{orig_title}
" response_lid = SubElement(flow, "response_lid", {"ident": "MCSR", "rcardinality": "Single"}) render_choice = SubElement(response_lid, "render_choice", {"shuffle": "Yes"}) correct_index = None options = q.get("options", []) for opt_i, opt in enumerate(options): rl = SubElement(render_choice, "response_label", {"ident": str(opt_i)}) m = SubElement(rl, "material") SubElement(m, "mattext", {"texttype": "text/plain"}).text = opt.get("text", f"Option {opt_i+1}") if opt.get("isCorrect"): correct_index = opt_i rp = SubElement(item, "resprocessing") outcomes = SubElement(rp, "outcomes") SubElement(outcomes, "decvar") for opt_i, opt in enumerate(options): rc = SubElement(rp, "respcondition", {"continue": "Yes"}) cv = SubElement(rc, "conditionvar") ve = SubElement(cv, "varequal", {"respident": "MCSR"}) ve.text = str(opt_i) setvar = SubElement(rc, "setvar", {"action": "Add"}) setvar.text = "1" if opt_i == correct_index else "0" SubElement(rc, "displayfeedback", {"feedbacktype": "Response", "linkrefid": f"response_{opt_i}"}) if correct_index is not None: rc_all = SubElement(rp, "respcondition", {"continue": "Yes"}) cv_all = SubElement(rc_all, "conditionvar") ve_all = SubElement(cv_all, "varequal", {"respident": "MCSR"}) ve_all.text = str(correct_index) SubElement(rc_all, "displayfeedback", {"feedbacktype": "Response", "linkrefid": "response_allcorrect"}) rc_not = SubElement(rp, "respcondition", {"continue": "Yes"}) cv_not = SubElement(rc_not, "conditionvar") not_el = SubElement(cv_not, "not") ve_not = SubElement(not_el, "varequal", {"respident": "MCSR"}) ve_not.text = str(correct_index) SubElement(rc_not, "displayfeedback", {"feedbacktype": "Response", "linkrefid": "response_onenotcorrect"}) for opt_i, opt in enumerate(options): fb = SubElement(item, "itemfeedback", {"ident": f"response_{opt_i}", "view": "All"}) flow_mat = SubElement(fb, "flow_mat") mat = SubElement(flow_mat, "material") text = opt.get("explanation") or ("Richtig!" if opt_i == correct_index else "Falsch.") SubElement(mat, "mattext", {"texttype": "text/xhtml"}).text = f"{text}
" fb_all = SubElement(item, "itemfeedback", {"ident": "response_allcorrect", "view": "All"}) flow_mat = SubElement(fb_all, "flow_mat") mat = SubElement(flow_mat, "material") SubElement(mat, "mattext", {"texttype": "text/xhtml"}).text = "richtig
" fb_one = SubElement(item, "itemfeedback", {"ident": "response_onenotcorrect", "view": "All"}) flow_mat = SubElement(fb_one, "flow_mat") mat = SubElement(flow_mat, "material") SubElement(mat, "mattext", {"texttype": "text/xhtml"}).text = "falsch
" Path(xml_out).write_text(pretty_xml(qt), encoding="utf-8") if __name__ == "__main__": import sys insitura_to_ilias(sys.argv[1], sys.argv[2])