Package lxml :: Package tests :: Module test_xmlschema
[hide private]
[frames] | no frames]

Source Code for Module lxml.tests.test_xmlschema

  1  # -*- coding: utf-8 -*- 
  2   
  3  """ 
  4  Test cases related to XML Schema parsing and validation 
  5  """ 
  6   
  7  import unittest, sys, os.path 
  8   
  9  this_dir = os.path.dirname(__file__) 
 10  if this_dir not in sys.path: 
 11      sys.path.insert(0, this_dir) # needed for Py3 
 12   
 13  from common_imports import etree, BytesIO, HelperTestCase, fileInTestDir 
 14  from common_imports import doctest, make_doctest 
 15   
16 -class ETreeXMLSchemaTestCase(HelperTestCase):
17 - def test_xmlschema(self):
18 tree_valid = self.parse('<a><b></b></a>') 19 tree_invalid = self.parse('<a><c></c></a>') 20 schema = self.parse(''' 21 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 22 <xsd:element name="a" type="AType"/> 23 <xsd:complexType name="AType"> 24 <xsd:sequence> 25 <xsd:element name="b" type="xsd:string" /> 26 </xsd:sequence> 27 </xsd:complexType> 28 </xsd:schema> 29 ''') 30 schema = etree.XMLSchema(schema) 31 self.assert_(schema.validate(tree_valid)) 32 self.assert_(not schema.validate(tree_invalid))
33
34 - def test_xmlschema_parse(self):
35 schema = self.parse(''' 36 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 37 <xsd:element name="a" type="AType"/> 38 <xsd:complexType name="AType"> 39 <xsd:sequence> 40 <xsd:element name="b" type="xsd:string" /> 41 </xsd:sequence> 42 </xsd:complexType> 43 </xsd:schema> 44 ''') 45 schema = etree.XMLSchema(schema) 46 parser = etree.XMLParser(schema=schema) 47 48 tree_valid = self.parse('<a><b></b></a>', parser=parser) 49 self.assertEquals('a', tree_valid.getroot().tag) 50 51 self.assertRaises(etree.XMLSyntaxError, 52 self.parse, '<a><c></c></a>', parser=parser)
53
54 - def test_xmlschema_stringio(self):
55 schema_file = BytesIO(''' 56 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 57 <xsd:element name="a" type="AType"/> 58 <xsd:complexType name="AType"> 59 <xsd:sequence> 60 <xsd:element name="b" type="xsd:string" /> 61 </xsd:sequence> 62 </xsd:complexType> 63 </xsd:schema> 64 ''') 65 schema = etree.XMLSchema(file=schema_file) 66 parser = etree.XMLParser(schema=schema) 67 68 tree_valid = self.parse('<a><b></b></a>', parser=parser) 69 self.assertEquals('a', tree_valid.getroot().tag) 70 71 self.assertRaises(etree.XMLSyntaxError, 72 self.parse, '<a><c></c></a>', parser=parser)
73
74 - def test_xmlschema_iterparse(self):
75 schema = self.parse(''' 76 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 77 <xsd:element name="a" type="AType"/> 78 <xsd:complexType name="AType"> 79 <xsd:sequence> 80 <xsd:element name="b" type="xsd:string" /> 81 </xsd:sequence> 82 </xsd:complexType> 83 </xsd:schema> 84 ''') 85 schema = etree.XMLSchema(schema) 86 xml = BytesIO('<a><b></b></a>') 87 events = [ (event, el.tag) 88 for (event, el) in etree.iterparse(xml, schema=schema) ] 89 90 self.assertEquals([('end', 'b'), ('end', 'a')], 91 events)
92
94 schema = self.parse(''' 95 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 96 <xsd:element name="a" type="AType"/> 97 <xsd:complexType name="AType"> 98 <xsd:sequence> 99 <xsd:element name="b" type="xsd:string" /> 100 </xsd:sequence> 101 </xsd:complexType> 102 </xsd:schema> 103 ''') 104 schema = etree.XMLSchema(schema) 105 self.assertRaises( 106 etree.XMLSyntaxError, 107 list, etree.iterparse(BytesIO('<a><c></c></a>'), schema=schema))
108
110 self.assertRaises(ValueError, etree.XMLSchema, etree.ElementTree())
111
113 schema = self.parse('''\ 114 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 115 <element name="a" type="AType"/> 116 <xsd:complexType name="AType"> 117 <xsd:sequence> 118 <xsd:element name="b" type="xsd:string" /> 119 </xsd:sequence> 120 </xsd:complexType> 121 </xsd:schema> 122 ''') 123 self.assertRaises(etree.XMLSchemaParseError, 124 etree.XMLSchema, schema)
125
127 schema = self.parse('<test/>') 128 self.assertRaises(etree.XMLSchemaParseError, 129 etree.XMLSchema, schema)
130
131 - def test_xmlschema_file(self):
132 # this will only work if we access the file through path or 133 # file object.. 134 f = open(fileInTestDir('test.xsd'), 'rb') 135 try: 136 schema = etree.XMLSchema(file=f) 137 finally: 138 f.close() 139 tree_valid = self.parse('<a><b></b></a>') 140 self.assert_(schema.validate(tree_valid))
141
143 # this will only work if we access the file through path or 144 # file object.. 145 schema = etree.XMLSchema(file=fileInTestDir('test_import.xsd')) 146 tree_valid = self.parse( 147 '<a:x xmlns:a="http://codespeak.net/lxml/schema/ns1"><b></b></a:x>') 148 self.assert_(schema.validate(tree_valid))
149
150 - def test_xmlschema_shortcut(self):
151 tree_valid = self.parse('<a><b></b></a>') 152 tree_invalid = self.parse('<a><c></c></a>') 153 schema = self.parse('''\ 154 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 155 <xsd:element name="a" type="AType"/> 156 <xsd:complexType name="AType"> 157 <xsd:sequence> 158 <xsd:element name="b" type="xsd:string" /> 159 </xsd:sequence> 160 </xsd:complexType> 161 </xsd:schema> 162 ''') 163 self.assert_(tree_valid.xmlschema(schema)) 164 self.assert_(not tree_invalid.xmlschema(schema))
165 166
167 -class ETreeXMLSchemaResolversTestCase(HelperTestCase):
168 resolver_schema_int = BytesIO("""\ 169 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 170 xmlns:etype="http://codespeak.net/lxml/test/external" 171 targetNamespace="http://codespeak.net/lxml/test/internal"> 172 <xsd:import namespace="http://codespeak.net/lxml/test/external" schemaLocation="XXX.xsd" /> 173 <xsd:element name="a" type="etype:AType"/> 174 </xsd:schema>""") 175 176 resolver_schema_int2 = BytesIO("""\ 177 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 178 xmlns:etype="http://codespeak.net/lxml/test/external" 179 targetNamespace="http://codespeak.net/lxml/test/internal"> 180 <xsd:import namespace="http://codespeak.net/lxml/test/external" schemaLocation="YYY.xsd" /> 181 <xsd:element name="a" type="etype:AType"/> 182 </xsd:schema>""") 183 184 resolver_schema_ext = """\ 185 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 186 targetNamespace="http://codespeak.net/lxml/test/external"> 187 <xsd:complexType name="AType"> 188 <xsd:sequence><xsd:element name="b" type="xsd:string" minOccurs="0" maxOccurs="unbounded" /></xsd:sequence> 189 </xsd:complexType> 190 </xsd:schema>""" 191
192 - class simple_resolver(etree.Resolver):
193 - def __init__(self, schema):
194 self.schema = schema
195
196 - def resolve(self, url, id, context):
197 assert url == 'XXX.xsd' 198 return self.resolve_string(self.schema, context)
199 200 # tests: 201
202 - def test_xmlschema_resolvers(self):
203 """Test that resolvers work with schema.""" 204 parser = etree.XMLParser() 205 parser.resolvers.add(self.simple_resolver(self.resolver_schema_ext)) 206 schema_doc = etree.parse(self.resolver_schema_int, parser = parser) 207 schema = etree.XMLSchema(schema_doc)
208
210 """Test that the default resolver will get called if there's no 211 specific parser resolver.""" 212 root_resolver = self.simple_resolver(self.resolver_schema_ext) 213 etree.get_default_parser().resolvers.add(root_resolver) 214 schema_doc = etree.parse(self.resolver_schema_int) 215 schema = etree.XMLSchema(schema_doc) 216 etree.get_default_parser().resolvers.remove(root_resolver)
217
219 """Test that the default resolver will not get called when a more 220 specific resolver is registered.""" 221 222 class res_root(etree.Resolver): 223 def resolve(self, url, id, context): 224 assert False 225 return None
226 227 root_resolver = res_root() 228 etree.get_default_parser().resolvers.add(root_resolver) 229 230 parser = etree.XMLParser() 231 parser.resolvers.add(self.simple_resolver(self.resolver_schema_ext)) 232 233 schema_doc = etree.parse(self.resolver_schema_int, parser = parser) 234 schema = etree.XMLSchema(schema_doc) 235 etree.get_default_parser().resolvers.remove(root_resolver) 236
237 - def test_xmlschema_nested_resolvers(self):
238 """Test that resolvers work in a nested fashion.""" 239 240 resolver_schema = self.resolver_schema_ext 241 242 class res_nested(etree.Resolver): 243 def __init__(self, ext_schema): 244 self.ext_schema = ext_schema
245 246 def resolve(self, url, id, context): 247 assert url == 'YYY.xsd' 248 return self.resolve_string(self.ext_schema, context) 249 250 class res(etree.Resolver): 251 def __init__(self, ext_schema_1, ext_schema_2): 252 self.ext_schema_1 = ext_schema_1 253 self.ext_schema_2 = ext_schema_2 254 255 def resolve(self, url, id, context): 256 assert url == 'XXX.xsd' 257 258 new_parser = etree.XMLParser() 259 new_parser.resolvers.add(res_nested(self.ext_schema_2)) 260 new_schema_doc = etree.parse(self.ext_schema_1, parser = new_parser) 261 new_schema = etree.XMLSchema(new_schema_doc) 262 263 return self.resolve_string(resolver_schema, context) 264 265 parser = etree.XMLParser() 266 parser.resolvers.add(res(self.resolver_schema_int2, self.resolver_schema_ext)) 267 schema_doc = etree.parse(self.resolver_schema_int, parser = parser) 268 schema = etree.XMLSchema(schema_doc) 269
270 -def test_suite():
271 suite = unittest.TestSuite() 272 suite.addTests([unittest.makeSuite(ETreeXMLSchemaTestCase)]) 273 suite.addTests([unittest.makeSuite(ETreeXMLSchemaResolversTestCase)]) 274 suite.addTests( 275 [make_doctest('../../../doc/validation.txt')]) 276 return suite
277 278 if __name__ == '__main__': 279 print('to test use test.py %s' % __file__) 280