def _add_to_question_response_map(data, repeat_index=None): for index, question in enumerate(data): if question.children: next_index = repeat_index if question.repeat else index _add_to_question_response_map(question.children, repeat_index=next_index) elif question.editable and question.response is not None: # ignore complex and skipped questions value = question.value if question.repeat: if question.repeat not in repeats: repeats[question.repeat] = repeat_index + 1 else: # This is the second or later instance of a repeat group, so it gets [i] notation value = _repeat_question_value(question, repeat_index + 1) # Update first instance of repeat group, which didn't know it needed [i] notation if question.value in question_response_map: first_value = _repeat_question_value( question, repeat_index) question_response_map[ first_value] = question_response_map.pop( question.value) try: index = ordered_question_values.index( question.value) ordered_question_values[index] = first_value except ValueError: pass # Limit data cleaning to nodes that can be found in the response submission. # form_data may contain other data that shouldn't be clean-able, like subcase attributes. try: get_node(instance.get_xml_element(), value, instance.xmlns) except XFormQuestionValueNotFound: continue question_response_map[value] = { 'label': question.label, 'icon': question.icon, 'value': question.response, 'options': [{ 'id': option.value, 'text': option.label, } for option in question.options], } if question.type == 'MSelect': question_response_map[value].update({ 'multiple': True, }) ordered_question_values.append(value)
def _add_to_question_response_map(data, repeat_index=None): for index, question in enumerate(data): if question.children: next_index = repeat_index if question.repeat else index _add_to_question_response_map(question.children, repeat_index=next_index) elif question.editable and question.response is not None: # ignore complex and skipped questions value = question.value if question.repeat: if question.repeat not in repeats: repeats[question.repeat] = repeat_index + 1 else: # This is the second or later instance of a repeat group, so it gets [i] notation value = _repeat_question_value(question, repeat_index + 1) # Update first instance of repeat group, which didn't know it needed [i] notation if question.value in question_response_map: first_value = _repeat_question_value(question, repeat_index) question_response_map[first_value] = question_response_map.pop(question.value) try: index = ordered_question_values.index(question.value) ordered_question_values[index] = first_value except ValueError: pass # Limit data cleaning to nodes that can be found in the response submission. # form_data may contain other data that shouldn't be clean-able, like subcase attributes. try: get_node(instance.get_xml_element(), value, instance.xmlns) except XFormQuestionValueNotFound: continue question_response_map[value] = { 'label': question.label, 'icon': question.icon, 'value': question.response, 'options': [{ 'id': option.value, 'text': option.label, } for option in question.options], } if question.type == 'MSelect': question_response_map[value].update({ 'multiple': True, }) ordered_question_values.append(value)
def test_get_node(self): xml = ''' <data> <something>elephant</something> <twin> <name>romulus</name> </twin> <twin> <name>remus</name> </twin> <has_attribute attr="dirty" /> </data> ''' root = etree.fromstring(xml) self.assertEqual('elephant', get_node(root, '/data/something').text) self.assertEqual('romulus', get_node(root, '/data/twin[1]/name').text) self.assertEqual('remus', get_node(root, '/data/twin[2]/name').text) with self.assertRaises(XFormQuestionValueNotFound): get_node(root, '/data/has_attribute/@dirty')