1
2
3 """PyXB stands for Python U{W3C XML
4 Schema<http://www.w3.org/XML/Schema>} Bindings, and is pronounced
5 "pixbee". It enables translation between XML instance documents and
6 Python objects following rules specified by an XML Schema document.
7
8 This is the top-level entrypoint to the PyXB system. Importing this
9 gets you all the L{exceptions<pyxb.exceptions_.PyXBException>}, and
10 L{pyxb.namespace}. For more functionality, delve into these
11 submodules:
12
13 - L{pyxb.xmlschema} Module holding the
14 L{structures<pyxb.xmlschema.structures>} that convert XMLSchema
15 from a DOM model to a Python class model based on the XMLSchema
16 components. Use this when you need to operate on the component
17 model.
18
19 - L{pyxb.binding} Module used to generate the bindings and at runtime
20 to support the generated bindings. Use this if you need to use the
21 binding model or content model.
22
23 - L{pyxb.utils} Common utilities used in parsing, generating, and
24 executing. The submodules must be imported separately.
25
26 """
27
28 import logging
29 from pyxb.utils import six
30
31 _log = logging.getLogger(__name__)
32
34 """This little bundle of joy exists because in Python 2.6 it
35 became an error to invoke C{object.__init__} with parameters (unless
36 you also override C{__new__}, in which case it's only a warning.
37 Whatever.). Since I'm bloody not going to check in every class
38 whether C{super(Myclass,self)} refers to C{object} (even if I could
39 figure out how to do that, 'cuz the obvious solutions don't work),
40 we'll just make this thing the root of all U{cooperative super
41 calling<http://www.geocities.com/foetsch/python/new_style_classes.htm#super>}
42 hierarchies. The standard syntax in PyXB for this pattern is::
43
44 def method_csc (self, *args, **kw):
45 self_fn = lambda *_args, **_kw: self
46 super_fn = getattr(super(ThisClass, self), 'method_csc', self_fn)
47 return super_fn(*args, **kw)
48
49 """
50
52
53
54
55
56
57
58
59
60
61 if issubclass(self.__class__.mro()[-2], ( list, dict )):
62 super(cscRoot, self).__init__(*args)
63
64 __version__ = '1.2.5'
65 """The version of PyXB"""
66
67 __url__ = 'http://pyxb.sourceforge.net'
68 """The URL for PyXB's homepage"""
69
70 __license__ = 'Apache License 2.0'
71
72
73 from pyxb.exceptions_ import *
74
75
76 import pyxb.namespace
77
79 """Bundle data for automated binding generation.
80
81 Instances of this class capture positional and keyword arguments that are
82 used to create binding instances based on context. For example, if C{w}
83 is an instance of a complex type whose C{option} element is declared to be
84 an anonymous class with simple content of type integer and an attribute of
85 C{units}, a correct assignment to that element could be achieved with::
86
87 w.option = BIND(54, units="m")
88
89 """
90 __args = None
91 __kw = None
92
94 """Cache parameters for subsequent binding creation.
95 Invoke just as you would the factory for a binding class."""
96 self.__args = args
97 self.__kw = kw
98
100 """Invoke the given factory method.
101
102 Position arguments to the factory are those cached in this instance.
103 Keyword arguments are the ones on the command line, updated from the
104 ones in this instance."""
105 kw.update(self.__kw)
106 return factory(*self.__args, **kw)
107
108
109 XMLStyle_minidom = 0
110 """Use xml.dom.minidom for XML processing. This is the fastest, but does not
111 provide location information. It produces DOM instances."""
112
113 XMLStyle_saxdom = 1
114 """Use pyxb.utils.saxdom for XML processing. This is the slowest, but both
115 provides location information and generates a DOM instance."""
116
117 XMLStyle_saxer = 2
118 """Use pyxb.binding.saxer when converting documents to binding instances.
119 This style supports location information in the bindings. It produces binding
120 instances directly, without going through a DOM stage, so is faster than
121 XMLStyle_saxdom. However, since the pyxb.xmlschema.structures classes require
122 a DOM model, XMLStyle_saxdom will be used for pyxb.utils.domutils.StringToDOM
123 if this style is selected."""
124
125 _XMLStyle = XMLStyle_saxer
126 """The current XML processing style."""
127
128 _XMLStyleMap = { 'minidom' : XMLStyle_minidom,
129 'saxdom' : XMLStyle_saxdom,
130 'saxer' : XMLStyle_saxer }
131 _XMLStyleMapReverse = dict([ (_v, _k) for (_k, _v) in six.iteritems(_XMLStyleMap) ])
132
133 _XMLStyle_envvar = 'PYXB_XML_STYLE'
134
136 """Set the interface used to parse XML content.
137
138 This can be invoked within code. The system default of L{XMLStyle_saxer}
139 can also be overridden at runtime by setting the environment variable
140 C{PYXB_XML_STYLE} to one of C{minidom}, C{saxdom}, or C{saxer}.
141
142 @param style: One of L{XMLStyle_minidom}, L{XMLStyle_saxdom},
143 L{XMLStyle_saxer}. If not provided, the system default is used.
144 """
145 global _XMLStyle
146 if style is None:
147 import os
148 style_name = os.environ.get(_XMLStyle_envvar)
149 if style_name is None:
150 style_name = 'saxer'
151 style = _XMLStyleMap.get(style_name)
152 if style is None:
153 raise PyXBException('Bad value "%s" for %s' % (style_name, _XMLStyle_envvar))
154 if _XMLStyleMapReverse.get(style) is None:
155 raise PyXBException('Bad value %s for _SetXMLStyle' % (style,))
156 _XMLStyle = style
157
158 _SetXMLStyle()
159
160
161
162
163 _OptimizationActive = False
164 try:
165 assert False
166 _OptimizationActive = True
167 except:
168 pass
169
170 _CorruptionDetectionEnabled = not _OptimizationActive
171 """If C{True}, blocks attempts to assign to attributes that are reserved for
172 PyXB methods.
173
174 Applies only at compilation time; dynamic changes are ignored.
175 """
176
178 """Class holding configuration related to validation.
179
180 L{pyxb.GlobalValidationConfig} is available to influence validation in all
181 contexts. Each binding class has a reference to an instance of this
182 class, which can be inspected using
183 L{pyxb.binding.basis._TypeBinding_mixin._GetValidationConfig} and changed
184 using L{pyxb.binding.basis._TypeBinding_mixin._SetValidationConfig}. Each
185 binding instance has a reference inherited from its class which can be
186 inspected using L{pyxb.binding.basis._TypeBinding_mixin._validationConfig}
187 and changed using
188 L{pyxb.binding.basis._TypeBinding_mixin._setValidationConfig}.
189
190 This allows fine control on a per class and per-instance basis.
191
192 L{forBinding} replaces L{RequireValidWhenParsing}.
193
194 L{forDocument} replaces L{RequireValidWhenGenerating}.
195
196 L{contentInfluencesGeneration}, L{orphanElementInContent}, and
197 L{invalidElementInContent} control how
198 L{pyxb.binding.basis.complexTypeDefinition.orderedContent} affects
199 generated documents.
200 """
201
202 __forBinding = True
204 """C{True} iff validation should be performed when manipulating a
205 binding instance.
206
207 This includes parsing a document or DOM tree, using a binding instance
208 class constructor, or assigning to an element or attribute field of a
209 binding instance."""
210 return self.__forBinding
212 """Configure whether validation should be performed when manipulating
213 a binding instance."""
214 if not isinstance(value, bool):
215 raise TypeError(value)
216 self.__forBinding = value
217 return value
218 forBinding = property(_getForBinding)
219
220 __forDocument = True
222 """C{True} iff validation should be performed when creating a document
223 from a binding instance.
224
225 This applies at invocation of
226 L{toDOM()<pyxb.binding.basis._TypeBinding_mixin.toDOM>}.
227 L{toxml()<pyxb.binding.basis._TypeBinding_mixin.toDOM>} invokes C{toDOM()}."""
228 return self.__forDocument
230 """Configure whether validation should be performed when generating
231 a document from a binding instance."""
232 if not isinstance(value, bool):
233 raise TypeError(value)
234 self.__forDocument = value
235 return value
236 forDocument = property(_getForDocument)
237
238 ALWAYS = -1
239 """Always do it."""
240
241 NEVER = 0
242 """Never do it."""
243
244 IGNORE_ONCE = 1
245 """If an error occurs ignore it and continue with the next one. (E.g., if
246 an element in a content list fails skip it and continue with the next
247 element in the list.)"""
248
249 GIVE_UP = 2
250 """If an error occurs ignore it and stop using whatever provided the cause
251 of the error. (E.g., if an element in a content list fails stop
252 processing the content list and execute as though it was absent)."""
253
254 RAISE_EXCEPTION = 3
255 """If an error occurs, raise an exception."""
256
257 MIXED_ONLY = 4
258 """Only when content type is mixed."""
259
260 __contentInfluencesGeneration = MIXED_ONLY
262 """Determine whether complex type content influences element order in
263 document generation.
264
265 The value is one of L{ALWAYS}, L{NEVER}, L{MIXED_ONLY} (default)."""
266 return self.__contentInfluencesGeneration
268 """Set the value of L{contentInfluencesGeneration}."""
269 if not (value in ( self.ALWAYS, self.NEVER, self.MIXED_ONLY )):
270 raise ValueError(value)
271 self.__contentInfluencesGeneration = value
272 contentInfluencesGeneration = property(__getContentInfluencesGeneration)
273
274 __orphanElementInContent = IGNORE_ONCE
276 """How to handle unrecognized elements in content lists.
277
278 This is used when consulting a complex type instance content list to
279 influence the generation of documents from a binding instance.
280
281 The value is one of L{IGNORE_ONCE} (default), L{GIVE_UP},
282 L{RAISE_EXCEPTION}."""
283 return self.__orphanElementInContent
285 """Set the value of L{orphanElementInContent}."""
286 if not (value in ( self.IGNORE_ONCE, self.GIVE_UP, self.RAISE_EXCEPTION )):
287 raise ValueError(value)
288 self.__orphanElementInContent = value
289 orphanElementInContent = property(__getOrphanElementInContent)
290
291 __invalidElementInContent = IGNORE_ONCE
293 """How to handle invalid elements in content lists.
294
295 The value is one of L{IGNORE_ONCE} (default), L{GIVE_UP},
296 L{RAISE_EXCEPTION}."""
297 return self.__invalidElementInContent
299 """Set the value of L{invalidElementInContent}."""
300 if not (value in ( self.IGNORE_ONCE, self.GIVE_UP, self.RAISE_EXCEPTION )):
301 raise ValueError(value)
302 self.__invalidElementInContent = value
303 invalidElementInContent = property(__getInvalidElementInContent)
304
306 """Make a copy of this instance.
307
308 Use this to get a starting point when you need to customize validation
309 on a per-instance/per-class basis."""
310 import copy
311 return copy.copy(self)
312
313 GlobalValidationConfig = ValidationConfig()
314
315 _GenerationRequiresValid = True
316 """Legacy flag; prefer L{forDocument<ValidationConfig.forDocument>} in L{GlobalValidationConfig}."""
317
319 """Query or set a flag that controls validation checking in XML generation.
320
321 Normally any attempts to convert a binding instance to a DOM or XML
322 representation requires that the binding validate against the content
323 model, since only in this way can the content be generated in the correct
324 order. In some cases it may be necessary or useful to generate a document
325 from a binding that is incomplete. If validation is not required, the
326 generated documents may not validate even if the content validates,
327 because ordering constraints will be ignored.
328
329 @keyword value: If absent or C{None}, no change is made; otherwise, this
330 enables (C{True}) or disables (C{False}) the requirement that instances
331 validate before being converted to XML.
332 @type value: C{bool}
333
334 @return: C{True} iff attempts to generate XML for a binding that does not
335 validate should raise an exception. """
336 if value is None:
337 return GlobalValidationConfig.forDocument
338 global _GenerationRequiresValid
339 _GenerationRequiresValid = GlobalValidationConfig._setForDocument(value)
340 return value
341
342 _ParsingRequiresValid = True
343 """Legacy flag; prefer L{forBinding<ValidationConfig.forBinding>} in L{GlobalValidationConfig}."""
345 """Query or set a flag that controls validation checking in XML parsing.
346
347 Normally any attempts to convert XML to a binding instance to a binding
348 instance requires that the document validate against the content model.
349 In some cases it may be necessary or useful to process a document that is
350 incomplete. If validation is not required, the generated documents may
351 not validate even if the content validates, because ordering constraints
352 will be ignored.
353
354 @keyword value: If absent or C{None}, no change is made; otherwise, this
355 enables (C{True}) or disables (C{False}) the requirement that documents
356 validate when being converted to bindings.
357 @type value: C{bool}
358
359 @return: C{True} iff attempts to generate bindings for a document that
360 does not validate should raise an exception."""
361 if value is None:
362 return GlobalValidationConfig.forBinding
363 global _ParsingRequiresValid
364 _ParsingRequiresValid = GlobalValidationConfig._setForBinding(value)
365 return _ParsingRequiresValid
366
367 _PreserveInputTimeZone = False
385
386 _OutputEncoding = 'utf-8'
387 """Default unicode encoding to use when creating output.
388
389 Material being written to an XML parser is not output."""
390
391 _InputEncoding = 'utf-8'
392 """Default unicode encoding to assume when decoding input.
393
394 Material being written to an XML parser is treated as input."""
395
396 -def NonElementContent (instance):
397 """Return an iterator producing the non-element content of the provided instance.
398
399 The catenated text of the non-element content of an instance can
400 be obtained with::
401
402 text = six.u('').join(pyxb.NonElementContent(instance))
403
404 @param instance: An instance of L{pyxb.binding.basis.complexTypeDefinition}.
405
406 @return: an iterator producing text values
407 """
408 import pyxb.binding.basis
409 return pyxb.binding.basis.NonElementContent.ContentIterator(instance.orderedContent())
410
411
412
413
414