(form_json)
return result
Given form JSON, returns question-value pairs, where questions are
    formatted "/data/foo/bar".

    e.g. Question "bar" in group "foo" has value "baz":

    >>> get_form_question_values({'form': {'foo': {'bar': 'baz'}}})
    {'/data/foo/bar': 'baz'}
Given form JSON, returns question-value pairs, where questions are
    formatted "/data/foo/bar".
Given form JSON returns question - value pairs where questions are formatted / data / foo / bar .
def get_form_question_values(form_json):
    """
    Given form JSON, returns question-value pairs, where questions are
    formatted "/data/foo/bar".

    e.g. Question "bar" in group "foo" has value "baz":

    >>> get_form_question_values({'form': {'foo': {'bar': 'baz'}}})
    {'/data/foo/bar': 'baz'}

    """
    _reserved_keys = ('@uiVersion', '@xmlns', '@name', '#type', 'case', 'meta', '@version')

    def _recurse_form_questions(form_dict, path, result_):
        for key, value in form_dict.items():
            if key in _reserved_keys:
                continue
            new_path = path + [key]
            if isinstance(value, list):
                # Repeat group
                for v in value:
                    assert isinstance(v, dict)
                    _recurse_form_questions(v, new_path, result_)
            elif isinstance(value, dict):
                # Group
                _recurse_form_questions(value, new_path, result_)
            else:
                # key is a question and value is its answer
                question = '/'.join((p.decode('utf8') if isinstance(p, bytes) else p for p in new_path))
                result_[question] = value

    result = {}
    _recurse_form_questions(form_json[TAG_FORM], [b'/data'], result)  # "/data" is just convention, hopefully
    # familiar from form builder. The form's data will usually be immediately under "form_json[TAG_FORM]" but not
    # necessarily. If this causes problems we may need a more reliable way to get to it.

    metadata = {}
    if '@xmlns' in form_json[TAG_FORM]:
        metadata['xmlns'] = form_json[TAG_FORM]['@xmlns']
    if TAG_META in form_json[TAG_FORM]:
        metadata.update(form_json[TAG_FORM][TAG_META])
    if 'received_on' in form_json:
        metadata['received_on'] = form_json['received_on']
    if metadata:
        _recurse_form_questions(metadata, [b'/metadata'], result)
    return result
def get_form_question_values ( form_json ) : _reserved_keys = ( '@uiVersion' , '@xmlns' , '@name' , '#type' , 'case' , 'meta' , '@version' ) def _recurse_form_questions ( form_dict , path , result_ ) : for key , value in form_dict . items ( ) : if key in _reserved_keys : continue new_path = path + [ key ] if isinstance ( value , list ) : # Repeat group for v in value : assert isinstance ( v , dict ) _recurse_form_questions ( v , new_path , result_ ) elif isinstance ( value , dict ) : # Group _recurse_form_questions ( value , new_path , result_ ) else : # key is a question and value is its answer question = '/' . join ( ( p . decode ( 'utf8' ) if isinstance ( p , bytes ) else p for p in new_path ) ) result_ [ question ] = value result = { } _recurse_form_questions ( form_json [ TAG_FORM ] , [ b'/data' ] , result ) # "/data" is just convention, hopefully # familiar from form builder. The form's data will usually be immediately under "form_json[TAG_FORM]" but not # necessarily. If this causes problems we may need a more reliable way to get to it. metadata = { } if '@xmlns' in form_json [ TAG_FORM ] : metadata [ 'xmlns' ] = form_json [ TAG_FORM ] [ '@xmlns' ] if TAG_META in form_json [ TAG_FORM ] : metadata . update ( form_json [ TAG_FORM ] [ TAG_META ] ) if 'received_on' in form_json : metadata [ 'received_on' ] = form_json [ 'received_on' ] if metadata : _recurse_form_questions ( metadata , [ b'/metadata' ] , result ) return result