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