1
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)
12
13 from common_imports import etree, BytesIO, HelperTestCase, fileInTestDir
14 from common_imports import doctest, make_doctest
15
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
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
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
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
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
130
138
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
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
186
187 - def resolve(self, url, id, context):
188 assert url == 'XXX.xsd'
189 return self.resolve_string(self.schema, context)
190
197
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
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
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