def test_dot_shortcut_token(self): parser = XPath2Parser(default_namespace="http://xpath.test/ns") context = XMLSchemaContext(self.schema1) elem_a = self.schema1.elements['a'] elem_b3 = self.schema1.elements['b3'] token = parser.parse('.') self.assertIsNone(token.xsd_types) result = token.evaluate(context) self.assertListEqual(result, [self.schema1]) self.assertEqual(token.xsd_types, {"{http://xpath.test/ns}a": elem_a.type, "{http://xpath.test/ns}b3": elem_b3.type}) context = XMLSchemaContext(self.schema1, item=self.schema1) token = parser.parse('.') self.assertIsNone(token.xsd_types) result = token.evaluate(context) self.assertListEqual(result, [self.schema1]) self.assertEqual(token.xsd_types, {"{http://xpath.test/ns}a": elem_a.type, "{http://xpath.test/ns}b3": elem_b3.type}) context = XMLSchemaContext(self.schema1, item=self.schema2) token = parser.parse('.') self.assertIsNone(token.xsd_types) result = token.evaluate(context) self.assertListEqual(result, [self.schema2]) self.assertIsNone(token.xsd_types)
def check_xsd_file(self): if expected_errors > 0: xs = schema_class(xsd_file, validation='lax', locations=locations, defuse=defuse, loglevel=loglevel) else: xs = schema_class(xsd_file, locations=locations, defuse=defuse, loglevel=loglevel) self.errors.extend(xs.maps.all_errors) if inspect: components_ids = set( [id(c) for c in xs.maps.iter_components()]) components_ids.update( id(c) for c in xs.meta_schema.iter_components()) missing = [ c for c in SchemaObserver.components if id(c) not in components_ids ] if missing: raise ValueError("schema missing %d components: %r" % (len(missing), missing)) # Pickling test (only for Python 3, skip inspected schema classes test) if not inspect: try: obj = pickle.dumps(xs) deserialized_schema = pickle.loads(obj) except pickle.PicklingError: # Don't raise if some schema parts (eg. a schema loaded from remote) # are built with the SafeXMLParser that uses pure Python elements. for e in xs.maps.iter_components(): elem = getattr(e, 'elem', getattr(e, 'root', None)) if isinstance(elem, py_etree_element): break else: raise else: self.assertTrue( isinstance(deserialized_schema, XMLSchemaBase)) self.assertEqual(xs.built, deserialized_schema.built) # XPath API tests if not inspect and not self.errors: context = XMLSchemaContext(xs) elements = [x for x in xs.iter()] context_elements = [ x for x in context.iter() if isinstance(x, XsdValidator) ] self.assertEqual(context_elements, [x for x in context.iter_descendants()]) self.assertEqual(context_elements, elements)
def test_wildcard_token(self): parser = XPath2Parser(default_namespace="http://xpath.test/ns") context = XMLSchemaContext(self.schema1) elem_a = self.schema1.elements['a'] elem_b3 = self.schema1.elements['b3'] token = parser.parse('*') self.assertEqual(token.symbol, '*') self.assertIsNone(token.xsd_types) result = token.evaluate(context) self.assertListEqual(result, [elem_a, elem_b3]) self.assertEqual(token.xsd_types, {"{http://xpath.test/ns}a": elem_a.type, "{http://xpath.test/ns}b3": elem_b3.type}) token = parser.parse('a/*') self.assertEqual(token.symbol, '/') self.assertEqual(token[0].symbol, '(name)') self.assertEqual(token[1].symbol, '*') result = token.evaluate(context) self.assertListEqual(result, elem_a.type.content[:]) self.assertIsNone(token.xsd_types) self.assertEqual(token[0].xsd_types, {"{http://xpath.test/ns}a": elem_a.type}) self.assertEqual(token[1].xsd_types, {'b1': elem_a.type.content[0].type, 'b2': elem_a.type.content[1].type, '{http://xpath.test/ns}b3': elem_b3.type})
def test_name_token(self): parser = XPath2Parser(default_namespace="http://xpath.test/ns") context = XMLSchemaContext(self.schema1) elem_a = self.schema1.elements['a'] token = parser.parse('a') self.assertIsNone(token.xsd_types) result = token.evaluate(context.copy()) self.assertEqual(token.xsd_types, {"{http://xpath.test/ns}a": elem_a.type}) self.assertListEqual(result, [TypedElement(elem_a, elem_a.type, UntypedAtomic('1'))]) elem_b1 = elem_a.type.content[0] token = parser.parse('a/b1') self.assertIsNone(token[0].xsd_types) self.assertIsNone(token[1].xsd_types) result = token.evaluate(context.copy()) self.assertEqual(token[0].xsd_types, {"{http://xpath.test/ns}a": elem_a.type}) self.assertEqual(token[1].xsd_types, {"b1": elem_b1.type}) self.assertListEqual(result, [TypedElement(elem_b1, elem_b1.type, ' alpha\t')])
def test_extended_name_token(self): parser = XPath2Parser(strict=False) context = XMLSchemaContext(self.schema1) elem_a = self.schema1.elements['a'] token = parser.parse('{http://xpath.test/ns}a') self.assertEqual(token.symbol, '{') self.assertIsNone(token.xsd_types) self.assertEqual(token[0].symbol, '(string)') self.assertEqual(token[1].symbol, '(name)') self.assertEqual(token[1].value, 'a') result = token.evaluate(context) self.assertListEqual(result, [TypedElement(elem_a, elem_a.type, UntypedAtomic('1'))]) self.assertEqual(token.xsd_types, {"{http://xpath.test/ns}a": elem_a.type}) self.assertIsNone(token[0].xsd_types) self.assertIsNone(token[1].xsd_types)
def test_not_applicable_functions(self): parser = XPath2Parser(default_namespace="http://xpath.test/ns") context = XMLSchemaContext(self.schema1) token = parser.parse("fn:collection('filepath')") self.assertIsNone(token.evaluate(context)) token = parser.parse("fn:doc-available('tns1')") self.assertIsNone(token.evaluate(context)) token = parser.parse("fn:root(.)") self.assertIsNone(token.evaluate(context)) token = parser.parse("fn:id('ID21256')") self.assertListEqual(token.evaluate(context), []) token = parser.parse("fn:idref('ID21256')") self.assertListEqual(token.evaluate(context), [])
def test_schema_variables(self): variable_types = {'a': 'item()', 'b': 'xs:integer?', 'c': 'xs:string'} parser = XPath2Parser(default_namespace="http://xpath.test/ns", variable_types=variable_types) context = XMLSchemaContext(self.schema1) token = parser.parse('$a') result = token.evaluate(context) self.assertIsInstance(result, UntypedAtomic) self.assertEqual(result.value, '') token = parser.parse('$b') result = token.evaluate(context) self.assertIsInstance(result, int) self.assertEqual(result, 1) token = parser.parse('$c') result = token.evaluate(context) self.assertIsInstance(result, str) self.assertEqual(result, ' alpha\t') token = parser.parse('$z') with self.assertRaises(NameError): token.evaluate(context)
def test_colon_token(self): parser = XPath2Parser(namespaces={'tst': "http://xpath.test/ns"}) context = XMLSchemaContext(self.schema1) elem_a = self.schema1.elements['a'] token = parser.parse('tst:a') self.assertEqual(token.symbol, ':') self.assertIsNone(token.xsd_types) result = token.evaluate(context.copy()) self.assertEqual(token.xsd_types, {"{http://xpath.test/ns}a": elem_a.type}) self.assertListEqual(result, [TypedElement(elem_a, elem_a.type, UntypedAtomic('1'))]) elem_b1 = elem_a.type.content[0] token = parser.parse('tst:a/b1') self.assertEqual(token.symbol, '/') self.assertEqual(token[0].symbol, ':') self.assertIsNone(token[0].xsd_types) self.assertIsNone(token[1].xsd_types) result = token.evaluate(context.copy()) self.assertListEqual(result, [TypedElement(elem_b1, elem_b1.type, ' alpha\t')]) self.assertEqual(token[0].xsd_types, {"{http://xpath.test/ns}a": elem_a.type}) self.assertEqual(token[1].xsd_types, {"b1": elem_b1.type}) token = parser.parse('tst:a/tst:b1') result = token.evaluate(context.copy()) self.assertListEqual(result, []) self.assertEqual(token[0].xsd_types, {"{http://xpath.test/ns}a": elem_a.type}) self.assertIsNone(token[1].xsd_types) elem_b3 = elem_a.type.content[2] token = parser.parse('tst:a/tst:b3') self.assertEqual(token.symbol, '/') self.assertEqual(token[0].symbol, ':') self.assertIsNone(token[0].xsd_types) self.assertIsNone(token[1].xsd_types) result = token.evaluate(context.copy()) self.assertListEqual(result, [TypedElement(elem_b3, elem_b3.type, 1.0)]) self.assertEqual(token[0].xsd_types, {"{http://xpath.test/ns}a": elem_a.type}) self.assertEqual(token[1].xsd_types, {"{http://xpath.test/ns}b3": elem_b3.type})
def check_xsd_file(self): if expected_errors > 0: xs = schema_class(xsd_file, validation='lax', locations=locations, defuse=defuse, loglevel=loglevel) else: xs = schema_class(xsd_file, locations=locations, defuse=defuse, loglevel=loglevel) self.errors.extend(xs.maps.all_errors) if inspect: components_ids = set( [id(c) for c in xs.maps.iter_components()]) components_ids.update( id(c) for c in xs.meta_schema.iter_components()) missing = [ c for c in SchemaObserver.components if id(c) not in components_ids ] if missing: raise ValueError("schema missing %d components: %r" % (len(missing), missing)) # Pickling test (only for Python 3, skip inspected schema classes test) if not inspect: try: obj = pickle.dumps(xs) deserialized_schema = pickle.loads(obj) except pickle.PicklingError: # Don't raise if some schema parts (eg. a schema loaded from remote) # are built with the SafeXMLParser that uses pure Python elements. for e in xs.maps.iter_components(): elem = getattr(e, 'elem', getattr(e, 'root', None)) if isinstance(elem, py_etree_element): break else: raise else: self.assertTrue( isinstance(deserialized_schema, XMLSchemaBase)) self.assertEqual(xs.built, deserialized_schema.built) # XPath API tests if not inspect and not self.errors: context = XMLSchemaContext(xs) elements = [x for x in xs.iter()] context_elements = [ x for x in context.iter() if isinstance(x, XsdValidator) ] self.assertEqual(context_elements, [x for x in context.iter_descendants()]) self.assertEqual(context_elements, elements) # Checks on XSD types for xsd_type in xs.maps.iter_components(xsd_classes=XsdType): self.assertNotEqual(xsd_type.content_type_label, 'unknown') # Check that the schema is valid also with XSD 1.1 validator if not expected_errors and schema_class.XSD_VERSION == '1.0': try: XMLSchema11(xsd_file, locations=locations, defuse=defuse, loglevel=loglevel) except XMLSchemaParseError as err: if not isinstance(err.validator, Xsd11ComplexType) or \ "is simple or has a simple content" not in str(err): raise # Not a case of forbidden complex content extension xs = schema_class(xsd_file, validation='lax', locations=locations, defuse=defuse, loglevel=loglevel) for error in xs.all_errors: if not isinstance(err.validator, Xsd11ComplexType) or \ "is simple or has a simple content" not in str(err): raise error