def convert_instance(in_node, out_node, form_name=None):
    xmlns, name = util.split_tag(in_node.tag)

    if list(in_node):
        if form_name:
            group = et.SubElement(out_node, _('FormData'))
            group.attrib['FormOID'] = form_name
        else:
            group = et.SubElement(out_node, _('ItemGroupData'))
            group.attrib['ItemGroupOID'] = name
            group.attrib['ItemGroupRepeatKey'] = str(1)
            group.attrib['TransactionType'] = 'Insert'

        for child in in_node:
            convert_instance(child, group)
    else:
        value = (in_node.text or '')
        
        # hack to fix time answers
        m = re.match(r'(\d{1,2}):(\d{2}):\d{2}', value)
        if m:
            value = '%02d%02d' % (int(m.group(1)), int(m.group(2)))

        ALLOW_FORCE_COMPLETION = True  # if we allow form to be submitted in incomplete state -- required questions might be blank
        is_required = True # TODO figure out how to pull this from the crf definition; i think currently everything is required so doesn't matter

        if ALLOW_FORCE_COMPLETION and is_required and value == '':
            # strip this answer from the submission or OC will complain about data integrity
            return

        q = et.SubElement(out_node, _('ItemData'))
        q.attrib['ItemOID'] = name
        q.attrib['Value'] = value
def trim_instance(inst_node):
    """remove temporary nodes from instance (starting with '__')"""
    for child in list(inst_node):
        _, tag = util.split_tag(child.tag)
        if tag.startswith('__'):
            inst_node.remove(child)
        else:
            trim_instance(child)
def parse_metadata(root):
    xmlns, tag = util.split_tag(root.tag)
    info = parse_xmlns(xmlns)

    assert info['form'] == tag

    info['xmlns'] = xmlns
    return info