def resp_body(self) -> str: """Check validation and organize validation error details. :returns: JSON formatted string that provides details of validation :raises: HTTPBadRequest if URLError was raised during validation """ try: self.schema.validate(self.xml_content) LOG.info("Submitted file is totally valid.") return json.dumps({"isValid": True}) except ParseError as error: reason = self._parse_error_reason(error) # Manually find instance element lines = StringIO(self.xml_content).readlines() line = lines[error.position[0] - 1] # line of instance instance = re.sub(r"^.*?<", "<", line) # strip whitespaces LOG.info("Submitted file does not not contain valid XML syntax.") return json.dumps({ "isValid": False, "detail": { "reason": reason, "instance": instance } }) except XMLSchemaValidationError as error: # Parse reason and instance from the validation error message reason = error.reason instance = ElementTree.tostring(error.elem, encoding="unicode") # Replace element address in reason with instance element if "<" and ">" in reason: instance_parent = "".join((instance.split(">")[0], ">")) reason = re.sub("<[^>]*>", instance_parent + " ", reason) LOG.info("Submitted file is not valid against schema.") return json.dumps({ "isValid": False, "detail": { "reason": reason, "instance": instance } }) except URLError as error: reason = f"Faulty file was provided. {error.reason}." LOG.error(reason) raise web.HTTPBadRequest(reason=reason)
def test_qname_decoding(self): schema = self.schema_class("""<?xml version="1.0" encoding="utf-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="root" type="rootType" /> <xs:complexType name="rootType"> <xs:simpleContent> <xs:extension base="xs:QName"> <xs:attribute name="name" type="xs:QName"/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:schema>""") xml_data = '<root xmlns:ns0="http://xmlschema.test/0">ns0:foo</root>' self.assertEqual(schema.decode(xml_data), 'ns0:foo') self.assertEqual(schema.decode('<root>foo</root>'), 'foo') with self.assertRaises(XMLSchemaValidationError) as ctx: schema.decode('<root>ns0:foo</root>') self.assertIn("failed validating 'ns0:foo'", str(ctx.exception)) self.assertIn("Reason: unmapped prefix 'ns0' on QName", str(ctx.exception)) self.assertIn("Path: /root", str(ctx.exception)) xml_data = '<root name="ns0:bar" xmlns:ns0="http://xmlschema.test/0">ns0:foo</root>' self.assertEqual(schema.decode(xml_data), { '@name': 'ns0:bar', '$': 'ns0:foo' }) # Check reverse encoding obj = schema.decode(xml_data, converter=JsonMLConverter) root = schema.encode(obj, converter=JsonMLConverter) self.assertEqual(ElementTree.tostring(root), b'<root name="ns0:bar">ns0:foo</root>\n') with self.assertRaises(XMLSchemaValidationError) as ctx: schema.decode('<root name="ns0:bar">foo</root>') self.assertIn("failed validating 'ns0:bar'", str(ctx.exception)) self.assertIn("Reason: unmapped prefix 'ns0' on QName", str(ctx.exception)) self.assertIn("Path: /root", str(ctx.exception))