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 schema = etree.XMLSchema(file=f) 136 tree_valid = self.parse('<a><b></b></a>') 137 self.assert_(schema.validate(tree_valid))
138
139 - def test_xmlschema_shortcut(self):
140 tree_valid = self.parse('<a><b></b></a>') 141 tree_invalid = self.parse('<a><c></c></a>') 142 schema = self.parse('''\ 143 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 144 <xsd:element name="a" type="AType"/> 145 <xsd:complexType name="AType"> 146 <xsd:sequence> 147 <xsd:element name="b" type="xsd:string" /> 148 </xsd:sequence> 149 </xsd:complexType> 150 </xsd:schema> 151 ''') 152 self.assert_(tree_valid.xmlschema(schema)) 153 self.assert_(not tree_invalid.xmlschema(schema))
154 155 # 156 # schema + resolvers tests&data: 157 # 158 159 resolver_schema_int = BytesIO("""\ 160 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 161 xmlns:etype="/test/external" 162 targetNamespace="/test/internal"> 163 <xsd:import namespace="/test/external" schemaLocation="XXX.xsd" /> 164 <xsd:element name="a" type="etype:AType"/> 165 </xsd:schema>""") 166 167 resolver_schema_int2 = BytesIO("""\ 168 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 169 xmlns:etype="/test/external" 170 targetNamespace="/test/internal"> 171 <xsd:import namespace="/test/external" schemaLocation="YYY.xsd" /> 172 <xsd:element name="a" type="etype:AType"/> 173 </xsd:schema>""") 174 175 resolver_schema_ext = """\ 176 <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 177 targetNamespace="/test/external"> 178 <xsd:complexType name="AType"> 179 <xsd:sequence><xsd:element name="b" type="xsd:string" minOccurs="0" maxOccurs="unbounded" /></xsd:sequence> 180 </xsd:complexType> 181 </xsd:schema>""" 182
183 - class simple_resolver(etree.Resolver):
184 - def __init__(self, schema):
185 self.schema = schema
186
187 - def resolve(self, url, id, context):
188 assert url == 'XXX.xsd' 189 return self.resolve_string(self.schema, context)
190
191 - def test_xmlschema_resolvers(self):
192 """Test that resolvers work with schema.""" 193 parser = etree.XMLParser() 194 parser.resolvers.add(self.simple_resolver(self.resolver_schema_ext)) 195 schema_doc = etree.parse(self.resolver_schema_int, parser = parser) 196 schema = etree.XMLSchema(schema_doc)
197
199 """Test that the default resolver will get called if there's no 200 specific parser resolver.""" 201 root_resolver = self.simple_resolver(self.resolver_schema_ext) 202 etree.get_default_parser().resolvers.add(root_resolver) 203 schema_doc = etree.parse(self.resolver_schema_int) 204 schema = etree.XMLSchema(schema_doc) 205 etree.get_default_parser().resolvers.remove(root_resolver)
206
208 """Test that the default resolver will not get called when a more 209 specific resolver is registered.""" 210 211 class res_root(etree.Resolver): 212 def resolve(self, url, id, context): 213 assert False 214 return None
215 216 root_resolver = res_root() 217 etree.get_default_parser().resolvers.add(root_resolver) 218 219 parser = etree.XMLParser() 220 parser.resolvers.add(self.simple_resolver(self.resolver_schema_ext)) 221 222 schema_doc = etree.parse(self.resolver_schema_int, parser = parser) 223 schema = etree.XMLSchema(schema_doc) 224 etree.get_default_parser().resolvers.remove(root_resolver) 225
226 - def test_xmlschema_nested_resolvers(self):
227 """Test that resolvers work in a nested fashion.""" 228 229 resolver_schema = self.resolver_schema_ext 230 231 class res_nested(etree.Resolver): 232 def __init__(self, ext_schema): 233 self.ext_schema = ext_schema
234 235 def resolve(self, url, id, context): 236 assert url == 'YYY.xsd' 237 return self.resolve_string(self.ext_schema, context) 238 239 class res(etree.Resolver): 240 def __init__(self, ext_schema_1, ext_schema_2): 241 self.ext_schema_1 = ext_schema_1 242 self.ext_schema_2 = ext_schema_2 243 244 def resolve(self, url, id, context): 245 assert url == 'XXX.xsd' 246 247 new_parser = etree.XMLParser() 248 new_parser.resolvers.add(res_nested(self.ext_schema_2)) 249 new_schema_doc = etree.parse(self.ext_schema_1, parser = new_parser) 250 new_schema = etree.XMLSchema(new_schema_doc) 251 252 return self.resolve_string(resolver_schema, context) 253 254 parser = etree.XMLParser() 255 parser.resolvers.add(res(self.resolver_schema_int2, self.resolver_schema_ext)) 256 schema_doc = etree.parse(self.resolver_schema_int, parser = parser) 257 schema = etree.XMLSchema(schema_doc) 258
259 -def test_suite():
260 suite = unittest.TestSuite() 261 suite.addTests([unittest.makeSuite(ETreeXMLSchemaTestCase)]) 262 suite.addTests( 263 [make_doctest('../../../doc/validation.txt')]) 264 return suite
265 266 if __name__ == '__main__': 267 print('to test use test.py %s' % __file__) 268