public static List <XmlElement> Convert(XmlDocument xml, Excel <ExamExcelColumn, ExamExcelColumnType> mockExamsExcel) { List <XmlElement> chapterNodes = new List <XmlElement>(); //get practice and final mock exam questions var practiceMockReference = "Practice"; var finalMockReference = "Final"; var practiceMockRows = mockExamsExcel.Rows.Where(r => r.Any(c => c.Type == ExamExcelColumnType.MockType && c.Value.Contains(practiceMockReference))); var finalMockRows = mockExamsExcel.Rows.Where(r => r.Any(c => c.Type == ExamExcelColumnType.MockType && c.Value.Contains(finalMockReference))); //work on practice mocks List <String> practiceMockExamPositionReferences = new List <String>(); var practiceMockExamPositionReferencesValues = practiceMockRows.GroupBy(r => r.First(tn => tn.Type == ExamExcelColumnType.ContainerPosition1).Value); foreach (var practiceMockExamPositionReferencesValue in practiceMockExamPositionReferencesValues) { string containerReferenceValue = practiceMockExamPositionReferencesValue.Key; //remove _AM and _PM from keys practiceMockExamPositionReferences.Add(containerReferenceValue.Remove(containerReferenceValue.Length - 3)); } practiceMockExamPositionReferences = practiceMockExamPositionReferences.Distinct().ToList(); foreach (var positionReference in practiceMockExamPositionReferences) { var mockRows = practiceMockRows.Where(r => r.Any(c => c.Type == ExamExcelColumnType.ContainerPosition1 && c.Value.Contains(positionReference))); if (mockRows.Any()) { char index = positionReference.Last(); var mockExamChapterContainerRef = mockRows.First().FirstOrDefault(tn => tn.Type == ExamExcelColumnType.ContainerRef1).Value; mockExamChapterContainerRef = mockExamChapterContainerRef.Remove(mockExamChapterContainerRef.Length - 3); var mockExamChapterNode = GetMockExamChapterNode(xml, mockRows); mockExamChapterNode.SetAttribute("display_name", "Mock Examination " + index); mockExamChapterNode.SetAttribute("url_name", CourseConverterHelper.getGuid("MockExamChapterNode " + mockExamChapterContainerRef, CourseTypes.Topic)); mockExamChapterNode.SetAttribute("cfa_type", "mock_exam"); mockExamChapterNode = GetMockExamType(mockExamChapterNode); mockExamChapterNode.SetAttribute("cfa_short_name", "Mock Exam " + index); mockExamChapterNode.SetAttribute("test_duration", "03:00"); chapterNodes.Add(mockExamChapterNode); } } //work on final mock exam var finalExamChapterNode = GetMockExamChapterNode(xml, finalMockRows); var finalExamChapterContainerRef = finalMockRows.First().FirstOrDefault(tn => tn.Type == ExamExcelColumnType.ContainerRef1).Value; finalExamChapterContainerRef = finalExamChapterContainerRef.Remove(finalExamChapterContainerRef.Length - 3); finalExamChapterNode.SetAttribute("display_name", "Final Mock Examination"); finalExamChapterNode.SetAttribute("url_name", CourseConverterHelper.getGuid("MockExamChapterNode " + finalExamChapterContainerRef, CourseTypes.Topic)); finalExamChapterNode.SetAttribute("cfa_type", "final_mock_exam"); finalExamChapterNode = GetMockExamType(finalExamChapterNode); finalExamChapterNode.SetAttribute("cfa_short_name", "Final Mock Exam"); finalExamChapterNode.SetAttribute("test_duration", "03:00"); chapterNodes.Add(finalExamChapterNode); return(chapterNodes); }
private static XmlNode GetProgressTestSequantialNode(XmlDocument xml, string topicName, string topicId, string kStructure, IEnumerable <List <IExcelColumn <ExamExcelColumnType> > > topicGroup) { var sequentialNode = xml.CreateElement("sequential"); sequentialNode.SetAttribute("display_name", topicName); sequentialNode.SetAttribute("url_name", CourseConverterHelper.getGuid(topicId, CourseTypes.StudySession)); sequentialNode.SetAttribute("taxon_id", kStructure); string itemSetTitle = topicGroup.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.ContainerTitle2) != null?topicGroup.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.ContainerTitle2).Value : ""; string vignetteTitle = topicGroup.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.VignetteTitle) != null?topicGroup.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.VignetteTitle).Value : ""; string vignetteBody = topicGroup.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.VignetteBody) != null?topicGroup.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.VignetteBody).Value : ""; string topicTaxonId = topicGroup.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.TopicTaxonId) != null?topicGroup.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.TopicTaxonId).Value : ""; //if item set title empty leave old vertical display name, if not change it string displayName = (itemSetTitle == null) ? "Progress test - R" : itemSetTitle; var verticalNode = xml.CreateElement("vertical"); verticalNode.SetAttribute("display_name", displayName); verticalNode.SetAttribute("study_session_test_id", ""); verticalNode.SetAttribute("url_name", CourseConverterHelper.getGuid(topicId, CourseTypes.Reading)); verticalNode.SetAttribute("taxon_id", topicTaxonId); verticalNode.SetAttribute("vignette_title", vignetteTitle); verticalNode.SetAttribute("vignette_body", vignetteBody); sequentialNode.AppendChild(verticalNode); //skip vignette row. if there is any topicGroup = topicGroup.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.Question).HaveValue() && topicGroup.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.Question) != null ? topicGroup : topicGroup.Skip(1); var problemBuilderNode = ProblemBuilderNodeGenerator.Generate(xml, topicGroup, new ProblemBuilderNodeSettings { DisplayName = "Progress test", UrlName = CourseConverterHelper.getGuid(topicId, CourseTypes.Question), ProblemBuilderNodeElement = "problem-builder-progress-test", PbMcqNodeElement = "pb-mcq-progress-test", PbChoiceBlockElement = "pb-choice-progress-test", PbTipBlockElement = "pb-tip-progress-test" }); verticalNode.AppendChild(problemBuilderNode); return(sequentialNode); }
private static XmlNode GetMockExamVerticalNode(XmlDocument xml, string seqContainerRef, IEnumerable <List <IExcelColumn <ExamExcelColumnType> > > mockRows) { string topicName = mockRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.TopicName).Value; string topicTaxonId = mockRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.TopicTaxonId).Value; string container2Title = mockRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.ContainerTitle2).Value != null? mockRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.ContainerTitle2).Value : ""; //if item set title empty leave old vertical display name, if not change it topicName = (container2Title == "") ? topicName : container2Title; string vignetteTitle = mockRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.VignetteTitle).Value != null? mockRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.VignetteTitle).Value : ""; string vignetteBody = mockRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.VignetteBody).Value != null? mockRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.VignetteBody).Value : ""; //create vertical node var verticalNode = xml.CreateElement("vertical"); verticalNode.SetAttribute("display_name", topicName); verticalNode.SetAttribute("url_name", CourseConverterHelper.getGuid(String.Format("mock-vertical-{0}-{1}", seqContainerRef, topicName), CourseTypes.Mock)); verticalNode.SetAttribute("study_session_test_id", ""); verticalNode.SetAttribute("taxon_id", topicTaxonId); verticalNode.SetAttribute("vignette_title", vignetteTitle); verticalNode.SetAttribute("vignette_body", vignetteBody); //skip vignette row, if there is any var topicQuestions = mockRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.Question).HaveValue() && mockRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.Question).Value != null ? mockRows : mockRows.Skip(1); var problemBuilderNode = ProblemBuilderNodeGenerator.Generate(xml, topicQuestions, new ProblemBuilderNodeSettings { DisplayName = String.Format("Mock exam questions - {0} - {1}", seqContainerRef, topicName), UrlName = CourseConverterHelper.getGuid(String.Format("mock-progress-test-{0}-{1}", seqContainerRef, topicName), CourseTypes.Mock), ProblemBuilderNodeElement = "problem-builder-mock-exam", PbMcqNodeElement = "pb-mcq-mock-exam", PbChoiceBlockElement = "pb-choice-mock-exam", PbTipBlockElement = "pb-tip-mock-exam" }); verticalNode.AppendChild(problemBuilderNode); return(verticalNode); }
private void AppendStudySessionTestQuestions(XmlDocument xml, XmlElement sequentialNode, string studySessionId, Excel <ExamExcelColumn, ExamExcelColumnType> ssTestExcel) { var excelRows = ssTestExcel.Rows.Where(r => r.Any(c => c.Type == ExamExcelColumnType.SessionRef && c.Value == studySessionId)); if (excelRows.Any()) { string verticalTestId = excelRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.Structure).Value; verticalTestId = String.Join("|", verticalTestId.Split('|').Take(3)); var verticalNode = xml.CreateElement("vertical"); verticalNode.SetAttribute("display_name", "Study Session Test"); verticalNode.SetAttribute("cfa_type", "test"); verticalNode.SetAttribute("cfa_short_name", "SST"); verticalNode.SetAttribute("study_session_test_id", verticalTestId); verticalNode.SetAttribute("url_name", CourseConverterHelper.getGuid(verticalTestId, CourseTypes.Reading)); var containerReferences = excelRows.GroupBy(r => r.First(tn => tn.Type == ExamExcelColumnType.ContainerRef1).Value); foreach (var containerReference in containerReferences) { string containerReferenceValue = containerReference.Key; var ssRows = excelRows.Where(r => r.Any(c => c.Type == ExamExcelColumnType.ContainerRef1 && c.Value.Contains(containerReferenceValue))); if (ssRows.Any()) { char index = containerReferenceValue.Last(); var problemBuilderNode = ProblemBuilderNodeGenerator.Generate(xml, ssRows, new ProblemBuilderNodeSettings { DisplayName = "Study Session Test", UrlName = CourseConverterHelper.getGuid(verticalTestId + '_' + index, CourseTypes.Question), ProblemBuilderNodeElement = "problem-builder-block", PbMcqNodeElement = "pb-mcq-block", PbChoiceBlockElement = "pb-choice-block", PbTipBlockElement = "pb-tip-block" }); verticalNode.AppendChild(problemBuilderNode); } } sequentialNode.AppendChild(verticalNode); } }
public static XmlElement Generate(XmlDocument xml, IEnumerable <List <IExcelColumn <ExamExcelColumnType> > > excelRows, ProblemBuilderNodeSettings settings) { var problemBuilderNode = xml.CreateElement(settings.ProblemBuilderNodeElement); problemBuilderNode.SetAttribute("display_name", settings.DisplayName); problemBuilderNode.SetAttribute("url_name", settings.UrlName); problemBuilderNode.SetAttribute("xblock-family", "xblock.v1"); problemBuilderNode.SetAttribute("cfa_type", "question"); foreach (var row in excelRows) { var questionDic = CourseConverterHelper.generateQuestionIds(); var questionColumn = row.FirstOrDefault(c => c.Type == ExamExcelColumnType.Question); var questionIdColumn = row.FirstOrDefault(c => c.Type == ExamExcelColumnType.QuestionId); string questionValue = questionColumn.HaveValue() ? questionColumn.Value : "Question Missing"; var pbMcqNode = xml.CreateElement(settings.PbMcqNodeElement); var correctColumn = row.FirstOrDefault(c => c.Type == ExamExcelColumnType.Correct); var actualCorrectValues = new List <string>(); if (correctColumn != null && correctColumn.HaveValue()) { var correctValues = correctColumn.Value.Split(' '); foreach (var correctValue in correctValues) { actualCorrectValues.Add(questionDic[correctValue]); } } pbMcqNode.SetAttribute("url_name", CourseConverterHelper.getGuid(questionIdColumn.Value, CourseTypes.Question)); pbMcqNode.SetAttribute("xblock-family", "xblock.v1"); pbMcqNode.SetAttribute("question", questionValue); pbMcqNode.SetAttribute("fitch_question_id", questionIdColumn.Value); pbMcqNode.SetAttribute("correct_choices", (correctColumn != null && correctColumn.Value != null) ? JsonConvert.SerializeObject(actualCorrectValues) : ""); problemBuilderNode.AppendChild(pbMcqNode); var questionIds = new List <string>(); var answer1Column = row.FirstOrDefault(c => c.Type == ExamExcelColumnType.Answer1); var question1Id = questionDic["A"]; var answer1Node = CourseConverterHelper.GetAnswerNode(xml, answer1Column, question1Id, false, settings.PbChoiceBlockElement); if (answer1Node != null) { pbMcqNode.AppendChild(answer1Node); questionIds.Add(question1Id); } var answer2Column = row.FirstOrDefault(c => c.Type == ExamExcelColumnType.Answer2); var question2Id = questionDic["B"]; var answer2Node = CourseConverterHelper.GetAnswerNode(xml, answer2Column, question2Id, true, settings.PbChoiceBlockElement); if (answer2Node != null) { pbMcqNode.AppendChild(answer2Node); questionIds.Add(question2Id); } var answer3Column = row.FirstOrDefault(c => c.Type == ExamExcelColumnType.Answer3); var question3Id = questionDic["C"]; var answer3Node = CourseConverterHelper.GetAnswerNode(xml, answer3Column, question3Id, true, settings.PbChoiceBlockElement); if (answer3Node != null) { pbMcqNode.AppendChild(answer3Node); questionIds.Add(question3Id); } //Harcoded answer 4 node var answer4Node = xml.CreateElement(settings.PbChoiceBlockElement); var question4Id = questionDic["D"]; questionIds.Add(question4Id); answer4Node.SetAttribute("url_name", CourseConverterHelper.getNewGuid()); answer4Node.SetAttribute("xblock-family", "xblock.v1"); answer4Node.SetAttribute("value", question4Id); pbMcqNode.AppendChild(answer4Node); //tip block var justificationCell = row.FirstOrDefault(c => c.Type == ExamExcelColumnType.Justification); string justificationInnerText = ""; string justificationValue = (justificationCell != null && justificationCell.HaveValue()) ? justificationCell.Value : ""; var questionTipNode = xml.CreateElement(settings.PbTipBlockElement); questionTipNode.SetAttribute("url_name", CourseConverterHelper.getNewGuid()); questionTipNode.SetAttribute("xblock-family", "xblock.v1"); questionTipNode.SetAttribute("values", JsonConvert.SerializeObject(questionIds)); questionTipNode.InnerText = String.Format("{0}{1}", justificationValue, justificationInnerText); pbMcqNode.AppendChild(questionTipNode); } return(problemBuilderNode); }
public static XmlElement Convert(XmlDocument xml, Excel <ExamExcelColumn, ExamExcelColumnType> progressTestExcel) { var chapterNode = xml.CreateElement("chapter"); chapterNode.SetAttribute("display_name", "Progress Test"); chapterNode.SetAttribute("url_name", CourseConverterHelper.getGuid("ProgressTestChapeterNode", CourseTypes.Topic)); chapterNode.SetAttribute("cfa_type", "progress_test"); chapterNode.SetAttribute("cfa_short_name", "Progress Test"); string progressTestAnswersPdf = progressTestExcel.Rows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.PdfAnswers) != null?progressTestExcel.Rows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.PdfAnswers).Value : ""; string progressTestQuestionsPdf = progressTestExcel.Rows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.PdfQuestions) != null?progressTestExcel.Rows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.PdfQuestions).Value : ""; chapterNode.SetAttribute("topic_pdf_answers", progressTestAnswersPdf); chapterNode.SetAttribute("topic_pdf_questions", progressTestQuestionsPdf); string progressTestId = progressTestExcel.Rows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.ContainerRef1) != null?progressTestExcel.Rows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.ContainerRef1).Value : ""; var essayRows = progressTestExcel.Rows.Where(r => r.Any(c => c.Type == ExamExcelColumnType.ContainerType2 && c.HaveValue() && c.Value.Contains("Essay"))); var questionRows = progressTestExcel.Rows.Where(r => r.Any(c => c.Type == ExamExcelColumnType.ContainerType2 && c.HaveValue() && c.Value.Contains("Item Set"))); if (!questionRows.Any()) { questionRows = progressTestExcel.Rows; } var topicReferences = questionRows.GroupBy(r => r.First(tn => tn.Type == ExamExcelColumnType.TopicRef).Value); foreach (var topicRef in topicReferences) { string topicRefValue = topicRef.Key; var topicRows = questionRows.Where(r => r.Any(c => c.Type == ExamExcelColumnType.TopicRef && c.Value.Contains(topicRefValue))); var itemSetReferencesRows = questionRows.Where(r => r.Any(c => c.Type == ExamExcelColumnType.ContainerRef2 && c.HaveValue())); var itemSetReferences = topicRows.GroupBy(r => r.First(tn => tn.Type == ExamExcelColumnType.ContainerRef2).Value); if (!itemSetReferencesRows.Any()) { itemSetReferences = topicRows.GroupBy(r => r.First(tn => tn.Type == ExamExcelColumnType.ContainerRef1).Value); } foreach (var itemSetReference in itemSetReferences) { string itemSetReferenceValue = itemSetReference.Key; char index = itemSetReferenceValue.Last(); var itemSetRows = topicRows.Where(r => r.Any(c => (c.Type == ExamExcelColumnType.ContainerRef2 || c.Type == ExamExcelColumnType.ContainerRef1) && c.Value.Contains(itemSetReferenceValue))); if (itemSetRows.Any()) { string kStructure = String.Join("|", itemSetRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.Structure).Value.Split('|').Take(2)); string topicName = itemSetRows.First().FirstOrDefault(tn => tn.Type == ExamExcelColumnType.TopicName).Value; string topicAbbrevation = itemSetRows.First().FirstOrDefault(tn => tn.Type == ExamExcelColumnType.TopicRef).Value; //if index is 1 leave old progress test topic id, else change it string topicId = index == '1' ? String.Format("{0}-r-progressTest", topicAbbrevation) : topicId = String.Format("{0}-r-progressTest-{1}-itemSet", topicAbbrevation, index); var sequentialNode = GetProgressTestSequantialNode(xml, topicName, topicId, kStructure, itemSetRows); chapterNode.AppendChild(sequentialNode); } } } bool ifItemSet = true; foreach (XmlElement sequentialNode in chapterNode.ChildNodes) { foreach (XmlElement verticalNode in sequentialNode.ChildNodes) { if (verticalNode.GetAttributeNode("vignette_title").Value == "" && verticalNode.GetAttributeNode("vignette_body").Value == "") { ifItemSet = false; } } } chapterNode.SetAttribute("exam_type", ifItemSet ? "item_set" : "regular"); chapterNode.SetAttribute("test_duration", "02:00"); if (essayRows.Any()) { chapterNode.SetAttribute("exam_type", "essay"); chapterNode.SetAttribute("test_duration", "01:00"); string essaysAnswersPdf = essayRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.PdfAnswers) != null?essayRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.PdfAnswers).Value : ""; string essaysQuestionsPdf = essayRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.PdfQuestions) != null?essayRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.PdfQuestions).Value : ""; var sequentialNode = xml.CreateElement("sequential"); sequentialNode.SetAttribute("display_name", "Progress Test Essays"); sequentialNode.SetAttribute("url_name", CourseConverterHelper.getGuid(String.Format("{0}--essays", progressTestId), CourseTypes.StudySession)); sequentialNode.SetAttribute("cfa_type", "essay"); sequentialNode.SetAttribute("pdf_answers", essaysAnswersPdf); sequentialNode.SetAttribute("pdf_questions", essaysQuestionsPdf); foreach (var row in essayRows) { string essayTitle = row.FirstOrDefault(c => c.Type == ExamExcelColumnType.ContainerTitle2).Value; string topicTaxonId = row.FirstOrDefault(c => c.Type == ExamExcelColumnType.TopicTaxonId).Value; string essayTopics = row.FirstOrDefault(c => c.Type == ExamExcelColumnType.TopicRef).Value; string essayMaxPoints = row.FirstOrDefault(c => c.Type == ExamExcelColumnType.ContainerMaxPoints2).Value; string essayReferenceValue = row.FirstOrDefault(c => c.Type == ExamExcelColumnType.ContainerRef2).Value; var verticalNode = xml.CreateElement("vertical"); verticalNode.SetAttribute("cfa_type", "essay"); verticalNode.SetAttribute("item_set_id", essayReferenceValue); verticalNode.SetAttribute("display_name", essayTitle); verticalNode.SetAttribute("taxon_id", topicTaxonId); verticalNode.SetAttribute("item_set_sessions", essayTopics); verticalNode.SetAttribute("url_name", CourseConverterHelper.getGuid(essayReferenceValue, CourseTypes.Essay)); verticalNode.SetAttribute("essay_max_points", essayMaxPoints); sequentialNode.AppendChild(verticalNode); } chapterNode.AppendChild(sequentialNode); } return(chapterNode); }
private static XmlNode GetMockExamSequantialNode(XmlDocument xml, string displayName, string seqContainerRef, List <List <IExcelColumn <ExamExcelColumnType> > > mockRows) { //create sequential node var pdfAnswers = mockRows.First().FirstOrDefault(tn => tn.Type == ExamExcelColumnType.PdfAnswers).Value; var pdfQuestions = mockRows.First().FirstOrDefault(tn => tn.Type == ExamExcelColumnType.PdfQuestions).Value; var sequentialNode = xml.CreateElement("sequential"); sequentialNode.SetAttribute("display_name", displayName); sequentialNode.SetAttribute("url_name", CourseConverterHelper.getGuid(String.Format("mock-sequential-{0}", seqContainerRef), CourseTypes.Mock)); sequentialNode.SetAttribute("taxon_id", seqContainerRef); sequentialNode.SetAttribute("pdf_answers", pdfAnswers); sequentialNode.SetAttribute("pdf_questions", pdfQuestions); sequentialNode.SetAttribute("cfa_type", ""); //get essays and questions var essayRows = mockRows.Where(r => r.Any(c => c.Type == ExamExcelColumnType.ContainerType2 && c.Value.Contains("Essay"))); var questionRows = mockRows.Where(r => r.Any(c => c.Type == ExamExcelColumnType.ContainerType2 && c.Value.Contains("Item Set"))); if (!questionRows.Any() && !essayRows.Any()) { questionRows = mockRows; } //work on questions if (questionRows.Any()) { //divide by item sets or topics List <String> container2References = new List <String>(); List <String> verticalContainerReferences = new List <String>(); //check if topic needs to be divided to item sets var container2RefKey = mockRows.First().FirstOrDefault(tn => tn.Type == ExamExcelColumnType.ContainerRef2).Value; if (container2RefKey != null) { var container2ReferencesValues = mockRows.GroupBy(r => r.First(tn => tn.Type == ExamExcelColumnType.ContainerRef2).Value); foreach (var container2ReferencesValue in container2ReferencesValues) { container2References.Add(container2ReferencesValue.Key); } foreach (var container2Reference in container2References) { //work on vertical var container2Rows = mockRows.Where(r => r.Any(c => c.Type == ExamExcelColumnType.ContainerRef2 && c.Value.Contains(container2Reference))); var verticalNode = GetMockExamVerticalNode(xml, seqContainerRef, container2Rows); sequentialNode.AppendChild(verticalNode); } } else { var verticalContainerReferencesValues = mockRows.GroupBy(r => r.First(tn => tn.Type == ExamExcelColumnType.TopicRef).Value); foreach (var verticalContainerReferencesValue in verticalContainerReferencesValues) { verticalContainerReferences.Add(verticalContainerReferencesValue.Key); } foreach (var containerReference in verticalContainerReferences) { //work on vertical var topicRows = mockRows.Where(r => r.Any(c => c.Type == ExamExcelColumnType.TopicRef && c.Value.Contains(containerReference))); var verticalNode = GetMockExamVerticalNode(xml, seqContainerRef, topicRows); sequentialNode.AppendChild(verticalNode); } } } //work on essays if (essayRows.Any()) { sequentialNode.SetAttribute("cfa_type", "essay"); foreach (var row in essayRows) { string topicTaxonId = row.FirstOrDefault(c => c.Type == ExamExcelColumnType.TopicTaxonId).Value; string container2Title = row.FirstOrDefault(c => c.Type == ExamExcelColumnType.ContainerTitle2).Value != null? row.FirstOrDefault(c => c.Type == ExamExcelColumnType.ContainerTitle2).Value : ""; string essayMaxPoints = row.FirstOrDefault(c => c.Type == ExamExcelColumnType.ContainerMaxPoints2).Value; string essayTopics = row.FirstOrDefault(c => c.Type == ExamExcelColumnType.TopicRef).Value; var verticalNode = xml.CreateElement("vertical"); verticalNode.SetAttribute("cfa_type", "essay"); verticalNode.SetAttribute("taxon_id", topicTaxonId); verticalNode.SetAttribute("display_name", container2Title); verticalNode.SetAttribute("url_name", CourseConverterHelper.getGuid(String.Format("mock-vertical-{0}-{1}", seqContainerRef, container2Title), CourseTypes.Mock)); verticalNode.SetAttribute("essay_max_points", essayMaxPoints); verticalNode.SetAttribute("study_session_test_id", ""); verticalNode.SetAttribute("vignette_title", ""); verticalNode.SetAttribute("vignette_body", ""); verticalNode.SetAttribute("item_set_sessions", essayTopics); sequentialNode.AppendChild(verticalNode); } } return(sequentialNode); }
private void AppendTopicWorkshop(XmlDocument xml, XmlElement chapterNode, string topicId, Excel <ExamExcelColumn, ExamExcelColumnType> TopicWorkshopExcel) { var topicWorkshopRows = TopicWorkshopExcel.Rows.Where(r => r.Any(c => c.Type == ExamExcelColumnType.TopicRef && c.Value == topicId)); if (topicWorkshopRows.Any()) { var workshopReferences = topicWorkshopRows.GroupBy(r => r.First(tn => tn.Type == ExamExcelColumnType.ContainerRef1).Value); foreach (var workshopReference in workshopReferences) { string workshopReferenceValue = workshopReference.Key; var workshopRows = topicWorkshopRows.Where(r => r.Any(c => c.Type == ExamExcelColumnType.ContainerRef1 && c.Value.Contains(workshopReferenceValue))); if (workshopRows.Any()) { string topicWorkshopTitle = workshopRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.ContainerTitle1).Value; string topicWorkshopType = workshopRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.ContainerType1).Value; if (topicWorkshopType == "Topic Workshop") { topicWorkshopType = "topic_workshop"; } else if (topicWorkshopType == "Review Course Workshop") { topicWorkshopType = "course_workshop"; } var sequentialNode = xml.CreateElement("sequential"); sequentialNode.SetAttribute("display_name", topicWorkshopTitle); sequentialNode.SetAttribute("url_name", CourseConverterHelper.getGuid(workshopReferenceValue, CourseTypes.Workshop)); sequentialNode.SetAttribute("workshop_id", workshopReferenceValue); sequentialNode.SetAttribute("cfa_type", topicWorkshopType); chapterNode.AppendChild(sequentialNode); var itemSetReferences = workshopRows.GroupBy(r => r.First(tn => tn.Type == ExamExcelColumnType.ContainerRef2).Value); foreach (var itemSetReference in itemSetReferences) { string itemSetReferenceValue = itemSetReference.Key; char index = itemSetReferenceValue.Last(); var itemSetRows = workshopRows.Where(r => r.Any(c => c.Type == ExamExcelColumnType.ContainerRef2 && c.Value.Contains(itemSetReferenceValue))); if (itemSetRows.Any()) { string itemSetType = itemSetRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.ContainerType2).Value; string itemSetTitle = itemSetRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.ContainerTitle2).Value; string topicTaxonId = itemSetRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.TopicTaxonId).Value; string itemSetStudySessions = itemSetRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.SessionName).Value; string itemSetPdf = itemSetRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.ContainerPdf2).Value; string itemSetAnswerVideo = itemSetRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.AnswerVideo).Value; var verticalNode = xml.CreateElement("vertical"); verticalNode.SetAttribute("item_set_id", itemSetReferenceValue); verticalNode.SetAttribute("display_name", itemSetTitle); verticalNode.SetAttribute("taxon_id", topicTaxonId); verticalNode.SetAttribute("item_set_sessions", itemSetStudySessions); verticalNode.SetAttribute("item_set_pdf", itemSetPdf); verticalNode.SetAttribute("item_set_video", itemSetAnswerVideo); if (itemSetType == "Item Set") { string vignetteTitle = itemSetRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.VignetteTitle).Value; string vignetteBody = itemSetRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.VignetteBody).Value; verticalNode.SetAttribute("cfa_type", "item_set"); verticalNode.SetAttribute("url_name", CourseConverterHelper.getGuid(itemSetReferenceValue, CourseTypes.ItemSet)); verticalNode.SetAttribute("vignette_title", vignetteTitle); verticalNode.SetAttribute("vignette_body", vignetteBody); sequentialNode.AppendChild(verticalNode); //skip first row(vignette row) itemSetRows = itemSetRows.Skip(1); var problemBuilderNode = ProblemBuilderNodeGenerator.Generate(xml, itemSetRows, new ProblemBuilderNodeSettings { DisplayName = "Item Set " + index, UrlName = CourseConverterHelper.getGuid(itemSetReferenceValue, CourseTypes.Question), ProblemBuilderNodeElement = "problem-builder-block", PbMcqNodeElement = "pb-mcq-block", PbChoiceBlockElement = "pb-choice-block", PbTipBlockElement = "pb-tip-block" }); verticalNode.AppendChild(problemBuilderNode); } else if (itemSetType == "Essay") { string essayMaxPoints = itemSetRows.First().FirstOrDefault(c => c.Type == ExamExcelColumnType.ContainerMaxPoints2).Value; verticalNode.SetAttribute("cfa_type", "essay"); verticalNode.SetAttribute("url_name", CourseConverterHelper.getGuid(itemSetReferenceValue, CourseTypes.Essay)); verticalNode.SetAttribute("essay_max_points", essayMaxPoints); sequentialNode.AppendChild(verticalNode); } } } } } } }
public XmlDocument ConvertExcelToCourseXml(Excel <MainStructureExcelColumn, MainStructureColumnType> mainStructureExcel, Excel <QuestionExcelColumn, QuestionExcelColumnType> questionExcel, Excel <LosExcelColumn, LosExcelColumnType> losExcel, Excel <AcceptanceCriteriaExcelColumn, AcceptanceCriteriaColumnType> acceptanceCriteriaExcel, Excel <ExamExcelColumn, ExamExcelColumnType> ssTestExcel, Excel <ExamExcelColumn, ExamExcelColumnType> progressTestExcel, Excel <ExamExcelColumn, ExamExcelColumnType> MockExamsExcel, Excel <ExamExcelColumn, ExamExcelColumnType> TopicWorkshopExcel, bool setTranscripts) { CourseConverterHelper.generatedQuestionIds = new Dictionary <string, string>(); CourseConverterHelper._generatedGuids = new Dictionary <string, guidRequest>(); XmlDocument xml = new XmlDocument(); var xmlTranscriptAccessor = new XmlTranscriptAccessor(); XmlElement rootNode = xml.CreateElement("xbundle"); xml.AppendChild(rootNode); // Getting Metadata from xml file XmlDocument doc = new XmlDocument(); System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly(); doc.Load(a.GetManifestResourceStream("ExcelParser.MetadataXml.xml")); XmlNode importNode = doc.DocumentElement.SelectSingleNode("/metadata"); XmlNode metadataNode = rootNode.OwnerDocument.ImportNode(importNode, true); rootNode.AppendChild(metadataNode); XmlElement courseNode = xml.CreateElement("course"); courseNode.SetAttribute("advanced_modules", "["annotatable", "videoalpha", "openassessment", "container", "problem-builder-block", "problem-builder-progress-test", "problem-builder-mock-exam", "textualatom"]"); courseNode.SetAttribute("display_name", "CFA Course Default name"); courseNode.SetAttribute("language", "en"); courseNode.SetAttribute("start", ""2016-01-01T00:00:00+00:00""); courseNode.SetAttribute("org", "s"); courseNode.SetAttribute("course", "s"); courseNode.SetAttribute("url_name_orig", "course"); courseNode.SetAttribute("semester", "course"); courseNode.SetAttribute("days_before_review_unlock", "28"); rootNode.AppendChild(courseNode); // Add Introduction Node courseNode.AppendChild(AddIntroductionTopic(xml)); XmlElement chapterNode = null; XmlElement sequentialNode = null; XmlElement previousSequentialNode = null; XmlElement previousChapterNode = null; XmlElement verticalNode = null; XmlElement bandContainerNode = null; XmlElement conceptNameContainerNode = null; bool skip = false; IExcelColumn <MainStructureColumnType> previousStudySessionId = null; IExcelColumn <MainStructureColumnType> previousTopicId = null; foreach (var row in mainStructureExcel.Rows) { var structureTokens = row.First(c => c.Type == MainStructureColumnType.Structure).Value.Split('|'); //Band need to be legal value else skip this row var bandColumn = row.FirstOrDefault(c => c.Type == MainStructureColumnType.Band); if (bandColumn == null || bandColumn.Value == null || bandColumn.Value[0].ToString().ToLower() != "b") { continue; } var atomType = row.FirstOrDefault(c => c.Type == MainStructureColumnType.AtomType); if (atomType == null || !atomType.HaveValue() || !(atomType.Value == "IN" || atomType.Value == "Q" || atomType.Value == "TXT")) { continue; } var atomIdColumn = row.FirstOrDefault(c => c.Type == MainStructureColumnType.AtomId); List <IExcelColumn <QuestionExcelColumnType> > questionRow = null; if (atomType.Value == "Q") { if (atomIdColumn == null || !atomIdColumn.HaveValue()) { continue; } questionRow = questionExcel.Rows.FirstOrDefault(r => r.Any(c => c.Type == QuestionExcelColumnType.QuestionId && c.Value == atomIdColumn.Value)); if (questionRow == null) { continue; } } var topicNameColumn = row.FirstOrDefault(c => c.Type == MainStructureColumnType.TopicName); skip = (chapterNode != null && chapterNode.GetAttribute("display_name") != topicNameColumn.Value) ? false : skip; var topicId = row.FirstOrDefault(c => c.Type == MainStructureColumnType.TopicShortName); if (!skip) { var topicShortName = row.FirstOrDefault(c => c.Type == MainStructureColumnType.TopicShortName); var examPercantage = row.FirstOrDefault(c => c.Type == MainStructureColumnType.ExamPercentage); var cfatopicweight = row.FirstOrDefault(c => c.Type == MainStructureColumnType.CfaTopicWeight); var lockedColumn = row.FirstOrDefault(c => c.Type == MainStructureColumnType.Locked); var demoColumn = row.FirstOrDefault(c => c.Type == MainStructureColumnType.Demo); var colorColumn = row.FirstOrDefault(c => c.Type == MainStructureColumnType.Color); var cfaTypeColumn = row.FirstOrDefault(c => c.Type == MainStructureColumnType.CfaType); var locked = lockedColumn != null && lockedColumn.HaveValue() ? lockedColumn.Value : ""; locked = locked.ToLower() == "true" ? "yes" : "no"; var demo = demoColumn != null && demoColumn.HaveValue() ? demoColumn.Value : ""; demo = demo.ToLower() == "true" ? "yes" : "no"; var description = row.FirstOrDefault(c => c.Type == MainStructureColumnType.Description); chapterNode = xml.CreateElement("chapter"); chapterNode.SetAttribute("display_name", topicNameColumn != null && topicNameColumn.HaveValue() ? topicNameColumn.Value : ""); chapterNode.SetAttribute("url_name", CourseConverterHelper.getGuid(topicShortName.Value, CourseTypes.Topic)); chapterNode.SetAttribute("cfa_short_name", topicShortName != null && topicShortName.HaveValue() ? topicShortName.Value : ""); chapterNode.SetAttribute("exam_percentage", examPercantage != null && examPercantage.HaveValue() ? examPercantage.Value : ""); chapterNode.SetAttribute("cfa_topic_weight", cfatopicweight != null && cfatopicweight.HaveValue() ? cfatopicweight.Value : ""); chapterNode.SetAttribute("description", description != null && description.HaveValue() ? description.Value : ""); chapterNode.SetAttribute("locked", locked); chapterNode.SetAttribute("demo_topic", demo); chapterNode.SetAttribute("topic_color", colorColumn != null && colorColumn.HaveValue() ? colorColumn.Value : ""); chapterNode.SetAttribute("cfa_type", cfaTypeColumn != null && cfaTypeColumn.HaveValue() ? cfaTypeColumn.Value : "topic"); chapterNode.SetAttribute("taxon_id", String.Join("|", structureTokens.Take(2))); courseNode.AppendChild(chapterNode); //ADD TOPIC WORKSHOP if (TopicWorkshopExcel != null && previousChapterNode != null && previousTopicId != null) { AppendTopicWorkshop(xml, previousChapterNode, previousTopicId.Value, TopicWorkshopExcel); } previousChapterNode = chapterNode; previousTopicId = topicId; } var sessionNameColumn = row.FirstOrDefault(c => c.Type == MainStructureColumnType.SessionName); skip = (sequentialNode != null && sequentialNode.GetAttribute("display_name") != sessionNameColumn.Value) ? false : skip; var studySessionId = row.FirstOrDefault(c => c.Type == MainStructureColumnType.StudySessionId); if (!skip) { var studySession = row.FirstOrDefault(c => c.Type == MainStructureColumnType.StudySession); sequentialNode = xml.CreateElement("sequential"); sequentialNode.SetAttribute("display_name", sessionNameColumn != null && sessionNameColumn.HaveValue() ? sessionNameColumn.Value : ""); sequentialNode.SetAttribute("url_name", CourseConverterHelper.getGuid(studySessionId.Value, CourseTypes.StudySession)); sequentialNode.SetAttribute("cfa_short_name", studySession != null && studySession.HaveValue() ? studySession.Value : ""); sequentialNode.SetAttribute("taxon_id", String.Join("|", structureTokens.Take(3))); sequentialNode.SetAttribute("proficiency_target", "70"); chapterNode.AppendChild(sequentialNode); //ADD TEST TO THE BOTTOM OF LAST SESSION NAME NODE if (ssTestExcel != null && previousSequentialNode != null && previousStudySessionId != null) { AppendStudySessionTestQuestions(xml, previousSequentialNode, previousStudySessionId.Value, ssTestExcel); } previousSequentialNode = sequentialNode; previousStudySessionId = studySessionId; } var readingNameColumn = row.FirstOrDefault(c => c.Type == MainStructureColumnType.ReadingName); var downloads1Column = row.FirstOrDefault(c => c.Type == MainStructureColumnType.Downloads1); var downloads2Column = row.FirstOrDefault(c => c.Type == MainStructureColumnType.Downloads2); var downloads = new List <string>(); if (downloads1Column != null && downloads1Column.HaveValue()) { downloads.Add(downloads1Column.Value); } if (downloads2Column != null && downloads2Column.HaveValue()) { downloads.Add(downloads2Column.Value); } skip = (verticalNode != null && verticalNode.GetAttribute("display_name") != readingNameColumn.Value) ? false : skip; if (!skip) { var readingColumn = row.FirstOrDefault(c => c.Type == MainStructureColumnType.Reading); var readingIdColumn = row.FirstOrDefault(c => c.Type == MainStructureColumnType.ReadingId); var readingLockedColumn = row.FirstOrDefault(c => c.Type == MainStructureColumnType.Locked); var readingLocked = readingLockedColumn != null && readingLockedColumn.HaveValue() ? readingLockedColumn.Value : ""; readingLocked = readingLocked.ToLower() == "true" ? "yes" : "no"; verticalNode = xml.CreateElement("vertical"); verticalNode.SetAttribute("display_name", readingNameColumn != null && readingNameColumn.HaveValue() ? readingNameColumn.Value : ""); verticalNode.SetAttribute("url_name", CourseConverterHelper.getGuid(readingIdColumn.Value, CourseTypes.Reading)); verticalNode.SetAttribute("cfa_short_name", readingColumn != null && readingColumn.HaveValue() ? readingColumn.Value : ""); verticalNode.SetAttribute("downloads", JsonConvert.SerializeObject(downloads)); verticalNode.SetAttribute("taxon_id", String.Join("|", structureTokens.Take(4))); verticalNode.SetAttribute("proficiency_target", "70"); verticalNode.SetAttribute("locked", readingLocked); if (losExcel != null) { var outcomes = new List <object>(); var losRows = losExcel.Rows.Where(r => r.Any(c => c.Type == LosExcelColumnType.ReadingRef && c.Value == readingIdColumn.Value) && r.Any(c => c.Type == LosExcelColumnType.TopicRef && c.Value == topicId.Value) && r.Any(c => c.Type == LosExcelColumnType.SessionRef && c.Value == studySessionId.Value) ); foreach (var losRow in losRows) { var cfaAlpfaColumn = losRow.Find(c => c.Type == LosExcelColumnType.CfaAlpha); var losTextColumn = losRow.Find(c => c.Type == LosExcelColumnType.LosText); outcomes.Add(new { text = losTextColumn != null ? losTextColumn.Value : "", letter = cfaAlpfaColumn != null ? cfaAlpfaColumn.Value : "" }); } verticalNode.SetAttribute("outcome_statements", JsonConvert.SerializeObject(outcomes)); } sequentialNode.AppendChild(verticalNode); } var conceptNameColumn = row.FirstOrDefault(c => c.Type == MainStructureColumnType.ConceptName); var conceptIdColumn = row.FirstOrDefault(c => c.Type == MainStructureColumnType.ConceptId); skip = (bandContainerNode != null && bandContainerNode.GetAttribute("display_name") != bandColumn.Value) ? false : skip; if (!skip) { var bandIdColumn = row.FirstOrDefault(c => c.Type == MainStructureColumnType.BandId); bandContainerNode = xml.CreateElement("container"); bandContainerNode.SetAttribute("url_name", CourseConverterHelper.getGuid(bandIdColumn.Value, CourseTypes.Band)); bandContainerNode.SetAttribute("display_name", bandColumn != null && bandColumn.HaveValue() ? bandColumn.Value : ""); bandContainerNode.SetAttribute("xblock-family", "xblock.v1"); bandContainerNode.SetAttribute("container_description", ""); bandContainerNode.SetAttribute("learning_objective_id", ""); bandContainerNode.SetAttribute("taxon_id", String.Join("|", structureTokens.Take(5))); string targetScore = ""; if (acceptanceCriteriaExcel != null) { var acceptanceCriteriaRow = acceptanceCriteriaExcel.Rows.FirstOrDefault( r => r.Any(c => c.Type == AcceptanceCriteriaColumnType.Lo1 && c.Value == conceptIdColumn.Value)); if (acceptanceCriteriaRow != null) { var scoreColumn = acceptanceCriteriaRow.FirstOrDefault(c => c.Type == AcceptanceCriteriaColumnType.TargetScore); if (scoreColumn != null && scoreColumn.HaveValue()) { targetScore = scoreColumn.Value; } } } bandContainerNode.SetAttribute("acceptance_criteria", targetScore); verticalNode.AppendChild(bandContainerNode); } skip = (conceptNameContainerNode != null && conceptNameContainerNode.GetAttribute("learning_objective_id") != conceptIdColumn.Value) ? false : skip; if (!skip) { conceptNameContainerNode = xml.CreateElement("container"); conceptNameContainerNode.SetAttribute("url_name", CourseConverterHelper.getGuid(conceptIdColumn.Value, CourseTypes.Concept)); conceptNameContainerNode.SetAttribute("display_name", conceptNameColumn != null && conceptNameColumn.HaveValue() ? conceptNameColumn.Value : ""); conceptNameContainerNode.SetAttribute("xblock-family", "xblock.v1"); conceptNameContainerNode.SetAttribute("container_description", ""); conceptNameContainerNode.SetAttribute("learning_objective_id", conceptIdColumn != null && conceptIdColumn.HaveValue() ? conceptIdColumn.Value : ""); conceptNameContainerNode.SetAttribute("taxon_id", String.Join("|", structureTokens.Take(6))); bandContainerNode.AppendChild(conceptNameContainerNode); } string atomTaxonId = String.Format("{0}|{1}", String.Join("|", structureTokens.Take(6)), atomIdColumn.Value); //VIDEO if (atomType.Value == "IN") { var atomTitleColumn = row.FirstOrDefault(c => c.Type == MainStructureColumnType.AtomTitle); var itemIdCoclumn = row.FirstOrDefault(c => c.Type == MainStructureColumnType.ItemId); var videoNode = xml.CreateElement("brightcove-video"); videoNode.SetAttribute("url_name", CourseConverterHelper.getGuid(atomIdColumn.Value, CourseTypes.Video)); videoNode.SetAttribute("xblock-family", "xblock.v1"); videoNode.SetAttribute("api_bckey", "AQ~~,AAAELMh4AWE~,vVFFDlX6sNOap1Tww7YwaMvqbQ8TtDoh"); videoNode.SetAttribute("display_name", atomTitleColumn != null && atomTitleColumn.HaveValue() ? atomTitleColumn.Value : ""); videoNode.SetAttribute("api_key", "JqnRdhYvLWNtVJllXkMzGGGTh66uLLmz8JB8YlcZQlC8OX94H4ZXXw.."); videoNode.SetAttribute("text_values", "[]"); videoNode.SetAttribute("api_bctid", itemIdCoclumn.Value); videoNode.SetAttribute("begin_values", "[]"); videoNode.SetAttribute("api_bcpid", "4830051907001"); videoNode.SetAttribute("cfa_type", "video"); videoNode.SetAttribute("atom_id", atomIdColumn.Value); videoNode.SetAttribute("taxon_id", atomTaxonId); if (setTranscripts) { string xmlTranscriptString = ""; if (atomIdColumn != null && atomIdColumn.HaveValue()) { XmlDocument xmlTranscript = xmlTranscriptAccessor.FindVideoTranscript(atomIdColumn.Value); if (xmlTranscript != null) { xmlTranscriptString = xmlTranscript.InnerXml.Replace("<br />", "").Replace("<br/>", ""); } } videoNode.SetAttribute("xml_string", xmlTranscriptString); } else { videoNode.SetAttribute("xml_string", " "); } conceptNameContainerNode.AppendChild(videoNode); } //TEXT else if (atomType.Value == "TXT") { var atomTitleColumn = row.FirstOrDefault(c => c.Type == MainStructureColumnType.AtomTitle); var itemIdCoclumn = row.FirstOrDefault(c => c.Type == MainStructureColumnType.ItemId); var atomText = row.FirstOrDefault(c => c.Type == MainStructureColumnType.AtomBody); var textualNode = xml.CreateElement("textualatom"); textualNode.SetAttribute("url_name", CourseConverterHelper.getGuid(atomIdColumn.Value, CourseTypes.TextAtom)); textualNode.SetAttribute("xblock-family", "xblock.v1"); textualNode.SetAttribute("atom_text", atomText != null && atomText.HaveValue() ? atomText.Value : ""); textualNode.SetAttribute("display_name", atomTitleColumn != null && atomTitleColumn.HaveValue() ? atomTitleColumn.Value : ""); textualNode.SetAttribute("cfa_type", "text"); textualNode.SetAttribute("atom_id", atomIdColumn.Value); textualNode.SetAttribute("taxon_id", atomTaxonId); conceptNameContainerNode.AppendChild(textualNode); } //QUESTION else { var questionDic = CourseConverterHelper.generateQuestionIds(); var problemBuilderNode = xml.CreateElement("problem-builder-block"); var questionIdColumn = questionRow.FirstOrDefault(c => c.Type == QuestionExcelColumnType.QuestionId); var questionColumn = questionRow.FirstOrDefault(c => c.Type == QuestionExcelColumnType.Question); var inFlowColumn = questionRow.FirstOrDefault(c => c.Type == QuestionExcelColumnType.InFlow); string questionValue = questionColumn.HaveValue() ? questionColumn.Value : "Question Missing"; problemBuilderNode.SetAttribute("display_name", Regex.Replace(questionValue, "<.*?>", string.Empty)); problemBuilderNode.SetAttribute("url_name", CourseConverterHelper.getGuid(atomIdColumn.Value, CourseTypes.Question)); problemBuilderNode.SetAttribute("xblock-family", "xblock.v1"); problemBuilderNode.SetAttribute("cfa_type", "question"); problemBuilderNode.SetAttribute("atom_id", atomIdColumn != null && atomIdColumn.HaveValue() ? atomIdColumn.Value : ""); problemBuilderNode.SetAttribute("instruct_assessment", inFlowColumn != null && inFlowColumn.HaveValue() ? inFlowColumn.Value : ""); problemBuilderNode.SetAttribute("taxon_id", atomTaxonId); conceptNameContainerNode.AppendChild(problemBuilderNode); var pbMcqNode = xml.CreateElement("pb-mcq-block"); var correctColumn = questionRow.FirstOrDefault(c => c.Type == QuestionExcelColumnType.Correct); var actualCorrectValues = new List <string>(); if (correctColumn != null && correctColumn.HaveValue()) { var correctValues = correctColumn.Value.Trim().Split(' '); foreach (var correctValue in correctValues) { actualCorrectValues.Add(questionDic[correctValue]); } } pbMcqNode.SetAttribute("url_name", CourseConverterHelper.getNewGuid()); pbMcqNode.SetAttribute("xblock-family", "xblock.v1"); pbMcqNode.SetAttribute("question", questionValue); pbMcqNode.SetAttribute("fitch_question_id", questionIdColumn.Value); pbMcqNode.SetAttribute("correct_choices", (correctColumn != null && correctColumn.Value != null) ? JsonConvert.SerializeObject(actualCorrectValues) : ""); problemBuilderNode.AppendChild(pbMcqNode); var questionIds = new List <string>(); var answer1Column = questionRow.FirstOrDefault(c => c.Type == QuestionExcelColumnType.Answer1); var question1Id = questionDic["A"]; var answer1Node = CourseConverterHelper.GetAnswerNode(xml, answer1Column, question1Id, false); if (answer1Node != null) { pbMcqNode.AppendChild(answer1Node); questionIds.Add(question1Id); } var answer2Column = questionRow.FirstOrDefault(c => c.Type == QuestionExcelColumnType.Answer2); var question2Id = questionDic["B"]; var answer2Node = CourseConverterHelper.GetAnswerNode(xml, answer2Column, question2Id, true); if (answer2Node != null) { pbMcqNode.AppendChild(answer2Node); questionIds.Add(question2Id); } var answer3Column = questionRow.FirstOrDefault(c => c.Type == QuestionExcelColumnType.Answer3); var question3Id = questionDic["C"]; var answer3Node = CourseConverterHelper.GetAnswerNode(xml, answer3Column, question3Id, true); if (answer3Node != null) { pbMcqNode.AppendChild(answer3Node); questionIds.Add(question3Id); } var answer4Column = questionRow.FirstOrDefault(c => c.Type == QuestionExcelColumnType.Answer4); var question4Id = questionDic["D"]; var answer4Node = CourseConverterHelper.GetAnswerNode(xml, answer4Column, question4Id); if (answer4Node != null) { pbMcqNode.AppendChild(answer4Node); questionIds.Add(question4Id); } //tip block var justificationCell = questionRow.FirstOrDefault(c => c.Type == QuestionExcelColumnType.Justification); string justificationValue = (justificationCell != null && justificationCell.HaveValue()) ? justificationCell.Value : ""; var questionTipNode = xml.CreateElement("pb-tip-block"); questionTipNode.SetAttribute("url_name", CourseConverterHelper.getNewGuid()); questionTipNode.SetAttribute("xblock-family", "xblock.v1"); questionTipNode.SetAttribute("values", JsonConvert.SerializeObject(questionIds)); questionTipNode.InnerText = String.Format("{0}", justificationValue); pbMcqNode.AppendChild(questionTipNode); } skip = true; } if (ssTestExcel != null) { AppendStudySessionTestQuestions(xml, previousSequentialNode, previousStudySessionId.Value, ssTestExcel); } if (progressTestExcel != null) { var progressTestChapterNode = ProgressTestExcelConverter.Convert(xml, progressTestExcel); // Insert Progress Test after Equity var equityTopicNode = courseNode.SelectSingleNode("chapter[@cfa_short_name = 'EQ']"); courseNode.InsertAfter(progressTestChapterNode, equityTopicNode); } if (MockExamsExcel != null) { var mockExamChapterNodes = MockExamsExcelConverter.Convert(xml, MockExamsExcel); foreach (var mockExamChapterNode in mockExamChapterNodes) { courseNode.AppendChild(mockExamChapterNode); } } if (TopicWorkshopExcel != null) { AppendTopicWorkshop(xml, previousChapterNode, previousTopicId.Value, TopicWorkshopExcel); } // Add Revision and FinalExam Node courseNode.AppendChild(AddRevisionTopic(xml)); courseNode.AppendChild(AddFinalExamTopic(xml)); LockStudySessionsTopic(courseNode); XmlElement wikiNode = xml.CreateElement("wiki"); wikiNode.SetAttribute("slug", "sf1.sf1.sf1"); courseNode.AppendChild(wikiNode); return(xml); }