def is_schema_valid(object_type, content, name=None): # is the name unique? if name is not None: if object_type.lower() == 'template': names = Template.objects.all().values_list('title') elif object_type.lower() == 'type': names = Type.objects.all().values_list('title') if name in names: raise MDCSError( 'A {} with the same name already exists'.format(object_type)) # is it a valid XML document? try: try: xsd_tree = etree.parse(BytesIO(content.encode('utf-8'))) except Exception: xsd_tree = etree.parse(BytesIO(content)) except Exception: raise XMLError('Uploaded file is not well formatted XML.') # is it supported by the MDCS? errors = common.getValidityErrorsForMDCS(xsd_tree, object_type) if len(errors) > 0: errors_str = ", ".join(errors) raise MDCSError(errors_str) # is it a valid XML schema? error = validate_xml_schema(xsd_tree) if error is not None: raise XSDError(error)
def check_result(self, expected_code=200): """ Check that the result template is valid :return: """ self.assertEqual(self.response.status_code, expected_code) composed_template = self.request.session['newXmlTemplateCompose'] self.assertEquals(validate_xml_schema(etree.fromstring(composed_template)), None)
def resolve_dependencies(request): print 'BEGIN def resolveDependencies(request)' schema_locations = request.POST.getlist('schemaLocations[]') dependencies = request.POST.getlist('dependencies[]') if ('uploadObjectName' in request.session and request.session['uploadObjectName'] is not None and 'uploadObjectFilename' in request.session and request.session['uploadObjectFilename'] is not None and 'uploadObjectContent' in request.session and request.session['uploadObjectContent'] is not None and 'uploadObjectType' in request.session and request.session['uploadObjectType'] is not None): object_content = request.session['uploadObjectContent'] name = request.session['uploadObjectName'] filename = request.session['uploadObjectFilename'] object_type = request.session['uploadObjectType'] # Load a parser able to clean the XML from blanks, comments and processing instructions clean_parser = etree.XMLParser(remove_blank_text=True, remove_comments=True, remove_pis=True) # set the parser etree.set_default_parser(parser=clean_parser) xsd_tree = etree.XML(str(object_content.encode('utf-8'))) # replace includes/imports by API calls (get dependencies starting by the imports) update_dependencies(xsd_tree, dict(zip(schema_locations, dependencies))) # validate the schema error = validate_xml_schema(xsd_tree) if error is None: object_content = etree.tostring(xsd_tree) # create a new version if 'uploadVersion' in request.session and request.session['uploadVersion'] is not None: object_versions_id = request.session['uploadVersion'] if object_type == 'Template': new_template = create_template_version(object_content, filename, object_versions_id) redirect = '/admin/manage_versions?type={0}&id={1}'.format(object_type, str(new_template.id)) elif object_type == 'Type': new_type = create_type_version(object_content, filename, object_versions_id) redirect = '/admin/manage_versions?type={0}&id={1}'.format(object_type, str(new_type.id)) # create new object else: # save the object if object_type == "Template": create_template(object_content, name, filename, dependencies) redirect = '/admin/xml-schemas/manage-schemas' elif object_type == "Type": if 'uploadBuckets' in request.session and request.session['uploadBuckets'] is not None: buckets = request.session['uploadBuckets'] create_type(object_content, name, filename, buckets, dependencies) redirect = '/admin/xml-schemas/manage-types' response_dict = {'redirect': redirect} messages.add_message(request, messages.INFO, '{} uploaded with success.'.format(object_type)) return HttpResponse(json.dumps(response_dict), content_type='application/javascript') else: response_dict = {'errorDependencies': error.replace("'", "")} return HttpResponse(json.dumps(response_dict), content_type='application/javascript')
def test_basic(self): # load template template_path = join(RESOURCES_PATH, 'basic.xsd') self.load_template(template_path) # test LXML if TEST_LXML: self.assertEquals(_lxml_validate_xsd(self.xsd_tree), None) # test global method self.assertEquals(validate_xml_schema(self.xsd_tree), None)
def test_include_filesystem(self): # load template template_path = join(RESOURCES_PATH, 'include.xsd') self.load_template(template_path) # test LXML if TEST_LXML: self.assertNotEquals(_lxml_validate_xsd(self.xsd_tree), None) # test global method self.assertNotEquals(validate_xml_schema(self.xsd_tree), None)
def test_basic(self): # load template template_path = join(RESOURCES_PATH, 'basic.xsd') self.load_template(template_path) # test LXML if TEST_LXML: self.assertEquals(_lxml_validate_xsd(self.xsd_tree), None) # test global method self.assertEquals(validate_xml_schema(self.xsd_tree), None)
def test_include_filesystem(self): # load template template_path = join(RESOURCES_PATH, 'include.xsd') self.load_template(template_path) # test LXML if TEST_LXML: self.assertNotEquals(_lxml_validate_xsd(self.xsd_tree), None) # test global method self.assertNotEquals(validate_xml_schema(self.xsd_tree), None)
def test_1_1(self): # load template template_path = join(RESOURCES_PATH, '1.1.xsd') self.load_template(template_path) # test LXML # TODO: LXML fails to validate if TEST_LXML: self.assertEquals(_lxml_validate_xsd(self.xsd_tree), None) # test global method self.assertEquals(validate_xml_schema(self.xsd_tree), None)
def test_1_1(self): # load template template_path = join(RESOURCES_PATH, '1.1.xsd') self.load_template(template_path) # test LXML # TODO: LXML fails to validate if TEST_LXML: self.assertEquals(_lxml_validate_xsd(self.xsd_tree), None) # test global method self.assertEquals(validate_xml_schema(self.xsd_tree), None)
def test_import_django(self): # load type type_path = join(RESOURCES_PATH, 'to-import.xsd') type_object = self.load_type(type_path) # load template template_path = join(RESOURCES_PATH, 'import.xsd') self.load_template(template_path) update_dependencies(self.xsd_tree, {'to-import.xsd': str(type_object.id)}) self.xsd_string = etree.tostring(self.xsd_tree) # test LXML if TEST_LXML: self.assertEquals(_lxml_validate_xsd(self.xsd_tree), None) # test global method self.assertEquals(validate_xml_schema(self.xsd_tree), None)
def test_import_django(self): # load type type_path = join(RESOURCES_PATH, 'to-import.xsd') type_object = self.load_type(type_path) # load template template_path = join(RESOURCES_PATH, 'import.xsd') self.load_template(template_path) update_dependencies(self.xsd_tree, {'to-import.xsd': str(type_object.id)}) self.xsd_string = etree.tostring(self.xsd_tree) # test LXML if TEST_LXML: self.assertEquals(_lxml_validate_xsd(self.xsd_tree), None) # test global method self.assertEquals(validate_xml_schema(self.xsd_tree), None)
################################################################################ def save_template(request): template_name = request.POST['templateName'] content = request.session['newXmlTemplateCompose'] response_dict = {} # Validate XML document try: xml_tree = etree.parse(BytesIO(content.encode('utf-8'))) except Exception, e: response_dict['errors'] = e.message.replace("'", "") return HttpResponse(json.dumps(response_dict), content_type='application/javascript') # validate the schema error = validate_xml_schema(xml_tree) if error is not None: response_dict['errors'] = 'This is not a valid XML schema.' + error.replace("'", "") return HttpResponse(json.dumps(response_dict), content_type='application/javascript') dependencies = [] for uri in request.session["includedTypesCompose"]: url = urlparse(uri) id = url.query.split("=")[1] dependencies.append(id) create_template(content, template_name, template_name, dependencies, user=str(request.user.id)) return HttpResponse(json.dumps(response_dict), content_type='application/javascript')
def insert_element_sequence(request): try: type_id = request.POST['typeID'] client_type_name = request.POST['typeName'] xpath = request.POST['xpath'] xml_tree_str = request.session['newXmlTemplateCompose'] # build the dom tree of the schema being built xsd_tree = etree.parse(BytesIO(xml_tree_str.encode('utf-8'))) # get namespaces information for the schema namespaces = get_namespaces(BytesIO(str(xml_tree_str))) default_prefix = get_default_prefix(namespaces) # get target namespace information target_namespace, target_namespace_prefix = get_target_namespace( namespaces, xsd_tree) # build xpath to element xpath = xpath.replace(default_prefix + ":", LXML_SCHEMA_NAMESPACE) if type_id == 'built_in_type': type_name = default_prefix + ':' + client_type_name xsd_tree.find(xpath).append( etree.Element("{}element".format(LXML_SCHEMA_NAMESPACE), attrib={ 'type': type_name, 'name': client_type_name })) # validate XML schema error = validate_xml_schema(xsd_tree) new_xsd_str = etree.tostring(xsd_tree) else: # get the type being included type_object = Type.objects().get(pk=type_id) type_xsd_tree = etree.parse( BytesIO(type_object.content.encode('utf-8'))) # get namespaces information for the type type_namespaces = get_namespaces(BytesIO(str(type_object.content))) type_target_namespace, type_target_namespace_prefix = get_target_namespace( type_namespaces, type_xsd_tree) # get the type from the included/imported file # If there is a complex type element_type = type_xsd_tree.find( "{}complexType".format(LXML_SCHEMA_NAMESPACE)) if element_type is None: # If there is a simple type element_type = type_xsd_tree.find( "{}simpleType".format(LXML_SCHEMA_NAMESPACE)) type_name = element_type.attrib["name"] if type_target_namespace is not None: ns_type_name = "{0}:{1}".format(type_target_namespace_prefix, type_name) else: if target_namespace is not None: ns_type_name = "{0}:{1}".format(target_namespace_prefix, type_name) else: ns_type_name = '{}'.format(type_name) nsmap = {type_target_namespace_prefix: type_target_namespace} update_nsmap = False # get link to the type to include include_url = getSchemaLocation(str(type_id)) # Schema without target namespace if target_namespace is None: # Type without target namespace if type_target_namespace is None: # add include xsd_tree.getroot().insert( 0, etree.Element( "{}include".format(LXML_SCHEMA_NAMESPACE), attrib={'schemaLocation': include_url})) # add element xsd_tree.find(xpath).append( etree.Element( "{}element".format(LXML_SCHEMA_NAMESPACE), attrib={ 'type': type_name, 'name': client_type_name })) # Type with target namespace else: # add import xsd_tree.getroot().insert( 0, etree.Element("{}import".format(LXML_SCHEMA_NAMESPACE), attrib={ 'schemaLocation': include_url, 'namespace': type_target_namespace })) # create the element to add element = etree.Element( "{}element".format(LXML_SCHEMA_NAMESPACE), attrib={ 'name': client_type_name, 'type': ns_type_name }, ) # add the element xsd_tree.find(xpath).append(element) update_nsmap = True # Schema with target namespace else: # Type without target namespace if type_target_namespace is None: # add include xsd_tree.getroot().insert( 0, etree.Element( "{}include".format(LXML_SCHEMA_NAMESPACE), attrib={'schemaLocation': include_url})) # add element xsd_tree.find(xpath).append( etree.Element( "{}element".format(LXML_SCHEMA_NAMESPACE), attrib={ 'name': client_type_name, 'type': ns_type_name })) # Type with target namespace else: # Same target namespace as base template if target_namespace == type_target_namespace: # add include xsd_tree.getroot().insert( 0, etree.Element( "{}include".format(LXML_SCHEMA_NAMESPACE), attrib={'schemaLocation': include_url})) # add element xsd_tree.find(xpath).append( etree.Element( "{}element".format(LXML_SCHEMA_NAMESPACE), attrib={ 'name': client_type_name, 'type': ns_type_name })) # Different target namespace as base template else: # add import xsd_tree.getroot().insert( 0, etree.Element( "{}import".format(LXML_SCHEMA_NAMESPACE), attrib={ 'schemaLocation': include_url, 'namespace': type_target_namespace })) # create the element to add element = etree.Element( "{}element".format(LXML_SCHEMA_NAMESPACE), attrib={ 'name': client_type_name, 'type': ns_type_name }, ) # add the element xsd_tree.find(xpath).append(element) update_nsmap = True # add the id of the type if not already present if include_url not in request.session['includedTypesCompose']: request.session['includedTypesCompose'].append(include_url) if update_nsmap: root = xsd_tree.getroot() root_nsmap = root.nsmap if type_target_namespace_prefix in root_nsmap.keys() and\ root_nsmap[type_target_namespace_prefix] != type_target_namespace: raise MDCSError( 'The namespace prefix is already declared for a different namespace.' ) else: root_nsmap[ type_target_namespace_prefix] = type_target_namespace new_root = etree.Element(root.tag, nsmap=root_nsmap) new_root[:] = root[:] # validate XML schema error = validate_xml_schema(new_root) new_xsd_str = etree.tostring(new_root) else: # validate XML schema error = validate_xml_schema(xsd_tree) new_xsd_str = etree.tostring(xsd_tree) if error is not None: raise MDCSError(error) # save the tree in the session request.session['newXmlTemplateCompose'] = new_xsd_str except Exception, e: return HttpResponseBadRequest(e.message, content_type='application/javascript')
def resolve_dependencies(request): print 'BEGIN def resolveDependencies(request)' schema_locations = request.POST.getlist('schemaLocations[]') dependencies = request.POST.getlist('dependencies[]') if ('uploadObjectName' in request.session and request.session['uploadObjectName'] is not None and 'uploadObjectFilename' in request.session and request.session['uploadObjectFilename'] is not None and 'uploadObjectContent' in request.session and request.session['uploadObjectContent'] is not None and 'uploadObjectType' in request.session and request.session['uploadObjectType'] is not None): object_content = request.session['uploadObjectContent'] name = request.session['uploadObjectName'] filename = request.session['uploadObjectFilename'] object_type = request.session['uploadObjectType'] # Load a parser able to clean the XML from blanks, comments and processing instructions clean_parser = etree.XMLParser(remove_blank_text=True, remove_comments=True, remove_pis=True) # set the parser etree.set_default_parser(parser=clean_parser) xsd_tree = etree.XML(str(object_content.encode('utf-8'))) # replace includes/imports by API calls (get dependencies starting by the imports) update_dependencies(xsd_tree, dict(zip(schema_locations, dependencies))) # validate the schema error = validate_xml_schema(xsd_tree) if error is None: object_content = etree.tostring(xsd_tree) # create a new version if 'uploadVersion' in request.session and request.session[ 'uploadVersion'] is not None: object_versions_id = request.session['uploadVersion'] if object_type == 'Template': new_template = create_template_version(object_content, filename, object_versions_id) redirect = '/admin/manage_versions?type={0}&id={1}'.format( object_type, str(new_template.id)) elif object_type == 'Type': new_type = create_type_version(object_content, filename, object_versions_id) redirect = '/admin/manage_versions?type={0}&id={1}'.format( object_type, str(new_type.id)) # create new object else: # save the object if object_type == "Template": create_template(object_content, name, filename, dependencies) redirect = '/admin/xml-schemas/manage-schemas' elif object_type == "Type": if 'uploadBuckets' in request.session and request.session[ 'uploadBuckets'] is not None: buckets = request.session['uploadBuckets'] create_type(object_content, name, filename, buckets, dependencies) redirect = '/admin/xml-schemas/manage-types' response_dict = {'redirect': redirect} messages.add_message(request, messages.INFO, '{} uploaded with success.'.format(object_type)) return HttpResponse(json.dumps(response_dict), content_type='application/javascript') else: response_dict = {'errorDependencies': error.replace("'", "")} return HttpResponse(json.dumps(response_dict), content_type='application/javascript')
def insert_element_sequence(request): try: type_id = request.POST['typeID'] client_type_name = request.POST['typeName'] xpath = request.POST['xpath'] xml_tree_str = request.session['newXmlTemplateCompose'] # build the dom tree of the schema being built xsd_tree = etree.parse(BytesIO(xml_tree_str.encode('utf-8'))) # get namespaces information for the schema namespaces = get_namespaces(BytesIO(str(xml_tree_str))) default_prefix = get_default_prefix(namespaces) target_namespace, target_namespace_prefix = get_target_namespace(namespaces, xsd_tree) # get the type being included type_object = Type.objects().get(pk=type_id) type_xsd_tree = etree.parse(BytesIO(type_object.content.encode('utf-8'))) # get namespaces information for the type type_namespaces = get_namespaces(BytesIO(str(type_object.content))) type_target_namespace, type_target_namespace_prefix = get_target_namespace(type_namespaces, type_xsd_tree) # get the type from the included/imported file # If there is a complex type element_type = type_xsd_tree.find("{}complexType".format(LXML_SCHEMA_NAMESPACE)) if element_type is None: # If there is a simple type element_type = type_xsd_tree.find("{}simpleType".format(LXML_SCHEMA_NAMESPACE)) type_name = element_type.attrib["name"] if type_target_namespace is not None: ns_type_name = "{0}:{1}".format(type_target_namespace_prefix, type_name) else: if target_namespace is not None: ns_type_name = "{0}:{1}".format(target_namespace_prefix, type_name) else: ns_type_name = '{}'.format(type_name) nsmap = {type_target_namespace_prefix: type_target_namespace} update_nsmap = False # build xpath to element xpath = xpath.replace(default_prefix + ":", LXML_SCHEMA_NAMESPACE) # get link to the type to include include_url = getSchemaLocation(str(type_id)) # Schema without target namespace if target_namespace is None: # Type without target namespace if type_target_namespace is None: # add include xsd_tree.getroot().insert(0, etree.Element("{}include".format(LXML_SCHEMA_NAMESPACE), attrib={'schemaLocation': include_url})) # add element xsd_tree.find(xpath).append(etree.Element("{}element".format(LXML_SCHEMA_NAMESPACE), attrib={'type': type_name, 'name': client_type_name})) # Type with target namespace else: # add import xsd_tree.getroot().insert(0, etree.Element("{}import".format(LXML_SCHEMA_NAMESPACE), attrib={'schemaLocation': include_url, 'namespace': type_target_namespace})) # create the element to add element = etree.Element("{}element".format(LXML_SCHEMA_NAMESPACE), attrib={'name': client_type_name, 'type': ns_type_name}, ) # add the element xsd_tree.find(xpath).append(element) update_nsmap = True # Schema with target namespace else: # Type without target namespace if type_target_namespace is None: # add include xsd_tree.getroot().insert(0, etree.Element("{}include".format(LXML_SCHEMA_NAMESPACE), attrib={'schemaLocation': include_url})) # add element xsd_tree.find(xpath).append(etree.Element("{}element".format(LXML_SCHEMA_NAMESPACE), attrib={'name': client_type_name, 'type': ns_type_name})) # Type with target namespace else: # Same target namespace as base template if target_namespace == type_target_namespace: # add include xsd_tree.getroot().insert(0, etree.Element("{}include".format(LXML_SCHEMA_NAMESPACE), attrib={'schemaLocation': include_url})) # add element xsd_tree.find(xpath).append(etree.Element("{}element".format(LXML_SCHEMA_NAMESPACE), attrib={'name': client_type_name, 'type': ns_type_name})) # Different target namespace as base template else: # add import xsd_tree.getroot().insert(0, etree.Element("{}import".format(LXML_SCHEMA_NAMESPACE), attrib={'schemaLocation': include_url, 'namespace': type_target_namespace})) # create the element to add element = etree.Element("{}element".format(LXML_SCHEMA_NAMESPACE), attrib={'name': client_type_name, 'type': ns_type_name}, ) # add the element xsd_tree.find(xpath).append(element) update_nsmap = True # add the id of the type if not already present if include_url not in request.session['includedTypesCompose']: request.session['includedTypesCompose'].append(include_url) if update_nsmap: root = xsd_tree.getroot() root_nsmap = root.nsmap if type_target_namespace_prefix in root_nsmap.keys() and\ root_nsmap[type_target_namespace_prefix] != type_target_namespace: raise MDCSError('The namespace prefix is already declared for a different namespace.') else: root_nsmap[type_target_namespace_prefix] = type_target_namespace new_root = etree.Element(root.tag, nsmap=root_nsmap) new_root[:] = root[:] # validate XML schema error = validate_xml_schema(new_root) new_xsd_str = etree.tostring(new_root) else: # validate XML schema error = validate_xml_schema(xsd_tree) new_xsd_str = etree.tostring(xsd_tree) if error is not None: raise MDCSError(error) # save the tree in the session request.session['newXmlTemplateCompose'] = new_xsd_str except Exception, e: return HttpResponseBadRequest(e.message, content_type='application/javascript')
################################################################################ def save_template(request): template_name = request.POST['templateName'] content = request.session['newXmlTemplateCompose'] response_dict = {} # Validate XML document try: xml_tree = etree.parse(BytesIO(content.encode('utf-8'))) except Exception, e: response_dict['errors'] = e.message.replace("'", "") return HttpResponse(json.dumps(response_dict), content_type='application/javascript') # validate the schema error = validate_xml_schema(xml_tree) if error is not None: response_dict['errors'] = 'This is not a valid XML schema.' + error.replace("'","") return HttpResponse(json.dumps(response_dict), content_type='application/javascript') dependencies = [] for uri in request.session["includedTypesCompose"]: try: url = urlparse(uri) id = url.query.split("=")[1] # add dependency if it matches a type id Type.objects().get(pk=id) dependencies.append(id) except: