diff --git a/pyxform/question.py b/pyxform/question.py
index 7947692b0..7a852f0c5 100644
--- a/pyxform/question.py
+++ b/pyxform/question.py
@@ -134,7 +134,7 @@ def validate(self):
choice.validate()
def xml_control(self):
- assert self.bind["type"] in ["select", "select1", "odk:rank"]
+ assert self.bind["type"] in ["string", "odk:rank"]
survey = self.get_root()
control_dict = self.control.copy()
# Resolve field references in attributes
diff --git a/pyxform/question_type_dictionary.py b/pyxform/question_type_dictionary.py
index 49df1f07e..1611999f9 100644
--- a/pyxform/question_type_dictionary.py
+++ b/pyxform/question_type_dictionary.py
@@ -47,7 +47,7 @@ def generate_new_dict():
},
"add select multiple prompt using": {
"control": {"tag": "select"},
- "bind": {"type": "select"},
+ "bind": {"type": "string"},
},
"add note prompt": {
"control": {"tag": "input"},
@@ -59,7 +59,7 @@ def generate_new_dict():
"text": {"control": {"tag": "input"}, "bind": {"type": "string"}},
"select all that apply from": {
"control": {"tag": "select"},
- "bind": {"type": "select"},
+ "bind": {"type": "string"},
},
"simserial": {
"bind": {
@@ -128,13 +128,13 @@ def generate_new_dict():
}
},
"q location": {"control": {"tag": "input"}, "bind": {"type": "geopoint"}},
- "select one": {"control": {"tag": "select1"}, "bind": {"type": "select1"}},
+ "select one": {"control": {"tag": "select1"}, "bind": {"type": "string"}},
"select one external": {"control": {"tag": "input"}, "bind": {"type": "string"}},
"add image prompt": {
"control": {"tag": "upload", "mediatype": "image/*"},
"bind": {"type": "binary"},
},
- "select all that apply": {"control": {"tag": "select"}, "bind": {"type": "select"}},
+ "select all that apply": {"control": {"tag": "select"}, "bind": {"type": "string"}},
"get end time": {
"bind": {
"jr:preload": "timestamp",
@@ -150,7 +150,7 @@ def generate_new_dict():
"geopoint": {"control": {"tag": "input"}, "bind": {"type": "geopoint"}},
"geoshape": {"control": {"tag": "input"}, "bind": {"type": "geoshape"}},
"geotrace": {"control": {"tag": "input"}, "bind": {"type": "geotrace"}},
- "select multiple from": {"control": {"tag": "select"}, "bind": {"type": "select"}},
+ "select multiple from": {"control": {"tag": "select"}, "bind": {"type": "string"}},
"end time": {
"bind": {
"jr:preload": "timestamp",
@@ -173,8 +173,8 @@ def generate_new_dict():
}
},
"q barcode": {"control": {"tag": "input"}, "bind": {"type": "barcode"}},
- "q select": {"control": {"tag": "select"}, "bind": {"type": "select"}},
- "select one using": {"control": {"tag": "select1"}, "bind": {"type": "select1"}},
+ "q select": {"control": {"tag": "select"}, "bind": {"type": "string"}},
+ "select one using": {"control": {"tag": "select1"}, "bind": {"type": "string"}},
"rank": {"control": {"tag": "odk:rank"}, "bind": {"type": "odk:rank"}},
"image": {
"control": {"tag": "upload", "mediatype": "image/*"},
@@ -234,7 +234,7 @@ def generate_new_dict():
},
"int": {"control": {"tag": "input"}, "bind": {"type": "int"}},
"add barcode prompt": {"control": {"tag": "input"}, "bind": {"type": "barcode"}},
- "select multiple using": {"control": {"tag": "select"}, "bind": {"type": "select"}},
+ "select multiple using": {"control": {"tag": "select"}, "bind": {"type": "string"}},
"q decimal": {"control": {"tag": "input"}, "bind": {"type": "decimal"}},
"end": {
"bind": {
@@ -272,7 +272,7 @@ def generate_new_dict():
"add integer prompt": {"control": {"tag": "input"}, "bind": {"type": "int"}},
"q dateTime": {"control": {"tag": "input"}, "bind": {"type": "dateTime"}},
"date": {"control": {"tag": "input"}, "bind": {"type": "date"}},
- "q select1": {"control": {"tag": "select1"}, "bind": {"type": "select1"}},
+ "q select1": {"control": {"tag": "select1"}, "bind": {"type": "string"}},
"start time": {
"bind": {
"jr:preload": "timestamp",
@@ -293,7 +293,7 @@ def generate_new_dict():
},
"add select one prompt using": {
"control": {"tag": "select1"},
- "bind": {"type": "select1"},
+ "bind": {"type": "string"},
},
"hidden": {"bind": {"type": "string"}},
"uri:subscriberid": {
diff --git a/pyxform/tests/example_xls/instance_xmlns_test.xml b/pyxform/tests/example_xls/instance_xmlns_test.xml
index 27b8a104c..c75defcb1 100644
--- a/pyxform/tests/example_xls/instance_xmlns_test.xml
+++ b/pyxform/tests/example_xls/instance_xmlns_test.xml
@@ -10,7 +10,7 @@
-
+
diff --git a/pyxform/tests/example_xls/spec_test_expected_output.xml b/pyxform/tests/example_xls/spec_test_expected_output.xml
index 11e199df6..c8dfe612a 100644
--- a/pyxform/tests/example_xls/spec_test_expected_output.xml
+++ b/pyxform/tests/example_xls/spec_test_expected_output.xml
@@ -624,25 +624,25 @@
-
+
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/pyxform/tests/example_xls/widgets.xml b/pyxform/tests/example_xls/widgets.xml
index 88ccb5200..ed039194f 100644
--- a/pyxform/tests/example_xls/widgets.xml
+++ b/pyxform/tests/example_xls/widgets.xml
@@ -115,8 +115,8 @@
-
-
+
+
@@ -126,25 +126,25 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
diff --git a/pyxform/tests/fixtures/strings.ini b/pyxform/tests/fixtures/strings.ini
index 8fc6fe41d..a46e9cded 100644
--- a/pyxform/tests/fixtures/strings.ini
+++ b/pyxform/tests/fixtures/strings.ini
@@ -6,7 +6,7 @@ test_answers_can_be_imported_from_xml =
test_question_type_string_binding =
test_select_one_question_multilingual_control = - a
- b
-test_select_one_question_multilingual_binding =
+test_select_one_question_multilingual_binding =
test_simple_integer_question_type_multilingual_control =
test_simple_integer_question_type_multilingual_binding =
test_simple_date_question_type_multilingual_control =
@@ -14,7 +14,7 @@ test_simple_date_question_type_multilingual_binding = Enter numbers only.
test_simple_phone_number_question_type_multilingual_binding =
test_simple_select_all_question_multilingual_control =
-test_simple_select_all_question_multilingual_binding =
+test_simple_select_all_question_multilingual_binding =
test_simple_decimal_question_multilingual_control =
test_simple_decimal_question_multilingual_binding =
diff --git a/pyxform/tests/test_expected_output/attribute_columns_test.xml b/pyxform/tests/test_expected_output/attribute_columns_test.xml
index 219cf4170..87cd6d7ec 100644
--- a/pyxform/tests/test_expected_output/attribute_columns_test.xml
+++ b/pyxform/tests/test_expected_output/attribute_columns_test.xml
@@ -675,7 +675,7 @@
-
+
@@ -684,20 +684,20 @@
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/pyxform/tests/test_expected_output/cascades_old.xml b/pyxform/tests/test_expected_output/cascades_old.xml
index 61b101445..0a45bfdad 100644
--- a/pyxform/tests/test_expected_output/cascades_old.xml
+++ b/pyxform/tests/test_expected_output/cascades_old.xml
@@ -2745,60 +2745,60 @@
-
+
-
-
-
-
+
+
+
+
-
+
-
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
diff --git a/pyxform/tests/test_expected_output/cascading_select_test.xml b/pyxform/tests/test_expected_output/cascading_select_test.xml
index 8bdd59d65..c16d2e3f6 100644
--- a/pyxform/tests/test_expected_output/cascading_select_test.xml
+++ b/pyxform/tests/test_expected_output/cascading_select_test.xml
@@ -101,9 +101,9 @@
-
-
-
+
+
+
diff --git a/pyxform/tests/test_expected_output/flat_xlsform_test.xml b/pyxform/tests/test_expected_output/flat_xlsform_test.xml
index 48b1b5b9c..0d3dd5ec3 100644
--- a/pyxform/tests/test_expected_output/flat_xlsform_test.xml
+++ b/pyxform/tests/test_expected_output/flat_xlsform_test.xml
@@ -631,7 +631,7 @@
-
+
@@ -639,18 +639,18 @@
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/pyxform/tests/test_expected_output/new_cascading_select.xml b/pyxform/tests/test_expected_output/new_cascading_select.xml
index 685fd0e88..7bfb2134d 100644
--- a/pyxform/tests/test_expected_output/new_cascading_select.xml
+++ b/pyxform/tests/test_expected_output/new_cascading_select.xml
@@ -101,9 +101,9 @@
-
-
-
+
+
+
diff --git a/pyxform/tests/test_expected_output/old_cascades.xml b/pyxform/tests/test_expected_output/old_cascades.xml
index f6af6e939..62e8590d6 100644
--- a/pyxform/tests/test_expected_output/old_cascades.xml
+++ b/pyxform/tests/test_expected_output/old_cascades.xml
@@ -101,9 +101,9 @@
-
-
-
+
+
+
diff --git a/pyxform/tests/test_expected_output/or_other.xml b/pyxform/tests/test_expected_output/or_other.xml
index 0a96c2ac3..d3da1c81e 100644
--- a/pyxform/tests/test_expected_output/or_other.xml
+++ b/pyxform/tests/test_expected_output/or_other.xml
@@ -42,9 +42,9 @@
-
+
-
+
diff --git a/pyxform/tests/test_expected_output/repeat_date_test.xml b/pyxform/tests/test_expected_output/repeat_date_test.xml
index 578342c48..39c182879 100644
--- a/pyxform/tests/test_expected_output/repeat_date_test.xml
+++ b/pyxform/tests/test_expected_output/repeat_date_test.xml
@@ -25,8 +25,8 @@
-
-
+
+
diff --git a/pyxform/tests/test_expected_output/search_and_select.xml b/pyxform/tests/test_expected_output/search_and_select.xml
index 2cd1dd656..b0af4c589 100644
--- a/pyxform/tests/test_expected_output/search_and_select.xml
+++ b/pyxform/tests/test_expected_output/search_and_select.xml
@@ -12,7 +12,7 @@
-
+
diff --git a/pyxform/tests/test_expected_output/select_one_external.xml b/pyxform/tests/test_expected_output/select_one_external.xml
index 134e4cec7..a0ef4c84c 100644
--- a/pyxform/tests/test_expected_output/select_one_external.xml
+++ b/pyxform/tests/test_expected_output/select_one_external.xml
@@ -13,7 +13,7 @@
-
+
diff --git a/pyxform/tests/test_expected_output/table-list.xml b/pyxform/tests/test_expected_output/table-list.xml
index 88b45c80e..a2232c02b 100644
--- a/pyxform/tests/test_expected_output/table-list.xml
+++ b/pyxform/tests/test_expected_output/table-list.xml
@@ -47,13 +47,13 @@
-
-
-
+
+
+
-
-
-
+
+
+
diff --git a/pyxform/tests/test_expected_output/widgets.xml b/pyxform/tests/test_expected_output/widgets.xml
index bec649657..833263931 100644
--- a/pyxform/tests/test_expected_output/widgets.xml
+++ b/pyxform/tests/test_expected_output/widgets.xml
@@ -115,8 +115,8 @@
-
-
+
+
@@ -126,25 +126,25 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
diff --git a/pyxform/tests/test_expected_output/xlsform_spec_test.xml b/pyxform/tests/test_expected_output/xlsform_spec_test.xml
index e63a32a9d..6ff582cf9 100644
--- a/pyxform/tests/test_expected_output/xlsform_spec_test.xml
+++ b/pyxform/tests/test_expected_output/xlsform_spec_test.xml
@@ -667,7 +667,7 @@
-
+
@@ -676,19 +676,19 @@
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/pyxform/tests/test_expected_output/xml_escaping.xml b/pyxform/tests/test_expected_output/xml_escaping.xml
index 036c436f6..58a23c760 100644
--- a/pyxform/tests/test_expected_output/xml_escaping.xml
+++ b/pyxform/tests/test_expected_output/xml_escaping.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/pyxform/tests/test_output/cascades_old.xml b/pyxform/tests/test_output/cascades_old.xml
index f31f3d63f..4aeaf4bab 100644
--- a/pyxform/tests/test_output/cascades_old.xml
+++ b/pyxform/tests/test_output/cascades_old.xml
@@ -1871,60 +1871,60 @@
-
+
-
-
-
-
+
+
+
+
-
+
-
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
diff --git a/pyxform/tests/xls2json_tests.py b/pyxform/tests/xls2json_tests.py
index 1bc0710c7..8ae2a256f 100644
--- a/pyxform/tests/xls2json_tests.py
+++ b/pyxform/tests/xls2json_tests.py
@@ -250,7 +250,6 @@ class DefaultToSurveyTest(TestCase):
def test_default_sheet_name_to_survey(self):
xls_path = utils.path_to_text_fixture("survey_no_name.xlsx")
dict_value = xls_to_dict(xls_path)
- print(json.dumps(dict_value))
self.assertTrue("survey" in json.dumps(dict_value))
self.assertTrue("state" in json.dumps(dict_value))
self.assertTrue("The State" in json.dumps(dict_value))
diff --git a/pyxform/tests/xml_tests.py b/pyxform/tests/xml_tests.py
index a4323bcbe..41596e1f2 100644
--- a/pyxform/tests/xml_tests.py
+++ b/pyxform/tests/xml_tests.py
@@ -50,7 +50,7 @@ def test_to_xml(self):
-
+
diff --git a/pyxform/tests_v1/test_sheet_columns.py b/pyxform/tests_v1/test_sheet_columns.py
index 6f506cdf6..f3c67a830 100644
--- a/pyxform/tests_v1/test_sheet_columns.py
+++ b/pyxform/tests_v1/test_sheet_columns.py
@@ -175,7 +175,7 @@ def test_value_and_name(self):
"""
% ({"name_alias": name_alias}),
instance__contains=[""],
- model__contains=[''],
+ model__contains=[''],
xml__contains=[
'',
"yes",
diff --git a/pyxform/xform2json.py b/pyxform/xform2json.py
index 6b20d5996..1ea0c2975 100644
--- a/pyxform/xform2json.py
+++ b/pyxform/xform2json.py
@@ -408,10 +408,12 @@ def _get_question_from_object(self, obj, type=None):
if "autoplay" in obj:
question["control"].update({"autoplay": obj["autoplay"]})
question_params = self._get_question_params_from_bindings(ref)
+
if isinstance(question_params, dict):
for k, v in iter(question_params.items()):
question[k] = v
- # has to come after the above block
+
+ # Some values set from bindings are incorrect or incomplete. Correct them now.
if "mediatype" in obj:
question["type"] = obj["mediatype"].replace("/*", "")
if "item" in obj:
@@ -450,6 +452,11 @@ def _get_question_from_object(self, obj, type=None):
question["type"] = question_type
if type == "trigger":
question["type"] = "acknowledge"
+ if type in [
+ "select1",
+ "select",
+ ]: # Select bind type is 'string' https://github.com/XLSForm/pyxform/issues/168
+ question["type"] = self.QUESTION_TYPES[type]
if question_type == "geopoint" and "hint" in question:
del question["hint"]
if "type" not in question and type: