def test_xmlschema_error_log_path(self): """We don't have a guarantee that there will always be a path for a _LogEntry object (or even a node for which to determina a path), but at least when this test was created schema validation errors always got a node and an XPath value. If that ever changes, we can modify this test to something like: self.assertTrue(error_path is None or tree_path == error_path) That way, we can at least verify that if we did get a path value it wasn't bogus. """ tree = self.parse('<a><b>42</b><b>dada</b></a>') schema = self.parse(''' <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="a" type="AType"/> <xsd:complexType name="AType"> <xsd:sequence> <xsd:element name="b" type="xsd:integer" maxOccurs="2"/> </xsd:sequence> </xsd:complexType> </xsd:schema> ''') schema = etree.XMLSchema(schema) schema.validate(tree) tree_path = tree.getpath(tree.findall('b')[1]) error_path = schema.error_log[0].path self.assertTrue(tree_path == error_path)
def test_xmlschema_nested_resolvers(self): """Test that resolvers work in a nested fashion.""" resolver_schema = self.resolver_schema_ext class res_nested(etree.Resolver): def __init__(self, ext_schema): self.ext_schema = ext_schema def resolve(self, url, id, context): assert url == 'YYY.xsd' return self.resolve_string(self.ext_schema, context) class res(etree.Resolver): def __init__(self, ext_schema_1, ext_schema_2): self.ext_schema_1 = ext_schema_1 self.ext_schema_2 = ext_schema_2 def resolve(self, url, id, context): assert url == 'XXX.xsd' new_parser = etree.XMLParser() new_parser.resolvers.add(res_nested(self.ext_schema_2)) new_schema_doc = etree.parse(self.ext_schema_1, parser=new_parser) new_schema = etree.XMLSchema(new_schema_doc) return self.resolve_string(resolver_schema, context) parser = etree.XMLParser() parser.resolvers.add( res(self.resolver_schema_int2, self.resolver_schema_ext)) schema_doc = etree.parse(self.resolver_schema_int, parser=parser) schema = etree.XMLSchema(schema_doc)
def test_xmlschema_error_log(self): tree_valid = self.parse('<a><b></b></a>') tree_invalid = self.parse('<a><c></c></a>') schema = self.parse(''' <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="a" type="AType"/> <xsd:complexType name="AType"> <xsd:sequence> <xsd:element name="b" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:schema> ''') schema = etree.XMLSchema(schema) self.assertTrue(schema.validate(tree_valid)) self.assertFalse(schema.error_log.filter_from_errors()) self.assertFalse(schema.validate(tree_invalid)) self.assertTrue(schema.error_log.filter_from_errors()) self.assertTrue(schema.error_log.filter_types( etree.ErrorTypes.SCHEMAV_ELEMENT_CONTENT)) self.assertTrue(schema.validate(tree_valid)) self.assertFalse(schema.error_log.filter_from_errors()) self.assertFalse(schema.validate(tree_invalid)) self.assertTrue(schema.error_log.filter_from_errors()) self.assertTrue(schema.error_log.filter_types( etree.ErrorTypes.SCHEMAV_ELEMENT_CONTENT))
def test_xmlschema_import_file(self): # this will only work if we access the file through path or # file object.. schema = etree.XMLSchema(file=fileInTestDir('test_import.xsd')) tree_valid = self.parse( '<a:x xmlns:a="http://codespeak.net/lxml/schema/ns1"><b></b></a:x>') self.assertTrue(schema.validate(tree_valid))
def test_xmlschema_parse_default_attributes(self): # does not work as of libxml2 2.7.3 schema = self.parse(''' <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="a" type="AType"/> <xsd:complexType name="AType"> <xsd:sequence minOccurs="4" maxOccurs="4"> <xsd:element name="b" type="BType" /> </xsd:sequence> </xsd:complexType> <xsd:complexType name="BType"> <xsd:attribute name="hardy" type="xsd:string" default="hey" /> </xsd:complexType> </xsd:schema> ''') schema = etree.XMLSchema(schema) parser = etree.XMLParser(schema=schema, attribute_defaults=True) tree_valid = self.parse( '<a><b hardy="ho"/><b/><b hardy="ho"/><b/></a>', parser=parser) root = tree_valid.getroot() self.assertEquals('ho', root[0].get('hardy')) self.assertEquals('hey', root[1].get('hardy')) self.assertEquals('ho', root[2].get('hardy')) self.assertEquals('hey', root[3].get('hardy'))
def test_xmlschema_default_attributes(self): schema = self.parse(''' <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="a" type="AType"/> <xsd:complexType name="AType"> <xsd:sequence minOccurs="4" maxOccurs="4"> <xsd:element name="b" type="BType" /> </xsd:sequence> </xsd:complexType> <xsd:complexType name="BType"> <xsd:attribute name="hardy" type="xsd:string" default="hey" /> </xsd:complexType> </xsd:schema> ''') schema = etree.XMLSchema(schema, attribute_defaults=True) tree = self.parse('<a><b hardy="ho"/><b/><b hardy="ho"/><b/></a>') root = tree.getroot() self.assertEquals('ho', root[0].get('hardy')) self.assertEquals(None, root[1].get('hardy')) self.assertEquals('ho', root[2].get('hardy')) self.assertEquals(None, root[3].get('hardy')) self.assert_(schema(tree)) root = tree.getroot() self.assertEquals('ho', root[0].get('hardy')) self.assertEquals('hey', root[1].get('hardy')) self.assertEquals('ho', root[2].get('hardy')) self.assertEquals('hey', root[3].get('hardy'))
def test_xmlschema_resolvers_root(self): """Test that the default resolver will get called if there's no specific parser resolver.""" root_resolver = self.simple_resolver(self.resolver_schema_ext) etree.get_default_parser().resolvers.add(root_resolver) schema_doc = etree.parse(self.resolver_schema_int) schema = etree.XMLSchema(schema_doc) etree.get_default_parser().resolvers.remove(root_resolver)
def test_create_from_partial_doc(self): # this used to crash because the schema part was not properly copied out wsdl = self.parse('''\ <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <wsdl:types> <xs:schema> </xs:schema> </wsdl:types> </wsdl:definitions> ''') schema_element = wsdl.find("{http://schemas.xmlsoap.org/wsdl/}types/" "{http://www.w3.org/2001/XMLSchema}schema") etree.XMLSchema(schema_element) etree.XMLSchema(schema_element) etree.XMLSchema(schema_element)
def resolve(self, url, id, context): assert url == 'XXX.xsd' new_parser = etree.XMLParser() new_parser.resolvers.add(res_nested(self.ext_schema_2)) new_schema_doc = etree.parse(self.ext_schema_1, parser = new_parser) new_schema = etree.XMLSchema(new_schema_doc) return self.resolve_string(resolver_schema, context)
def test_schematron_xmlschema_embedded(self): schema = self.parse('''\ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:sch="http://purl.oclc.org/dsdl/schematron"> <xs:element name="message"> <xs:complexType> <xs:sequence> <xs:element name="number_of_entries" type="xs:positiveInteger"> <xs:annotation> <xs:appinfo> <sch:pattern id="number_of_entries"> <sch:title>mandatory number_of_entries tests</sch:title> <sch:rule context="number_of_entries"> <sch:assert test="text()=count(../entries/entry)">[ERROR] number_of_entries (<sch:value-of select="."/>) must equal the number of entries/entry elements (<sch:value-of select="count(../entries/entry)"/>)</sch:assert> </sch:rule> </sch:pattern> </xs:appinfo> </xs:annotation> </xs:element> <xs:element name="entries"> <xs:complexType> <xs:sequence> <xs:element name="entry" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> ''') tree_valid = self.parse('''\ <message> <number_of_entries>2</number_of_entries> <entries> <entry>Entry 1</entry> <entry>Entry 2</entry> </entries> </message> ''') tree_invalid = self.parse('''\ <message> <number_of_entries>1</number_of_entries> <entries> <entry>Entry 1</entry> <entry>Entry 2</entry> </entries> </message> ''') xmlschema = etree.XMLSchema(schema) schematron = isoschematron.Schematron(schema) # fwiw, this must also be XMLSchema-valid self.assertTrue(xmlschema(tree_valid), xmlschema.error_log) self.assertTrue(schematron(tree_valid)) # still schema-valid self.assertTrue(xmlschema(tree_invalid), xmlschema.error_log) self.assertTrue(not schematron(tree_invalid))
def test_xmlschema_file(self): # this will only work if we access the file through path or # file object.. f = open(fileInTestDir('test.xsd'), 'rb') try: schema = etree.XMLSchema(file=f) finally: f.close() tree_valid = self.parse('<a><b></b></a>') self.assert_(schema.validate(tree_valid))
def test_xmlschema_iterparse_fail(self): schema = self.parse(''' <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="a" type="AType"/> <xsd:complexType name="AType"> <xsd:sequence> <xsd:element name="b" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:schema> ''') schema = etree.XMLSchema(schema) self.assertRaises( etree.XMLSyntaxError, list, etree.iterparse(BytesIO('<a><c></c></a>'), schema=schema))
def test_xmlschema_illegal_validation_error(self): schema = self.parse(''' <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="a" type="xsd:string"/> </xsd:schema> ''') schema = etree.XMLSchema(schema) root = etree.Element('a') root.text = 'TEST' self.assertTrue(schema(root)) self.assertRaises(ValueError, schema, etree.Comment('TEST')) self.assertRaises(ValueError, schema, etree.PI('a', 'text')) self.assertRaises(ValueError, schema, etree.Entity('text'))
def test_xmlschema(self): tree_valid = self.parse('<a><b></b></a>') tree_invalid = self.parse('<a><c></c></a>') schema = self.parse(''' <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="a" type="AType"/> <xsd:complexType name="AType"> <xsd:sequence> <xsd:element name="b" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:schema> ''') schema = etree.XMLSchema(schema) self.assert_(schema.validate(tree_valid)) self.assert_(not schema.validate(tree_invalid))
def test_xmlschema_iterparse_incomplete(self): schema = self.parse(''' <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="a" type="AType"/> <xsd:complexType name="AType"> <xsd:sequence> <xsd:element name="b" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:schema> ''') schema = etree.XMLSchema(schema) xml = BytesIO('<a><b></b></a>') event, element = next(iter(etree.iterparse(xml, schema=schema))) self.assertEqual('end', event) self.assertEqual('b', element.tag)
def test_xmlschema_iterparse(self): schema = self.parse(''' <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="a" type="AType"/> <xsd:complexType name="AType"> <xsd:sequence> <xsd:element name="b" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:schema> ''') schema = etree.XMLSchema(schema) xml = BytesIO('<a><b></b></a>') events = [(event, el.tag) for (event, el) in etree.iterparse(xml, schema=schema)] self.assertEquals([('end', 'b'), ('end', 'a')], events)
def test_xmlschema_resolvers_noroot(self): """Test that the default resolver will not get called when a more specific resolver is registered.""" class res_root(etree.Resolver): def resolve(self, url, id, context): assert False return None root_resolver = res_root() etree.get_default_parser().resolvers.add(root_resolver) parser = etree.XMLParser() parser.resolvers.add(self.simple_resolver(self.resolver_schema_ext)) schema_doc = etree.parse(self.resolver_schema_int, parser=parser) schema = etree.XMLSchema(schema_doc) etree.get_default_parser().resolvers.remove(root_resolver)
def test_xmlschema_stringio(self): schema_file = BytesIO(''' <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="a" type="AType"/> <xsd:complexType name="AType"> <xsd:sequence> <xsd:element name="b" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:schema> ''') schema = etree.XMLSchema(file=schema_file) parser = etree.XMLParser(schema=schema) tree_valid = self.parse('<a><b></b></a>', parser=parser) self.assertEqual('a', tree_valid.getroot().tag) self.assertRaises(etree.XMLSyntaxError, self.parse, '<a><c></c></a>', parser=parser)
def test_xmlschema_resolvers(self): """Test that resolvers work with schema.""" parser = etree.XMLParser() parser.resolvers.add(self.simple_resolver(self.resolver_schema_ext)) schema_doc = etree.parse(self.resolver_schema_int, parser=parser) schema = etree.XMLSchema(schema_doc)