Skip to content

Commit

Permalink
Merge pull request #514 from DavisRayM/circular-reference-error
Browse files Browse the repository at this point in the history
Fix error encountered while converting multi-language XLSForms to JSON
  • Loading branch information
DavisRayM authored Feb 9, 2021
2 parents 1c4a2ed + f2515d3 commit 7e86931
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 4 deletions.
19 changes: 16 additions & 3 deletions pyxform/survey_element.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,19 @@ def get_abbreviated_xpath(self):
else:
return lineage[0].name

def _delete_keys_from_dict(self, dictionary: dict, keys: list):
"""
Deletes a list of keys from a dictionary.
Credits: https://stackoverflow.com/a/49723101
"""
for key in keys:
if key in dictionary:
del dictionary[key]

for value in dictionary.values():
if isinstance(value, dict):
self._delete_keys_from_dict(value, keys)

def to_json_dict(self):
"""
Create a dict copy of this survey element by removing inappropriate
Expand All @@ -227,9 +240,9 @@ def to_json_dict(self):
self.validate()
result = self.copy()
to_delete = ["parent", "question_type_dictionary", "_created"]
for key in to_delete:
if key in result:
del result[key]
# Delete all keys that may cause a "Circular Reference"
# error while converting the result to JSON
self._delete_keys_from_dict(result, to_delete)
children = result.pop("children")
result["children"] = []
for child in children:
Expand Down
3 changes: 2 additions & 1 deletion pyxform/tests/xform2json_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@

from pyxform.builder import create_survey_from_path
from pyxform.tests import utils
from pyxform.tests_v1.pyxform_test_case import PyxformTestCase
from pyxform.xform2json import _try_parse, create_survey_element_from_xml


class DumpAndLoadXForm2JsonTests(utils.XFormTestCase):
class DumpAndLoadXForm2JsonTests(utils.XFormTestCase, PyxformTestCase):

maxDiff = None

Expand Down
43 changes: 43 additions & 0 deletions pyxform/tests_v1/test_xform2json.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
"""
Test XForm2JSON functionality
"""
import json

from pyxform.builder import create_survey_element_from_dict
from pyxform.tests_v1.pyxform_test_case import PyxformTestCase


class TestXForm2JSON(PyxformTestCase):
"""
Test xform2json module
"""

def test_convert_toJSON_multi_language(self):
"""
Test that it's possible to convert XLSForms with multiple languages
to JSON and back into XML without losing any of the required information
"""
md = """
| survey |
| | type | name | label:Eng | label:Fr |
| | text | name | Name | Prénom |
| | select_multiple fruits | fruit | Fruit | Fruit |
| | | | | |
| choices | list name | name | label:Eng | label:Fr |
| | fruits | 1 | Mango | Mangue |
| | fruits | 2 | Orange | Orange |
| | fruits | 3 | Apple | Pomme |
"""

survey = self.md_to_pyxform_survey(
md_raw=md,
kwargs={"id_string": "id", "name": "multi-language", "title": "some-title"},
autoname=False,
)
expected_xml = survey.to_xml()
generated_json = survey.to_json()

survey = create_survey_element_from_dict(json.loads(generated_json))

self.assertEqual(expected_xml, survey.to_xml())

0 comments on commit 7e86931

Please sign in to comment.