2828 default_is_dynamic ,
2929 print_pyobj_to_json ,
3030)
31- from pyxform .validators .pyxform import parameters_generic , select_from_file
31+ from pyxform .validators .pyxform import parameters_generic , select_from_file , unique_names
3232from pyxform .validators .pyxform import question_types as qt
3333from pyxform .validators .pyxform .android_package_name import validate_android_package_name
3434from pyxform .validators .pyxform .choices import validate_and_clean_choices
@@ -527,6 +527,8 @@ def workbook_to_json(
527527 "control_type" : None ,
528528 "control_name" : None ,
529529 "parent_children" : json_dict .get (constants .CHILDREN ),
530+ "child_names" : set (),
531+ "child_names_lower" : set (),
530532 "row_number" : None ,
531533 }
532534 ]
@@ -539,11 +541,14 @@ def workbook_to_json(
539541 # To check that questions with triggers refer to other questions that exist.
540542 question_names = set ()
541543 trigger_references = []
544+ repeat_names = set ()
542545
543546 # row by row, validate questions, throwing errors and adding warnings where needed.
544547 for row_number , row in enumerate (survey_sheet .data , start = 2 ):
545548 prev_control_type = stack [- 1 ]["control_type" ]
546549 parent_children_array = stack [- 1 ]["parent_children" ]
550+ child_names = stack [- 1 ]["child_names" ]
551+ child_names_lower = stack [- 1 ]["child_names_lower" ]
547552
548553 # Disabled should probably be first
549554 # so the attributes below can be disabled.
@@ -789,9 +794,9 @@ def workbook_to_json(
789794
790795 # Make sure the row has a valid name
791796 if constants .NAME not in row :
792- if row ["type" ] == "note" :
797+ if row [constants . TYPE ] == "note" :
793798 # autogenerate names for notes without them
794- row ["name" ] = "generated_note_name_" + str (row_number )
799+ row [constants . NAME ] = "generated_note_name_" + str (row_number )
795800 else :
796801 raise PyXFormError (
797802 ROW_FORMAT_STRING % row_number + " Question or group with no name."
@@ -805,7 +810,17 @@ def workbook_to_json(
805810 f"{ ROW_FORMAT_STRING % row_number } Invalid question name '{ question_name } '. Names { XML_IDENTIFIER_ERROR_MESSAGE } "
806811 )
807812
808- in_repeat = any (ancestor ["control_type" ] == "repeat" for ancestor in stack )
813+ unique_names .validate_question_group_repeat_name (
814+ row_number = row_number ,
815+ name = question_name ,
816+ seen_names = child_names ,
817+ seen_names_lower = child_names_lower ,
818+ warnings = warnings ,
819+ )
820+
821+ in_repeat = any (
822+ ancestor ["control_type" ] == constants .REPEAT for ancestor in stack
823+ )
809824 validate_entity_saveto (row , row_number , in_repeat , entity_declaration )
810825
811826 # Try to parse question as begin control statement
@@ -820,7 +835,14 @@ def workbook_to_json(
820835 # (so following questions are nested under it)
821836 # until an end command is encountered.
822837 control_type = aliases .control [parse_dict ["type" ]]
823- control_name = question_name
838+
839+ unique_names .validate_repeat_name (
840+ row_number = row_number ,
841+ name = question_name ,
842+ control_type = control_type ,
843+ instance_element_name = json_dict [constants .NAME ],
844+ seen_names = repeat_names ,
845+ )
824846
825847 # Check if the control item has a label, if applicable.
826848 # This label check used to apply to all items, but no longer is
@@ -854,7 +876,7 @@ def workbook_to_json(
854876 new_json_dict [constants .TYPE ] = control_type
855877 child_list = []
856878 new_json_dict [constants .CHILDREN ] = child_list
857- if control_type is constants .LOOP :
879+ if control_type == constants .LOOP :
858880 if not parse_dict .get (constants .LIST_NAME_U ):
859881 # TODO: Perhaps warn and make repeat into a group?
860882 raise PyXFormError (
@@ -932,8 +954,10 @@ def workbook_to_json(
932954 stack .append (
933955 {
934956 "control_type" : control_type ,
935- "control_name" : control_name ,
957+ "control_name" : question_name ,
936958 "parent_children" : child_list ,
959+ "child_names" : set (),
960+ "child_names_lower" : set (),
937961 "row_number" : row_number ,
938962 }
939963 )
0 commit comments