def download_instances(self, form_id, cursor=0, num_entries=100): self.logger.debug("Starting submissions download for %s" % form_id) if not self._get_response(self.submission_list_url, params={ 'formId': form_id, 'numEntries': num_entries, 'cursor': cursor }): self.logger.error("Fetching %s formId: %s, cursor: %s" % (self.submission_list_url, form_id, cursor)) return response = self._current_response self.logger.debug("Fetching %s formId: %s, cursor: %s" % (self.submission_list_url, form_id, cursor)) try: xml_doc = clean_and_parse_xml(response.content) except ExpatError: return instances = self.get_instances_uuids(xml_doc) path = os.path.join(self.forms_path, form_id, 'instances') for uuid in instances: self.logger.debug("Fetching %s %s submission" % (uuid, form_id)) form_str = u'%(formId)s[@version=null and @uiVersion=null]/'\ u'%(formId)s[@key=%(instanceId)s]' % { 'formId': form_id, 'instanceId': uuid } instance_path = os.path.join(path, uuid.replace(':', ''), 'submission.xml') if not default_storage.exists(instance_path): if self._get_response(self.download_submission_url, params={'formId': form_str}): instance_res = self._current_response content = instance_res.content.strip() default_storage.save(instance_path, ContentFile(content)) else: continue else: instance_res = default_storage.open(instance_path) content = instance_res.read() try: instance_doc = clean_and_parse_xml(content) except ExpatError: continue media_path = os.path.join(path, uuid.replace(':', '')) self.download_media_files(instance_doc, media_path) self.logger.debug("Fetched %s %s submission" % (form_id, uuid)) if xml_doc.getElementsByTagName('resumptionCursor'): rs_node = xml_doc.getElementsByTagName('resumptionCursor')[0] cursor = rs_node.childNodes[0].nodeValue if self.resumption_cursor != cursor: self.resumption_cursor = cursor self.download_instances(form_id, cursor)
def download_instances(self, form_id, cursor=0, num_entries=100): self.logger.debug("Starting submissions download for %s" % form_id) if not self._get_response(self.submission_list_url, params={'formId': form_id, 'numEntries': num_entries, 'cursor': cursor}): self.logger.error("Fetching %s formId: %s, cursor: %s" % (self.submission_list_url, form_id, cursor)) return response = self._current_response self.logger.debug("Fetching %s formId: %s, cursor: %s" % (self.submission_list_url, form_id, cursor)) try: xml_doc = clean_and_parse_xml(response.content) except ExpatError: return instances = self.get_instances_uuids(xml_doc) path = os.path.join(self.forms_path, form_id, 'instances') for uuid in instances: self.logger.debug("Fetching %s %s submission" % (uuid, form_id)) form_str = u'%(formId)s[@version=null and @uiVersion=null]/'\ u'%(formId)s[@key=%(instanceId)s]' % { 'formId': form_id, 'instanceId': uuid } instance_path = os.path.join(path, uuid.replace(':', ''), 'submission.xml') if not default_storage.exists(instance_path): if self._get_response(self.download_submission_url, params={'formId': form_str}): instance_res = self._current_response content = instance_res.content.strip() default_storage.save(instance_path, ContentFile(content)) else: continue else: instance_res = default_storage.open(instance_path) content = instance_res.read() try: instance_doc = clean_and_parse_xml(content) except ExpatError: continue media_path = os.path.join(path, uuid.replace(':', '')) self.download_media_files(instance_doc, media_path) self.logger.debug("Fetched %s %s submission" % (form_id, uuid)) if xml_doc.getElementsByTagName('resumptionCursor'): rs_node = xml_doc.getElementsByTagName('resumptionCursor')[0] cursor = rs_node.childNodes[0].nodeValue if self.resumption_cursor != cursor: self.resumption_cursor = cursor self.download_instances(form_id, cursor)
def download_xforms(self, include_instances=False): # fetch formList response = requests.get(self.form_list_url, auth=self.auth) self.logger.debug('Successfull fetched %s.' % self.form_list_url) xml_doc = clean_and_parse_xml(response.content) forms = [] for childNode in xml_doc.childNodes: if childNode.nodeName == 'xforms': for xformNode in childNode.childNodes: if xformNode.nodeName == 'xform': form_id = xformNode.getElementsByTagName('formID')[0] id_string = form_id.childNodes[0].nodeValue form_name = xformNode.getElementsByTagName('name')[0] name = form_name.childNodes[0].nodeValue if name.startswith('Crowd/'): # skip crowdforms: very formhub specific continue d = xformNode.getElementsByTagName('downloadUrl')[0] download_url = d.childNodes[0].nodeValue m = xformNode.getElementsByTagName('manifestUrl')[0] manifest_url = m.childNodes[0].nodeValue forms.append((id_string, download_url, manifest_url)) # download each xform if forms: for id_string, download_url, manifest_url in forms: form_path = os.path.join(self.forms_path, id_string, '%s.xml' % id_string) if not default_storage.exists(form_path): form_res = requests.get(download_url, auth=self.auth) content = ContentFile(form_res.content.strip()) default_storage.save(form_path, content) else: form_res = default_storage.open(form_path) content = form_res.read() self.logger.debug("Fetched %s." % download_url) manifest_res = requests.get(manifest_url, auth=self.auth) try: manifest_doc = clean_and_parse_xml(manifest_res.content) except ExpatError: continue manifest_path = os.path.join(self.forms_path, id_string, 'form-media') self.logger.debug("Downloading media files for %s" % id_string) self.download_media_files(manifest_doc, manifest_path) if include_instances: self.logger.debug("Downloading submissions for %s" % id_string) self.download_instances(id_string) self.logger.debug("Done downloading submissions for %s" % id_string)
def check_custom_form_validation(xml, request, username): TAG_TO_PARSE = '_Tubewell_ID' FORM_ID_TO_CHECK = str('tubewell_arsenic_level') tubewell_id = 0 form_id = None valid = False FormXMLTree = clean_and_parse_xml(xml) collection = FormXMLTree.documentElement if collection.hasAttribute("id"): form_id = collection.getAttribute("id") #print "Root element : %s " % collection.getAttribute("id") if form_id != FORM_ID_TO_CHECK: return True all_Tag_to_parse = collection.getElementsByTagName( "group_arsenic_level_group") for ids in all_Tag_to_parse: tubewell_id = ids.getElementsByTagName(TAG_TO_PARSE)[0] tubewell_id = tubewell_id.childNodes[0].data #print "Tubewell_ID: %s" % tubewell_id cursor = connection.cursor() registration_query = "SELECT (json->>'Tubewell_ID') AS identification FROM logger_instance WHERE xform_id=18" cursor.execute(registration_query) fetchVal = cursor.fetchall() for each in fetchVal: tmpval = int(each[0]) # print 'tmpval ' + tmpval if tmpval == int(tubewell_id): # print 'each for: '+ each[0] valid = True #print 'fetchVal: '+fetchVal #print 'valid : '+ str(valid) return valid
def inject_instanceid(xml_str, uuid): if get_uuid_from_xml(xml_str) is None: xml = clean_and_parse_xml(xml_str) children = xml.childNodes if children.length == 0: raise ValueError(_("XML string must have a survey element.")) # check if we have a meta tag survey_node = children.item(0) meta_tags = [ n for n in survey_node.childNodes if n.nodeType == Node.ELEMENT_NODE and n.tagName.lower() == "meta"] if len(meta_tags) == 0: meta_tag = xml.createElement("meta") xml.documentElement.appendChild(meta_tag) else: meta_tag = meta_tags[0] # check if we have an instanceID tag uuid_tags = [ n for n in meta_tag.childNodes if n.nodeType == Node.ELEMENT_NODE and n.tagName == "instanceID"] if len(uuid_tags) == 0: uuid_tag = xml.createElement("instanceID") meta_tag.appendChild(uuid_tag) else: uuid_tag = uuid_tags[0] # insert meta and instanceID text_node = xml.createTextNode(u"uuid:%s" % uuid) uuid_tag.appendChild(text_node) return xml.toxml() return xml_str
def inject_instanceid(xml_str, uuid): if get_uuid_from_xml(xml_str) is None: xml = clean_and_parse_xml(xml_str) children = xml.childNodes if children.length == 0: raise ValueError(_("XML string must have a survey element.")) # check if we have a meta tag survey_node = children.item(0) meta_tags = [ n for n in survey_node.childNodes if n.nodeType == Node.ELEMENT_NODE and n.tagName.lower() == "meta" ] if len(meta_tags) == 0: meta_tag = xml.createElement("meta") xml.documentElement.appendChild(meta_tag) else: meta_tag = meta_tags[0] # check if we have an instanceID tag uuid_tags = [ n for n in meta_tag.childNodes if n.nodeType == Node.ELEMENT_NODE and n.tagName == "instanceID" ] if len(uuid_tags) == 0: uuid_tag = xml.createElement("instanceID") meta_tag.appendChild(uuid_tag) else: uuid_tag = uuid_tags[0] # insert meta and instanceID text_node = xml.createTextNode(u"uuid:%s" % uuid) uuid_tag.appendChild(text_node) return xml.toxml() return xml_str
def test_edited_submission(self): """ Test submissions that have been edited """ xml_submission_file_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "..", "fixtures", "tutorial", "instances", "tutorial_2012-06-27_11-27-53_w_uuid.xml", ) num_instances_history = InstanceHistory.objects.count() num_instances = Instance.objects.count() query_args = { "username": self.user.username, "id_string": self.xform.id_string, "query": "{}", "fields": "[]", "sort": "[]", "count": True, } cursor = ParsedInstance.query_mongo(**query_args) num_mongo_instances = cursor[0]["count"] # make first submission self._make_submission(xml_submission_file_path) self.assertEqual(self.response.status_code, 201) self.assertEqual(Instance.objects.count(), num_instances + 1) # no new record in instances history self.assertEqual(InstanceHistory.objects.count(), num_instances_history) # check count of mongo instances after first submission cursor = ParsedInstance.query_mongo(**query_args) self.assertEqual(cursor[0]["count"], num_mongo_instances + 1) # edited submission xml_submission_file_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "..", "fixtures", "tutorial", "instances", "tutorial_2012-06-27_11-27-53_w_uuid_edited.xml", ) self._make_submission(xml_submission_file_path) self.assertEqual(self.response.status_code, 201) # we must have the same number of instances self.assertEqual(Instance.objects.count(), num_instances + 1) # should be a new record in instances history self.assertEqual(InstanceHistory.objects.count(), num_instances_history + 1) cursor = ParsedInstance.query_mongo(**query_args) self.assertEqual(cursor[0]["count"], num_mongo_instances + 1) # make sure we edited the mongo db record and NOT added a new row query_args["count"] = False cursor = ParsedInstance.query_mongo(**query_args) record = cursor[0] with open(xml_submission_file_path, "r") as f: xml_str = f.read() xml_str = clean_and_parse_xml(xml_str).toxml() edited_name = re.match(ur"^.+?<name>(.+?)</name>", xml_str).groups()[0] self.assertEqual(record["name"], edited_name)
def download_xforms(self, include_instances=False): # fetch formList response = requests.get(self.form_list_url, auth=self.auth) self.logger.debug("Successfull fetched %s." % self.form_list_url) xml_doc = clean_and_parse_xml(response.content) forms = [] for childNode in xml_doc.childNodes: if childNode.nodeName == "xforms": for xformNode in childNode.childNodes: if xformNode.nodeName == "xform": form_id = xformNode.getElementsByTagName("formID")[0] id_string = form_id.childNodes[0].nodeValue form_name = xformNode.getElementsByTagName("name")[0] name = form_name.childNodes[0].nodeValue if name.startswith("Crowd/"): # skip crowdforms: very formhub specific continue d = xformNode.getElementsByTagName("downloadUrl")[0] download_url = d.childNodes[0].nodeValue m = xformNode.getElementsByTagName("manifestUrl")[0] manifest_url = m.childNodes[0].nodeValue forms.append((id_string, download_url, manifest_url)) # download each xform if forms: for id_string, download_url, manifest_url in forms: form_path = os.path.join(self.forms_path, id_string, "%s.xml" % id_string) if not default_storage.exists(form_path): form_res = requests.get(download_url, auth=self.auth) content = ContentFile(form_res.content.strip()) default_storage.save(form_path, content) else: form_res = default_storage.open(form_path) content = form_res.read() self.logger.debug("Fetched %s." % download_url) manifest_res = requests.get(manifest_url, auth=self.auth) try: manifest_doc = clean_and_parse_xml(manifest_res.content) except ExpatError: continue manifest_path = os.path.join(self.forms_path, id_string, "form-media") self.logger.debug("Downloading media files for %s" % id_string) self.download_media_files(manifest_doc, manifest_path) if include_instances: self.logger.debug("Downloading submissions for %s" % id_string) self.download_instances(id_string) self.logger.debug("Done downloading submissions for %s" % id_string)
def get_case_id_string_from_xml_str(xml_str): xml_obj = clean_and_parse_xml(xml_str) try: case_id = xml_obj.getElementsByTagName("case_id")[0].firstChild.data except: case_id = None return case_id
def test_edited_submission(self): """ Test submissions that have been edited """ xml_submission_file_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "..", "fixtures", "tutorial", "instances", "tutorial_2012-06-27_11-27-53_w_uuid.xml" ) num_instances_history = InstanceHistory.objects.count() num_instances = Instance.objects.count() query_args = { 'username': self.user.username, 'id_string': self.xform.id_string, 'query': '{}', 'fields': '[]', 'sort': '[]', 'count': True } cursor = ParsedInstance.query_mongo(**query_args) num_mongo_instances = cursor[0]['count'] # make first submission self._make_submission(xml_submission_file_path) self.assertEqual(self.response.status_code, 201) self.assertEqual(Instance.objects.count(), num_instances + 1) # no new record in instances history self.assertEqual( InstanceHistory.objects.count(), num_instances_history) # check count of mongo instances after first submission cursor = ParsedInstance.query_mongo(**query_args) self.assertEqual(cursor[0]['count'], num_mongo_instances + 1) # edited submission xml_submission_file_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "..", "fixtures", "tutorial", "instances", "tutorial_2012-06-27_11-27-53_w_uuid_edited.xml" ) client = DigestClient() client.set_authorization('bob', 'bob', 'Digest') self._make_submission(xml_submission_file_path, client=client) self.assertEqual(self.response.status_code, 201) # we must have the same number of instances self.assertEqual(Instance.objects.count(), num_instances + 1) # should be a new record in instances history self.assertEqual( InstanceHistory.objects.count(), num_instances_history + 1) cursor = ParsedInstance.query_mongo(**query_args) self.assertEqual(cursor[0]['count'], num_mongo_instances + 1) # make sure we edited the mongo db record and NOT added a new row query_args['count'] = False cursor = ParsedInstance.query_mongo(**query_args) record = cursor[0] with open(xml_submission_file_path, "r") as f: xml_str = f.read() xml_str = clean_and_parse_xml(xml_str).toxml() edited_name = re.match(ur"^.+?<name>(.+?)</name>", xml_str).groups()[0] self.assertEqual(record['name'], edited_name)
def call_parave_ai_reg_api(xml, request, username, user): FormXMLTree = clean_and_parse_xml(xml) collection = FormXMLTree.documentElement if collection.hasAttribute("id"): form_id = collection.getAttribute("id") print form_id if form_id == "paravet_ai_technitian_reg": mobile = collection.getElementsByTagName( "mobile")[0].__dict__['childNodes'][0].data paravet_name = collection.getElementsByTagName( "name")[0].__dict__['childNodes'][0].data occupation = collection.getElementsByTagName( "occupation")[0].__dict__['childNodes'][0].data print mobile #print paravet_name #print occupation # 1=para,farmer=3,ai=2 if occupation == '1': _occupation = 'Paravet' elif occupation == '2': _occupation = 'AI Technicians' elif occupation == '3': _occupation = 'Farmer' else: _occupation = '' views_api.register_as_paravet_ai(paravet_name, mobile, _occupation, user.id) if form_id == "farmer_registration": password = views_api.id_generator() #password = '******' mobile = collection.getElementsByTagName( "mobile")[0].__dict__['childNodes'][0].data farmer_name = collection.getElementsByTagName( "name")[0].__dict__['childNodes'][0].data occupation = 'Farmer' #print occupation submitted_data = {} submitted_data['username'] = mobile #user = User.objects.filter(username=data['phone']).first() # password = id_generator() #password = '******' # when login submitted_data['contact_number'] = mobile submitted_data['first_name'] = farmer_name submitted_data['password'] = password submitted_data['password_repeat'] = password submitted_data['organisation_name'] = 397 user_form = UserForm(data=submitted_data) profile_form = UserProfileForm(data=submitted_data) views_api.save_user_details(user_form, profile_form, submitted_data, farmer_name, mobile, occupation, user.id) return 0
def test_uuid_injection_in_cascading_select(self): """ Test that the uuid is injected in the right instance node for forms with a cascading select """ pre_count = XForm.objects.count() xls_path = os.path.join(self.this_directory, "fixtures", "cascading_selects", "new_cascading_select.xls") file_name, file_ext = os.path.splitext(os.path.split(xls_path)[1]) self.response = TestBase._publish_xls_file(self, xls_path) post_count = XForm.objects.count() self.assertEqual(post_count, pre_count + 1) xform = XForm.objects.latest('date_created') # check that the uuid is within the main instance/ # the one without an id attribute xml = clean_and_parse_xml(xform.xml) # check for instance nodes that are direct children of the model node model_node = xml.getElementsByTagName("model")[0] instance_nodes = [ node for node in model_node.childNodes if node.nodeType == Node.ELEMENT_NODE and node.tagName.lower() == "instance" and not node.hasAttribute("id") ] self.assertEqual(len(instance_nodes), 1) instance_node = instance_nodes[0] # get the first element whose id attribute is equal to our form's # id_string form_nodes = [ node for node in instance_node.childNodes if node.nodeType == Node.ELEMENT_NODE and node.getAttribute("id") == xform.id_string ] form_node = form_nodes[0] # find the formhub node that has a uuid child node formhub_nodes = form_node.getElementsByTagName("formhub") self.assertEqual(len(formhub_nodes), 1) uuid_nodes = formhub_nodes[0].getElementsByTagName("uuid") self.assertEqual(len(uuid_nodes), 1) # check for the calculate bind calculate_bind_nodes = [ node for node in model_node.childNodes if node.nodeType == Node.ELEMENT_NODE and node.tagName == "bind" and node.getAttribute("nodeset") == "/%s/formhub/uuid" % xform.id_string ] self.assertEqual(len(calculate_bind_nodes), 1) calculate_bind_node = calculate_bind_nodes[0] self.assertEqual(calculate_bind_node.getAttribute("calculate"), "'%s'" % xform.uuid)
def test_edited_submission(self): """ Test submissions that have been edited """ xml_submission_file_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "..", "fixtures", "tutorial", "instances", "tutorial_2012-06-27_11-27-53_w_uuid.xml") num_instances_history = InstanceHistory.objects.count() num_instances = Instance.objects.count() query_args = { 'username': self.user.username, 'id_string': self.xform.id_string, 'query': '{}', 'fields': '[]', 'sort': '[]', 'count': True } cursor = ParsedInstance.query_mongo(**query_args) num_mongo_instances = cursor[0]['count'] # make first submission self._make_submission(xml_submission_file_path) self.assertEqual(self.response.status_code, 201) self.assertEqual(Instance.objects.count(), num_instances + 1) # no new record in instances history self.assertEqual(InstanceHistory.objects.count(), num_instances_history) # check count of mongo instances after first submission cursor = ParsedInstance.query_mongo(**query_args) self.assertEqual(cursor[0]['count'], num_mongo_instances + 1) # edited submission xml_submission_file_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "..", "fixtures", "tutorial", "instances", "tutorial_2012-06-27_11-27-53_w_uuid_edited.xml") client = DigestClient() client.set_authorization('bob', 'bob', 'Digest') self._make_submission(xml_submission_file_path, client=client) self.assertEqual(self.response.status_code, 201) # we must have the same number of instances self.assertEqual(Instance.objects.count(), num_instances + 1) # should be a new record in instances history self.assertEqual(InstanceHistory.objects.count(), num_instances_history + 1) cursor = ParsedInstance.query_mongo(**query_args) self.assertEqual(cursor[0]['count'], num_mongo_instances + 1) # make sure we edited the mongo db record and NOT added a new row query_args['count'] = False cursor = ParsedInstance.query_mongo(**query_args) record = cursor[0] with open(xml_submission_file_path, "r") as f: xml_str = f.read() xml_str = clean_and_parse_xml(xml_str).toxml() edited_name = re.match(r"^.+?<name>(.+?)</name>", xml_str).groups()[0] self.assertEqual(record['name'], edited_name)
def download_instances(self, form_id, cursor=0, num_entries=100): response = requests.get( self.submission_list_url, auth=self.auth, params={"formId": form_id, "numEntries": num_entries, "cursor": cursor}, ) self.logger.debug("Fetching %s formId: %s, cursor: %s" % (self.submission_list_url, form_id, cursor)) try: xml_doc = clean_and_parse_xml(response.content) except ExpatError: return instances = self.get_instances_uuids(xml_doc) path = os.path.join(self.forms_path, form_id, "instances") for uuid in instances: self.logger.debug("Fetching %s %s submission" % (uuid, form_id)) form_str = u"%(formId)s[@version=null and @uiVersion=null]/" u"%(formId)s[@key=%(instanceId)s]" % { "formId": form_id, "instanceId": uuid, } instance_path = os.path.join(path, uuid.replace(":", ""), "submission.xml") if not default_storage.exists(instance_path): instance_res = requests.get(self.download_submission_url, auth=self.auth, params={"formId": form_str}) content = instance_res.content.strip() default_storage.save(instance_path, ContentFile(content)) else: instance_res = default_storage.open(instance_path) content = instance_res.read() try: instance_doc = clean_and_parse_xml(content) except ExpatError: continue media_path = os.path.join(path, uuid.replace(":", "")) self.download_media_files(instance_doc, media_path) self.logger.debug("Fetched %s %s submission" % (form_id, uuid)) if xml_doc.getElementsByTagName("resumptionCursor"): rs_node = xml_doc.getElementsByTagName("resumptionCursor")[0] cursor = rs_node.childNodes[0].nodeValue if self.resumption_cursor != cursor: self.resumption_cursor = cursor self.download_instances(form_id, cursor)
def test_xml_repeated_nodes_to_dict(self): xml_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../fixtures/repeated_nodes.xml") json_file = os.path.join( os.path.dirname(os.path.abspath(__file__)), "../fixtures/repeated_nodes_expected_results.json") with open(xml_file) as file: xml_dict = _xml_node_to_dict(clean_and_parse_xml(file.read())) self.assertTrue(xml_dict['#document']['RW_OUNIS_2016']['S2A']) self.assertEqual( 3, len(xml_dict['#document']['RW_OUNIS_2016']['S2A'])) with open(json_file) as file: self.assertEqual(json.loads(file.read()), xml_dict)
def _get_form_list(self, xml_text): xml_doc = clean_and_parse_xml(xml_text) forms = [] for childNode in xml_doc.childNodes: if childNode.nodeName == 'xforms': for xformNode in childNode.childNodes: if xformNode.nodeName == 'xform': id_string = node_value(xformNode, 'formID') download_url = node_value(xformNode, 'downloadUrl') manifest_url = node_value(xformNode, 'manifestUrl') forms.append((id_string, download_url, manifest_url)) return forms
def download_manifest(self, manifest_url, id_string): if self._get_response(manifest_url): manifest_res = self._current_response try: manifest_doc = clean_and_parse_xml(manifest_res.content) except ExpatError: return manifest_path = os.path.join( self.forms_path, id_string, 'form-media') self.logger.debug("Downloading media files for %s" % id_string) self.download_media_files(manifest_doc, manifest_path)
def test_uuid_injection_in_cascading_select(self): """Test that the uuid is injected in the right instance node for forms with a cascading select""" pre_count = XForm.objects.count() xls_path = os.path.join( self.this_directory, "fixtures", "cascading_selects", "new_cascading_select.xls") file_name, file_ext = os.path.splitext(os.path.split(xls_path)[1]) self.response = TestBase._publish_xls_file(self, xls_path) post_count = XForm.objects.count() self.assertEqual(post_count, pre_count + 1) xform = XForm.objects.latest('date_created') # check that the uuid is within the main instance/ # the one without an id attribute xml = clean_and_parse_xml(xform.xml) # check for instance nodes that are direct children of the model node model_node = xml.getElementsByTagName("model")[0] instance_nodes = [node for node in model_node.childNodes if node.nodeType == Node.ELEMENT_NODE and node.tagName.lower() == "instance" and not node.hasAttribute("id")] self.assertEqual(len(instance_nodes), 1) instance_node = instance_nodes[0] # get the first element whose id attribute is equal to our form's # id_string form_nodes = [node for node in instance_node.childNodes if node.nodeType == Node.ELEMENT_NODE and node.getAttribute("id") == xform.id_string] form_node = form_nodes[0] # find the formhub node that has a uuid child node formhub_nodes = form_node.getElementsByTagName("formhub") self.assertEqual(len(formhub_nodes), 1) uuid_nodes = formhub_nodes[0].getElementsByTagName("uuid") self.assertEqual(len(uuid_nodes), 1) # check for the calculate bind calculate_bind_nodes = [node for node in model_node.childNodes if node.nodeType == Node.ELEMENT_NODE and node.tagName == "bind" and node.getAttribute("nodeset") == "/%s/formhub/uuid" % file_name] self.assertEqual(len(calculate_bind_nodes), 1) calculate_bind_node = calculate_bind_nodes[0] self.assertEqual( calculate_bind_node.getAttribute("calculate"), "'%s'" % xform.uuid)
def is_exist_farmer_paravet_ait(xml, request, username, user): flag = 0 FormXMLTree = clean_and_parse_xml(xml) collection = FormXMLTree.documentElement if collection.hasAttribute("id"): form_id = collection.getAttribute("id") print form_id if form_id == "farmer_registration": mobile = collection.getElementsByTagName( "mobile")[0].__dict__['childNodes'][0].data if views_api.check_duplicate_farmer(mobile) == 0: flag = 0 else: flag = 1 return flag
def test_xml_repeated_group_to_dict(self): xml_file = os.path.join( os.path.dirname(os.path.abspath(__file__)), "../fixtures/repeated_group/repeated_group.xml") json_file = os.path.join( os.path.dirname(os.path.abspath(__file__)), "../fixtures/repeated_group/repeated_group.json") with open(xml_file) as file: dict_ = _xml_node_to_dict(clean_and_parse_xml(file.read())) self.assertTrue(dict_['#document']['form']['question_group']) self.assertEqual(2, len(dict_['#document']['form']['question_group'])) with open(json_file) as jfile: import json self.assertEqual(jfile.read(), json.dumps(dict_))
def test_xml_repeated_nodes_to_dict(self): xml_file = os.path.join( os.path.dirname(os.path.abspath(__file__)), "../fixtures/repeated_nodes.xml" ) json_file = os.path.join( os.path.dirname(os.path.abspath(__file__)), "../fixtures/repeated_nodes_expected_results.json" ) with open(xml_file) as file: xml_dict = _xml_node_to_dict(clean_and_parse_xml(file.read())) self.assertTrue(xml_dict['#document']['RW_OUNIS_2016']['S2A']) self.assertEqual(3, len( xml_dict['#document']['RW_OUNIS_2016']['S2A'])) with open(json_file) as file: self.assertEqual(json.loads(file.read()), xml_dict)
def test_xml_repeated_group_to_dict(self): xml_file = os.path.join( os.path.dirname(os.path.abspath(__file__)), "../fixtures/repeated_group/repeated_group.xml" ) json_file = os.path.join( os.path.dirname(os.path.abspath(__file__)), "../fixtures/repeated_group/repeated_group.json" ) with open(xml_file) as file: dict_ = _xml_node_to_dict(clean_and_parse_xml(file.read())) self.assertTrue(dict_['#document']['form']['question_group']) self.assertEqual(2, len(dict_['#document']['form']['question_group'])) with open(json_file) as jfile: import json self.assertEqual(jfile.read(), json.dumps(dict_))
def _upload_instance(self, xml_file, instance_dir_path, files): xml_doc = clean_and_parse_xml(xml_file.read()) xml = StringIO() de_node = xml_doc.documentElement for node in de_node.firstChild.childNodes: xml.write(node.toxml()) new_xml_file = ContentFile(xml.getvalue()) new_xml_file.content_type = "text/xml" xml.close() attachments = [] for attach in de_node.getElementsByTagName("mediaFile"): filename_node = attach.getElementsByTagName("filename") filename = filename_node[0].childNodes[0].nodeValue if filename in files: file_obj = default_storage.open(os.path.join(instance_dir_path, filename)) mimetype, encoding = mimetypes.guess_type(file_obj.name) media_obj = django_file(file_obj, "media_files[]", mimetype) attachments.append(media_obj) create_instance(self.user.username, new_xml_file, attachments)
def send_push_noti_after_profile_update(xml): FormXMLTree = clean_and_parse_xml(xml) collection = FormXMLTree.documentElement if collection.hasAttribute("id"): form_id = collection.getAttribute("id") print form_id if form_id == "farmer_profile_update": mobile = collection.getElementsByTagName( "mobile")[0].__dict__['childNodes'][0].data views.send_push_message(mobile, 5, 'Profile update', 'Your profile has been updated as Farmer', '', mobile, '') if form_id == "paravet_at_tech_profile_update": mobile = collection.getElementsByTagName( "mobile")[0].__dict__['childNodes'][0].data views.send_push_message(mobile, 5, 'Profile update', 'Your profile has been updated as AI/Paravet', '', mobile, '') print 'push notificatiob ended*************************************'
def get_id_string_from_xml_str(xml_str): xml_obj = clean_and_parse_xml(xml_str) root_node = xml_obj.documentElement id_string = root_node.getAttribute(u"id") if len(id_string) == 0: # may be hidden in submission/data/id_string elems = root_node.getElementsByTagName('data') for data in elems: for child in data.childNodes: id_string = data.childNodes[0].getAttribute('id') if len(id_string) > 0: break if len(id_string) > 0: break return id_string
def _upload_instance(self, xml_file, instance_dir_path, files): xml_doc = clean_and_parse_xml(xml_file.read()) xml = StringIO() de_node = xml_doc.documentElement for node in de_node.firstChild.childNodes: xml.write(node.toxml()) new_xml_file = ContentFile(xml.getvalue()) new_xml_file.content_type = 'text/xml' xml.close() attachments = [] for attach in de_node.getElementsByTagName('mediaFile'): filename_node = attach.getElementsByTagName('filename') filename = filename_node[0].childNodes[0].nodeValue if filename in files: file_obj = default_storage.open( os.path.join(instance_dir_path, filename)) mimetype, encoding = mimetypes.guess_type(file_obj.name) media_obj = django_file(file_obj, 'media_files[]', mimetype) attachments.append(media_obj) create_instance(self.user.username, new_xml_file, attachments)
def retrieve(self, request, *args, **kwargs): self.object = self.get_object() xml_obj = clean_and_parse_xml(self.object.xml) submission_xml_root_node = xml_obj.documentElement submission_xml_root_node.setAttribute('instanceID', u'uuid:%s' % self.object.uuid) submission_xml_root_node.setAttribute( 'submissionDate', self.object.date_created.isoformat()) data = { 'submission_data': submission_xml_root_node.toxml(), 'media_files': Attachment.objects.filter(instance=self.object), 'host': request.build_absolute_uri().replace(request.get_full_path(), '') } return Response(data, headers=get_openrosa_headers(request, location=False), template_name='downloadSubmission.xml')
def test_edited_submission_require_auth(self): """ Test submissions that have been edited """ xml_submission_file_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "..", "fixtures", "tutorial", "instances", "tutorial_2012-06-27_11-27-53_w_uuid.xml") # require authentication self.user.profile.require_auth = True self.user.profile.save() num_instances_history = InstanceHistory.objects.count() num_instances = Instance.objects.count() query_args = { 'xform': self.xform, 'query': '{}', 'fields': '[]', 'count': True } cursor = ParsedInstance.query_data(**query_args) num_data_instances = cursor[0]['count'] # make first submission self._make_submission(xml_submission_file_path) self.assertEqual(self.response.status_code, 201) self.assertEqual(Instance.objects.count(), num_instances + 1) # no new record in instances history self.assertEqual(InstanceHistory.objects.count(), num_instances_history) # check count of mongo instances after first submission cursor = ParsedInstance.query_data(**query_args) self.assertEqual(cursor[0]['count'], num_data_instances + 1) # create a new user alice = self._create_user('alice', 'alice') UserProfile.objects.create(user=alice) auth = DigestAuth('alice', 'alice') # edited submission xml_submission_file_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "..", "fixtures", "tutorial", "instances", "tutorial_2012-06-27_11-27-53_w_uuid_edited.xml") self._make_submission(xml_submission_file_path, auth=auth) self.assertEqual(self.response.status_code, 403) # assign report perms to user assign_perm('report_xform', alice, self.xform) assign_perm('logger.change_xform', alice, self.xform) self._make_submission(xml_submission_file_path, auth=auth) self.assertEqual(self.response.status_code, 201) # we must have the same number of instances self.assertEqual(Instance.objects.count(), num_instances + 1) # should be a new record in instances history self.assertEqual(InstanceHistory.objects.count(), num_instances_history + 1) cursor = ParsedInstance.query_data(**query_args) self.assertEqual(cursor[0]['count'], num_data_instances + 1) # make sure we edited the mongo db record and NOT added a new row query_args['count'] = False cursor = ParsedInstance.query_data(**query_args) record = cursor[0] with open(xml_submission_file_path, "r") as f: xml_str = f.read() xml_str = clean_and_parse_xml(xml_str).toxml() edited_name = re.match(ur"^.+?<name>(.+?)</name>", xml_str).groups()[0] self.assertEqual(record['name'], edited_name)
def test_edited_submission(self): """ Test submissions that have been edited """ # Delete all previous instance history objects InstanceHistory.objects.all().delete() xml_submission_file_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "..", "fixtures", "tutorial", "instances", "tutorial_2012-06-27_11-27-53_w_uuid.xml") num_instances_history = InstanceHistory.objects.count() num_instances = Instance.objects.count() query_args = { 'xform': self.xform, 'query': '{}', 'fields': '[]', 'count': True } cursor = [r for r in query_data(**query_args)] num_data_instances = cursor[0]['count'] # make first submission self._make_submission(xml_submission_file_path) self.assertEqual(self.response.status_code, 201) self.assertEqual(Instance.objects.count(), num_instances + 1) # Take initial instance from DB initial_instance = self.xform.instances.first() # check that '_last_edited' key is not in the json self.assertIsNone(initial_instance.json.get(LAST_EDITED)) # no new record in instances history self.assertEqual(InstanceHistory.objects.count(), num_instances_history) # check count of mongo instances after first submission cursor = query_data(**query_args) self.assertEqual(cursor[0]['count'], num_data_instances + 1) # edited submission xml_edit_submission_file_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "..", "fixtures", "tutorial", "instances", "tutorial_2012-06-27_11-27-53_w_uuid_edited.xml") client = DigestClient() client.set_authorization('bob', 'bob', 'Digest') with catch_signal(process_submission) as handler: self._make_submission(xml_edit_submission_file_path, client=client) self.assertEqual(self.response.status_code, 201) # we must have the same number of instances self.assertEqual(Instance.objects.count(), num_instances + 1) # should be a new record in instances history self.assertEqual(InstanceHistory.objects.count(), num_instances_history + 1) instance_history_1 = InstanceHistory.objects.first() edited_instance = self.xform.instances.first() self.assertDictEqual(initial_instance.get_dict(), instance_history_1.get_dict()) handler.assert_called_once_with(instance=edited_instance, sender=Instance, signal=ANY) self.assertNotEqual(edited_instance.uuid, instance_history_1.uuid) # check that instance history's submission_date is equal to instance's # date_created - last_edited by default is null for an instance self.assertEquals(edited_instance.date_created, instance_history_1.submission_date) # check that '_last_edited' key is not in the json self.assertIn(LAST_EDITED, edited_instance.json) cursor = query_data(**query_args) self.assertEqual(cursor[0]['count'], num_data_instances + 1) # make sure we edited the mongo db record and NOT added a new row query_args['count'] = False cursor = query_data(**query_args) record = cursor[0] with open(xml_edit_submission_file_path, "r") as f: xml_str = f.read() xml_str = clean_and_parse_xml(xml_str).toxml() edited_name = re.match(ur"^.+?<name>(.+?)</name>", xml_str).groups()[0] self.assertEqual(record['name'], edited_name) instance_before_second_edit = edited_instance xml_edit_submission_file_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "..", "fixtures", "tutorial", "instances", "tutorial_2012-06-27_11-27-53_w_uuid_edited_again.xml") self._make_submission(xml_edit_submission_file_path) cursor = query_data(**query_args) record = cursor[0] edited_instance = self.xform.instances.first() instance_history_2 = InstanceHistory.objects.last() self.assertEquals(instance_before_second_edit.last_edited, instance_history_2.submission_date) # check that '_last_edited' key is not in the json self.assertIn(LAST_EDITED, edited_instance.json) self.assertEqual(record['name'], 'Tom and Jerry') self.assertEqual(InstanceHistory.objects.count(), num_instances_history + 2) # submitting original submission is treated as a duplicate # does not add a new record # does not change data self._make_submission(xml_submission_file_path) self.assertEqual(self.response.status_code, 202) self.assertEqual(Instance.objects.count(), num_instances + 1) self.assertEqual(InstanceHistory.objects.count(), num_instances_history + 2)
def get_id_string_from_xml_str(xml_str): xml_obj = clean_and_parse_xml(xml_str) root_node = xml_obj.documentElement return root_node.getAttribute(u"id")
def _set_uuid_in_xml(self, file_name=None): """ Add bind to automatically set UUID node in XML. """ if not file_name: file_name = self.file_name() file_name, file_ext = os.path.splitext(file_name) doc = clean_and_parse_xml(self.xml) model_nodes = doc.getElementsByTagName("model") if len(model_nodes) != 1: raise Exception(u"xml contains multiple model nodes") model_node = model_nodes[0] instance_nodes = [node for node in model_node.childNodes if node.nodeType == Node.ELEMENT_NODE and node.tagName.lower() == "instance" and not node.hasAttribute("id")] if len(instance_nodes) != 1: raise Exception(u"Multiple instance nodes without the id " u"attribute, can't tell which is the main one") instance_node = instance_nodes[0] # get the first child whose id attribute matches our id_string survey_nodes = [node for node in instance_node.childNodes if node.nodeType == Node.ELEMENT_NODE and (node.tagName == file_name or node.attributes.get('id'))] if len(survey_nodes) != 1: raise Exception( u"Multiple survey nodes with the id '%s'" % self.id_string) survey_node = survey_nodes[0] formhub_nodes = [n for n in survey_node.childNodes if n.nodeType == Node.ELEMENT_NODE and n.tagName == "formhub"] if len(formhub_nodes) > 1: raise Exception( u"Multiple formhub nodes within main instance node") elif len(formhub_nodes) == 1: formhub_node = formhub_nodes[0] else: formhub_node = survey_node.insertBefore( doc.createElement("formhub"), survey_node.firstChild) uuid_nodes = [node for node in formhub_node.childNodes if node.nodeType == Node.ELEMENT_NODE and node.tagName == "uuid"] if len(uuid_nodes) == 0: formhub_node.appendChild(doc.createElement("uuid")) if len(formhub_nodes) == 0: # append the calculate bind node calculate_node = doc.createElement("bind") calculate_node.setAttribute( "nodeset", "/%s/formhub/uuid" % file_name) calculate_node.setAttribute("type", "string") calculate_node.setAttribute("calculate", "'%s'" % self.uuid) model_node.appendChild(calculate_node) self.xml = doc.toprettyxml(indent=" ", encoding='utf-8') # hack # http://ronrothman.com/public/leftbraned/xml-dom-minidom-toprettyxml-\ # and-silly-whitespace/ text_re = re.compile('>\n\s+([^<>\s].*?)\n\s+</', re.DOTALL) output_re = re.compile('\n.*(<output.*>)\n( )*') prettyXml = text_re.sub('>\g<1></', self.xml) inlineOutput = output_re.sub('\g<1>', prettyXml) inlineOutput = re.compile('<label>\s*\n*\s*\n*\s*</label>').sub( '<label></label>', inlineOutput) self.xml = inlineOutput
def test_edited_submission_require_auth(self): """ Test submissions that have been edited """ xml_submission_file_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "..", "fixtures", "tutorial", "instances", "tutorial_2012-06-27_11-27-53_w_uuid.xml" ) # require authentication self.user.profile.require_auth = True self.user.profile.save() num_instances_history = InstanceHistory.objects.count() num_instances = Instance.objects.count() query_args = { 'xform': self.xform, 'query': '{}', 'fields': '[]', 'count': True } cursor = ParsedInstance.query_data(**query_args) num_data_instances = cursor[0]['count'] # make first submission self._make_submission(xml_submission_file_path) self.assertEqual(self.response.status_code, 201) self.assertEqual(Instance.objects.count(), num_instances + 1) # no new record in instances history self.assertEqual( InstanceHistory.objects.count(), num_instances_history) # check count of mongo instances after first submission cursor = ParsedInstance.query_data(**query_args) self.assertEqual(cursor[0]['count'], num_data_instances + 1) # create a new user alice = self._create_user('alice', 'alice') UserProfile.objects.create(user=alice) auth = DigestAuth('alice', 'alice') # edited submission xml_submission_file_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "..", "fixtures", "tutorial", "instances", "tutorial_2012-06-27_11-27-53_w_uuid_edited.xml" ) self._make_submission(xml_submission_file_path, auth=auth) self.assertEqual(self.response.status_code, 403) # assign report perms to user assign_perm('report_xform', alice, self.xform) assign_perm('logger.change_xform', alice, self.xform) self._make_submission(xml_submission_file_path, auth=auth) self.assertEqual(self.response.status_code, 201) # we must have the same number of instances self.assertEqual(Instance.objects.count(), num_instances + 1) # should be a new record in instances history self.assertEqual( InstanceHistory.objects.count(), num_instances_history + 1) cursor = ParsedInstance.query_data(**query_args) self.assertEqual(cursor[0]['count'], num_data_instances + 1) # make sure we edited the mongo db record and NOT added a new row query_args['count'] = False cursor = ParsedInstance.query_data(**query_args) record = cursor[0] with open(xml_submission_file_path, "r") as f: xml_str = f.read() xml_str = clean_and_parse_xml(xml_str).toxml() edited_name = re.match(ur"^.+?<name>(.+?)</name>", xml_str).groups()[0] self.assertEqual(record['name'], edited_name)
def test_edited_submission(self): """ Test submissions that have been edited """ # Delete all previous instance history objects InstanceHistory.objects.all().delete() xml_submission_file_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "..", "fixtures", "tutorial", "instances", "tutorial_2012-06-27_11-27-53_w_uuid.xml" ) num_instances_history = InstanceHistory.objects.count() num_instances = Instance.objects.count() query_args = { 'xform': self.xform, 'query': '{}', 'fields': '[]', 'count': True } cursor = [r for r in query_data(**query_args)] num_data_instances = cursor[0]['count'] # make first submission self._make_submission(xml_submission_file_path) self.assertEqual(self.response.status_code, 201) self.assertEqual(Instance.objects.count(), num_instances + 1) # Take initial instance from DB initial_instance = self.xform.instances.first() # check that '_last_edited' key is not in the json self.assertIsNone(initial_instance.json.get(LAST_EDITED)) # no new record in instances history self.assertEqual( InstanceHistory.objects.count(), num_instances_history) # check count of mongo instances after first submission cursor = query_data(**query_args) self.assertEqual(cursor[0]['count'], num_data_instances + 1) # edited submission xml_edit_submission_file_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "..", "fixtures", "tutorial", "instances", "tutorial_2012-06-27_11-27-53_w_uuid_edited.xml" ) client = DigestClient() client.set_authorization('bob', 'bob', 'Digest') with catch_signal(process_submission) as handler: self._make_submission(xml_edit_submission_file_path, client=client) self.assertEqual(self.response.status_code, 201) # we must have the same number of instances self.assertEqual(Instance.objects.count(), num_instances + 1) # should be a new record in instances history self.assertEqual( InstanceHistory.objects.count(), num_instances_history + 1) instance_history_1 = InstanceHistory.objects.first() edited_instance = self.xform.instances.first() self.assertDictEqual(initial_instance.get_dict(), instance_history_1.get_dict()) handler.assert_called_once_with(instance=edited_instance, sender=Instance, signal=ANY) self.assertNotEqual(edited_instance.uuid, instance_history_1.uuid) # check that instance history's submission_date is equal to instance's # date_created - last_edited by default is null for an instance self.assertEquals(edited_instance.date_created, instance_history_1.submission_date) # check that '_last_edited' key is not in the json self.assertIn(LAST_EDITED, edited_instance.json) cursor = query_data(**query_args) self.assertEqual(cursor[0]['count'], num_data_instances + 1) # make sure we edited the mongo db record and NOT added a new row query_args['count'] = False cursor = query_data(**query_args) record = cursor[0] with open(xml_edit_submission_file_path, "r") as f: xml_str = f.read() xml_str = clean_and_parse_xml(xml_str).toxml() edited_name = re.match(r"^.+?<name>(.+?)</name>", xml_str).groups()[0] self.assertEqual(record['name'], edited_name) instance_before_second_edit = edited_instance xml_edit_submission_file_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "..", "fixtures", "tutorial", "instances", "tutorial_2012-06-27_11-27-53_w_uuid_edited_again.xml" ) self._make_submission(xml_edit_submission_file_path) cursor = query_data(**query_args) record = cursor[0] edited_instance = self.xform.instances.first() instance_history_2 = InstanceHistory.objects.last() self.assertEquals(instance_before_second_edit.last_edited, instance_history_2.submission_date) # check that '_last_edited' key is not in the json self.assertIn(LAST_EDITED, edited_instance.json) self.assertEqual(record['name'], 'Tom and Jerry') self.assertEqual( InstanceHistory.objects.count(), num_instances_history + 2) # submitting original submission is treated as a duplicate # does not add a new record # does not change data self._make_submission(xml_submission_file_path) self.assertEqual(self.response.status_code, 202) self.assertEqual(Instance.objects.count(), num_instances + 1) self.assertEqual( InstanceHistory.objects.count(), num_instances_history + 2)
def _set_uuid_in_xml(self, file_name=None): """ Add bind to automatically set UUID node in XML. """ if not file_name: file_name = self.file_name() file_name, file_ext = os.path.splitext(file_name) doc = clean_and_parse_xml(self.xml) model_nodes = doc.getElementsByTagName("model") if len(model_nodes) != 1: raise Exception(u"xml contains multiple model nodes") model_node = model_nodes[0] instance_nodes = [ node for node in model_node.childNodes if node.nodeType == Node.ELEMENT_NODE and node.tagName.lower() == "instance" and not node.hasAttribute("id") ] if len(instance_nodes) != 1: raise Exception(u"Multiple instance nodes without the id " u"attribute, can't tell which is the main one") instance_node = instance_nodes[0] # get the first child whose id attribute matches our id_string survey_nodes = [ node for node in instance_node.childNodes if node.nodeType == Node.ELEMENT_NODE and (node.tagName == file_name or node.attributes.get('id')) ] if len(survey_nodes) != 1: raise Exception( u"Multiple survey nodes with the id '%s'" % self.id_string) survey_node = survey_nodes[0] formhub_nodes = [ n for n in survey_node.childNodes if n.nodeType == Node.ELEMENT_NODE and n.tagName == "formhub" ] if len(formhub_nodes) > 1: raise Exception( u"Multiple formhub nodes within main instance node") elif len(formhub_nodes) == 1: formhub_node = formhub_nodes[0] else: formhub_node = survey_node.insertBefore( doc.createElement("formhub"), survey_node.firstChild) uuid_nodes = [ node for node in formhub_node.childNodes if node.nodeType == Node.ELEMENT_NODE and node.tagName == "uuid" ] if len(uuid_nodes) == 0: formhub_node.appendChild(doc.createElement("uuid")) if len(formhub_nodes) == 0: # append the calculate bind node calculate_node = doc.createElement("bind") calculate_node.setAttribute( "nodeset", "/%s/formhub/uuid" % survey_node.tagName) calculate_node.setAttribute("type", "string") calculate_node.setAttribute("calculate", "'%s'" % self.uuid) model_node.appendChild(calculate_node) self.xml = doc.toprettyxml(indent=" ", encoding='utf-8') # hack # http://ronrothman.com/public/leftbraned/xml-dom-minidom-toprettyxml-\ # and-silly-whitespace/ text_re = re.compile('(>)\n\s*(\s[^<>\s].*?)\n\s*(\s</)', re.DOTALL) output_re = re.compile('\n.*(<output.*>)\n( )*') pretty_xml = text_re.sub(lambda m: ''.join(m.group(1, 2, 3)), self.xml.decode('utf-8')) inline_output = output_re.sub('\g<1>', pretty_xml) inline_output = re.compile('<label>\s*\n*\s*\n*\s*</label>').sub( '<label></label>', inline_output) self.xml = inline_output