Package pyxb :: Package binding :: Module basis |
[hide private]
[frames] | no frames]

# Source Code for Module pyxb.binding.basis

       1  # -*- coding: utf-8 -*-
       2  # Copyright 2009-2013, Peter A. Bigot
       3  #
       4  # Licensed under the Apache License, Version 2.0 (the "License"); you may
       5  # not use this file except in compliance with the License. You may obtain a
       6  # copy of the License at:
       7  #
       8  #            http://www.apache.org/licenses/LICENSE-2.0
       9  #
      10  # Unless required by applicable law or agreed to in writing, software
      11  # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
      12  # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
      13  # License for the specific language governing permissions and limitations
      14  # under the License.
      15
      16  """This module contains support classes from which schema-specific bindings
      17  inherit, and that describe the content models of those schema."""
      18
      19  import logging
      20  import pyxb
      21  import xml.dom
      22  import pyxb.utils.domutils as domutils
      23  import pyxb.utils.utility as utility
      24  import types
      25  import pyxb.namespace
      26  import collections
      27  from pyxb.namespace.builtin import XMLSchema_instance as XSI
      28
      29  _log = logging.getLogger(__name__)
      30
      31 -class _TypeBinding_mixin (utility.Locatable_mixin):
      32      # Private member holding the validation configuration that applies to the
      33      # class or instance.  Can't really make it private with __ prefix because
      34      # that would screw up parent classes.  You end users---stay away from
      35      # this.
      36      _validationConfig_ = pyxb.GlobalValidationConfig
      37
      38      @classmethod
      39 -    def _SetValidationConfig (cls, validation_config):
      40          """Set the validation configuration for this class."""
      41          cls._validationConfig_ = validation_config
      42
      43      @classmethod
      44 -    def _GetValidationConfig (cls):
      45          """The L{pyxb.ValidationConfig} instance that applies to this class.
      46
      47          By default this will reference L{pyxb.GlobalValidationConfig}."""
      48          return cls._validationConfig_
      49
      50 -    def _setValidationConfig (self, validation_config):
      51          """Set the validation configuration for this instance."""
      52          self._validationConfig_ = validation_config
      53
      54 -    def __getValidationConfig (self):
      55          """The L{pyxb.ValidationConfig} instance that applies to this instance.
      56
      57          By default this will reference the class value from
      58          L{_GetValidationConfig}, which defaults to
      59          L{pyxb.GlobalValidationConfig}."""
      60          return self._validationConfig_
      61
      62      # This is how you should be accessing this value.
      63      _validationConfig = property(__getValidationConfig)
      64
      65      @classmethod
      66 -    def _PerformValidation (cls):
      67          """Determine whether the content model should be validated for this class.
      68
      69          In the absence of context, this returns C{True} iff both binding and
      70          document validation are in force.
      71
      72          @deprecated: use L{_GetValidationConfig} and check specific requirements."""
      73          # Bypass the property since this is a class method
      74          vo = cls._validationConfig_
      75          return vo.forBinding and vo.forDocument
      76
      77 -    def _performValidation (self):
      78          """Determine whether the content model should be validated for this
      79          instance.
      80
      81          In the absence of context, this returns C{True} iff both binding and
      82          document validation are in force.
      83
      84          @deprecated: use L{_validationConfig} and check specific requirements."""
      85          vo = self._validationConfig
      86          return vo.forBinding and vo.forDocument
      87
      88      _ExpandedName = None
      89      """The expanded name of the component."""
      90
      91      _XSDLocation = None
      92      """Where the definition can be found in the originating schema."""
      93
      94      _ReservedSymbols = set([ 'validateBinding', 'toDOM', 'toxml', 'Factory', 'property' ])
      95
      96      if pyxb._CorruptionDetectionEnabled:
      97 -        def __setattr__ (self, name, value):
      98              if name in self._ReservedSymbols:
      99                  raise pyxb.ReservedNameError(self, name)
     100              return super(_TypeBinding_mixin, self).__setattr__(name, value)
     101
     102      _PyXBFactoryKeywords = ( '_dom_node', '_fallback_namespace', '_from_xml',
     103                               '_apply_whitespace_facet', '_validate_constraints',
     104                               '_require_value', '_nil', '_element', '_apply_attributes',
     105                               '_convert_string_values', '_location' )
     106      """Keywords that are interpreted by __new__ or __init__ in one or more
     107      classes in the PyXB type hierarchy.  All these keywords must be removed
     108      before invoking base Python __init__ or __new__."""
     109
     110      # While simple type definitions cannot be abstract, they can appear in
     111      # many places where complex types can, so we want it to be legal to test
     112      # for abstractness without checking whether the object is a complex type.
     113      _Abstract = False
     114
     115 -    def _namespaceContext (self):
     116          """Return a L{namespace context <pyxb.binding.NamespaceContext>}
     117          associated with the binding instance.
     118
     119          This will return C{None} unless something has provided a context to
     120          the instance.  Context is provided when instances are generated by the
     121          DOM and SAX-based translators."""
     122          return self.__namespaceContext
     123 -    def _setNamespaceContext (self, namespace_context):
     124          """Associate a L{namespace context <pyxb.binding.NamespaceContext>}
     125          with the binding instance."""
     126          self.__namespaceContext = namespace_context
     127          return self
     128      __namespaceContext = None
     129
     130 -    def _setElement (self, elt):
     131          """Associate an element binding with the instance.
     132
     133          Since the value of a binding instance reflects only its content, an
     134          associated element is necessary to generate an XML document or DOM
     135          tree.
     136
     137          @param elt: the L{pyxb.binding.basis.element} instance associated with
     138          the value.  This may be C{None} when disassociating a value from a
     139          specific element."""
     140          import pyxb.binding.content
     141          assert (elt is None) or isinstance(elt, element)
     142          self.__element = elt
     143          return self
     144 -    def _element (self):
     145          """Return a L{pyxb.binding.basis.element} associated with the binding
     146          instance.
     147
     148          This will return C{None} unless an element has been associated.
     149          Constructing a binding instance using the element instance will add
     150          this association.
     151          """
     152          return self.__element
     153      __element = None
     154
     155      __xsiNil = None
     156 -    def _isNil (self):
     157          """Indicate whether this instance is U{nil
     158          <http://www.w3.org/TR/xmlschema-1/#xsi_nil>}.
     159
     160          The value is set by the DOM and SAX parsers when building an instance
     161          from a DOM element with U{xsi:nil
     162          <http://www.w3.org/TR/xmlschema-1/#xsi_nil>} set to C{true}.
     163
     164          @return: C{None} if the element used to create the instance is not
     165          U{nillable<http://www.w3.org/TR/xmlschema-1/#nillable>}.
     166          If it is nillable, returns C{True} or C{False} depending on
     167          whether the instance itself is U{nil<http://www.w3.org/TR/xmlschema-1/#xsi_nil>}.
     168          """
     169          return self.__xsiNil
     170 -    def _setIsNil (self, nil=True):
     171          """Set the xsi:nil property of the instance.
     172
     173          @param nil: C{True} if the value of xsi:nil should be C{true},
     174          C{False} if the value of xsi:nil should be C{false}.
     175
     176          @raise pyxb.NoNillableSupportError: the instance is not associated
     177          with an element that is L{nillable
     178          <pyxb.binding.basis.element.nillable>}.
     179          """
     180          if self.__xsiNil is None:
     181              raise pyxb.NoNillableSupportError(self)
     182          self.__xsiNil = not not nil
     183          if self.__xsiNil:
     184              # The element must be empty, so also remove all element content.
     185              # Attribute values are left unchanged.
     186              self._resetContent(reset_elements=True)
     187
     188 -    def _resetContent (self, reset_elements=False):
     189          """Reset the content of an element value.
     190
     191          This is not a public method.
     192
     193          For simple types, this does nothing. For complex types, this clears the
     194          L{content<complexTypeDefinition.content>} array, removing all
     195          non-element content from the instance.  It optionally also removes all
     196          element content.
     197
     198          @param reset_elements: If C{False} (default) only the content array is
     199          cleared, which has the effect of removing any preference for element
     200          order when generating a document.  If C{True}, the element content
     201          stored within the binding is also cleared, leaving it with no content
     202          at all.
     203
     204          @note: This is not the same thing as L{complexTypeDefinition.reset},
     205          which unconditionally resets attributes and element and non-element
     206          content.
     207          """
     208          pass
     209
     210      __constructedWithValue = False
     211 -    def __checkNilCtor (self, args):
     212          self.__constructedWithValue = (0 < len(args))
     213          if self.__xsiNil:
     214              if self.__constructedWithValue:
     215                  raise pyxb.ContentInNilInstanceError(self, args[0])
     216          else:
     217              # Types that descend from string will, when constructed from an
     218              # element with empty content, appear to have no constructor value,
     219              # while in fact an empty string should have been passed.
     220              if issubclass(type(self), basestring):
     221                  self.__constructedWithValue = True
     222 -    def _constructedWithValue (self):
     223          return self.__constructedWithValue
     224
     225      # Flag used to control whether we print a warning when creating a complex
     226      # type instance that does not have an associated element.  Not sure yet
     227      # whether that'll be common practice or common error.
     228      __WarnedUnassociatedElement = False
     229
     230 -    def __init__ (self, *args, **kw):
     231          # Strip keyword not used above this level.
     232          element = kw.pop('_element', None)
     233          is_nil = kw.pop('_nil', False)
     234          super(_TypeBinding_mixin, self).__init__(*args, **kw)
     235          if (element is None) or element.nillable():
     236              self.__xsiNil = is_nil
     237          if element is not None:
     238              self._setElement(element)
     239          self.__checkNilCtor(args)
     240
     241      @classmethod
     242 -    def _PreFactory_vx (cls, args, kw):
     243          """Method invoked upon entry to the Factory method.
     244
     245          This method is entitled to modify the keywords array.  It can also
     246          return a state value which is passed to _postFactory_vx."""
     247          return None
     248
     249 -    def _postFactory_vx (cls, state):
     250          """Method invoked prior to leaving the Factory method.
     251
     252          This is an instance method, and is given the state that was returned
     253          by _PreFactory_vx."""
     254          return None
     255
     256      @classmethod
     257 -    def Factory (cls, *args, **kw):
     258          """Provide a common mechanism to create new instances of this type.
     259
     260          The class constructor won't do, because you can't create
     261          instances of union types.
     262
     263          This method may be overridden in subclasses (like STD_union).  Pre-
     264          and post-creation actions can be customized on a per-class instance by
     265          overriding the L{_PreFactory_vx} and L{_postFactory_vx} methods.
     266
     267          @keyword _dom_node: If provided, the value must be a DOM node, the
     268          content of which will be used to set the value of the instance.
     269
     270          @keyword _location: An optional instance of
     271          L{pyxb.utils.utility.Location} showing the origin the binding.  If
     272          C{None}, a value from C{_dom_node} is used if available.
     273
     274          @keyword _from_xml: If C{True}, the input must be either a DOM node or
     275          a unicode string comprising a lexical representation of a value.  This
     276          is a further control on C{_apply_whitespace_facet} and arises from
     277          cases where the lexical and value representations cannot be
     278          distinguished by type.  The default value is C{True} iff C{_dom_node}
     279          is not C{None}.
     280
     281          @keyword _apply_whitespace_facet: If C{True} and this is a
     282          simpleTypeDefinition with a whiteSpace facet, the first argument will
     283          be normalized in accordance with that facet prior to invoking the
     284          parent constructor.  The value is always C{True} if text content is
     285          extracted from a C{_dom_node}, and otherwise defaults to the defaulted
     286          value of C{_from_xml}.
     287
     288          @keyword _validate_constraints: If C{True}, any constructed value is
     289          checked against constraints applied to the union as well as the member
     290          type.
     291
     292          @keyword _require_value: If C{False} (default), it is permitted to
     293          create a value without an initial value.  If C{True} and no initial
     294          value was provided, causes L{pyxb.SimpleContentAbsentError} to be raised.
     295          Only applies to simpleTypeDefinition instances; this is used when
     296          creating values from DOM nodes.
     297          """
     298          # Invoke _PreFactory_vx for the superseding class, which is where
     299          # customizations will be found.
     300          dom_node = kw.get('_dom_node')
     301          location = kw.get('_location')
     302          if (location is None) and isinstance(dom_node, utility.Locatable_mixin):
     303              location = dom_node._location()
     304          kw.setdefault('_from_xml', dom_node is not None)
     305          used_cls = cls._SupersedingClass()
     306          state = used_cls._PreFactory_vx(args, kw)
     307          rv = cls._DynamicCreate(*args, **kw)
     308          rv._postFactory_vx(state)
     309          if (rv._location is None) and (location is not None):
     310              rv._setLocation(location)
     311          return rv
     312
     313 -    def _substitutesFor (self, element):
     314          if (element is None) or (self._element() is None):
     315              return False
     316          return self._element().substitutesFor(element)
     317
     318      @classmethod
     319 -    def _IsUrType (cls):
     320          """Return C{True} iff this is the ur-type.
     321
     322          The only ur-type is {http://www.w3.org/2001/XMLSchema}anyType.  The
     323          implementation of this method is overridden for
     324          L{pyxb.binding.datatypes.anyType}."""
     325          return False
     326
     327      @classmethod
     328 -    def _RequireXSIType (cls, value_type):
     329          if cls._IsUrType():
     330              # Require xsi:type if value refines xs:anyType
     331              return value_type != cls
     332          return cls._Abstract and value_type != cls._SupersedingClass()
     333
     334      @classmethod
     335 -    def _CompatibleValue (cls, value, **kw):
     336          """Return a variant of the value that is compatible with this type.
     337
     338          Compatibility is defined relative to the type definition associated
     339          with the element.  The value C{None} is always compatible.  If
     340          C{value} has a Python type (e.g., C{int}) that is a superclass of the
     341          required L{_TypeBinding_mixin} class (e.g., C{xs:byte}), C{value} is
     342          used as a constructor parameter to return a new instance of the
     343          required type.  Note that constraining facets are applied here if
     344          necessary (e.g., although a Python C{int} with value C{500} is
     345          type-compatible with C{xs:byte}, it is outside the value space, and
     346          compatibility will fail).
     347
     348          @keyword _convert_string_values: If C{True} (default) and the incoming value is
     349          a string, an attempt will be made to form a compatible value by using
     350          the string as a constructor argument to the this class.  This flag is
     351          set to C{False} when testing automaton transitions.
     352
     353          @raise pyxb.SimpleTypeValueError: if the value is not both
     354          type-consistent and value-consistent with the element's type.
     355          """
     356          convert_string_values = kw.get('_convert_string_values', True)
     357          # None is always None
     358          if value is None:
     359              return None
     360          # Already an instance?
     361          if isinstance(value, cls):
     362              # @todo: Consider whether we should change the associated _element
     363              # of this value.  (**Consider** it, don't just do it.)
     364              return value
     365          value_type = type(value)
     366          # All string-based PyXB binding types use unicode, not str
     367          if str == value_type:
     368              value_type = unicode
     369
     370          # See if we got passed a Python value which needs to be "downcasted"
     371          # to the _TypeBinding_mixin version.
     372          if issubclass(cls, value_type):
     373              return cls(value)
     374
     375          # See if we have a numeric type that needs to be cast across the
     376          # numeric hierarchy.  int to long is the *only* conversion we accept.
     377          if isinstance(value, int) and issubclass(cls, long):
     378              return cls(value)
     379
     380          # Same, but for boolean, which Python won't let us subclass
     381          if isinstance(value, bool) and issubclass(cls, pyxb.binding.datatypes.boolean):
     382              return cls(value)
     383
     384          # See if we have convert_string_values on, and have a string type that
     385          # somebody understands.
     386          if convert_string_values and (unicode == value_type):
     387              return cls(value)
     388
     389          # Maybe this is a union?
     390          if issubclass(cls, STD_union):
     391              for mt in cls._MemberTypes:
     392                  try:
     393                      return mt._CompatibleValue(value, **kw)
     394                  except:
     395                      pass
     396
     397          # Any type is compatible with the corresponding ur-type
     398          if (pyxb.binding.datatypes.anySimpleType == cls) and issubclass(value_type, simpleTypeDefinition):
     399              return value
     400          if pyxb.binding.datatypes.anyType == cls:
     401              if not isinstance(value, _TypeBinding_mixin):
     402                  _log.info('Created %s instance from value of type %s', cls._ExpandedName, type(value))
     403                  value = cls(value)
     404              return value
     405
     406          # Is this the wrapper class that indicates we should create a binding
     407          # from arguments?
     408          if isinstance(value, pyxb.BIND):
     409              return value.createInstance(cls.Factory, **kw)
     410
     411          # Does the class have simple content which we can convert?
     412          if cls._IsSimpleTypeContent():
     413              # NB: byte(34.2) will create a value, but it may not be one we
     414              # want to accept, so only do this if the output is equal to the
     415              # input.
     416              rv = cls.Factory(value)
     417              if isinstance(rv, simpleTypeDefinition) and (rv == value):
     418                  return rv
     419              if isinstance(rv, complexTypeDefinition) and (rv.value() == value):
     420                  return rv
     421
     422          # There may be other things that can be converted to the desired type,
     423          # but we can't tell that from the type hierarchy.  Too many of those
     424          # things result in an undesirable loss of information: for example,
     425          # when an all model supports both numeric and string transitions, the
     426          # candidate is a number, and the string transition is tested first.
     427          raise pyxb.SimpleTypeValueError(cls, value)
     428
     429      @classmethod
     430 -    def _IsSimpleTypeContent (cls):
     431          """Return True iff the content of this binding object is a simple type.
     432
     433          This is true only for descendents of simpleTypeDefinition and instances
     434          of complexTypeDefinition that have simple type content."""
     435          raise pyxb.LogicError('Failed to override _TypeBinding_mixin._IsSimpleTypeContent')
     436
     437      # If the type supports wildcard attributes, this describes their
     438      # constraints.  (If it doesn't, this should remain None.)  Supporting
     439      # classes should override this value.
     440      _AttributeWildcard = None
     441
     442      _AttributeMap = { }
     443      """Map from expanded names to AttributeUse instances.  Non-empty only in
     444      L{complexTypeDefinition} subclasses."""
     445
     446      @classmethod
     447 -    def __AttributesFromDOM (cls, node):
     448          attribute_settings = { }
     449          for ai in range(0, node.attributes.length):
     450              attr = node.attributes.item(ai)
     451              # NB: Specifically do not consider attr's NamespaceContext, since
     452              # attributes do not accept a default namespace.
     453              attr_en = pyxb.namespace.ExpandedName(attr)
     454
     455              # Ignore xmlns and xsi attributes; we've already handled those
     456              if attr_en.namespace() in ( pyxb.namespace.XMLNamespaces, XSI ):
     457                  continue
     458
     459              attribute_settings[attr_en] = attr.value
     460          return attribute_settings
     461
     462 -    def _setAttributesFromKeywordsAndDOM (self, kw, dom_node):
     463          """Invoke self._setAttribute based on node attributes and keywords.
     464
     465          Though attributes can only legally appear in complexTypeDefinition
     466          instances, delayed conditional validation requires caching them in
     467          simpleTypeDefinition.
     468
     469          @param kw: keywords passed to the constructor.  This map is mutated by
     470          the call: keywords corresponding to recognized attributes are removed.
     471
     472          @param dom_node: an xml.dom Node instance, possibly C{None}
     473          """
     474
     475          # Extract keywords that match field names
     476          attribute_settings = { }
     477          if dom_node is not None:
     478              attribute_settings.update(self.__AttributesFromDOM(dom_node))
     479          for fu in self._AttributeMap.itervalues():
     480              iv = kw.pop(fu.id(), None)
     481              if iv is not None:
     482                  attribute_settings[fu.name()] = iv
     483          for (attr_en, value_lex) in attribute_settings.iteritems():
     484              self._setAttribute(attr_en, value_lex)
     485
     486 -    def toDOM (self, bds=None, parent=None, element_name=None):
     487          """Convert this instance to a DOM node.
     488
     489          The name of the top-level element is either the name of the L{element}
     490          instance associated with this instance, or the XML name of the type of
     491          this instance.
     492
     493          @param bds: Support for customizing the generated document
     494          @type bds: L{pyxb.utils.domutils.BindingDOMSupport}
     495          @param parent: If C{None}, a standalone document is created;
     496          otherwise, the created element is a child of the given element.
     497          @type parent: C{xml.dom.Element} or C{None}
     498          @rtype: C{xml.dom.Document}
     499          """
     500
     501          if bds is None:
     502              bds = domutils.BindingDOMSupport()
     503          need_xsi_type = bds.requireXSIType()
     504          if isinstance(element_name, (str, unicode)):
     505              element_name = pyxb.namespace.ExpandedName(bds.defaultNamespace(), element_name)
     506          if (element_name is None) and (self._element() is not None):
     507              element_binding = self._element()
     508              element_name = element_binding.name()
     509              need_xsi_type = need_xsi_type or element_binding.typeDefinition()._RequireXSIType(type(self))
     510          if element_name is None:
     511              raise pyxb.UnboundElementError(self)
     512          element = bds.createChildElement(element_name, parent)
     513          if need_xsi_type:
     514              val_type_qname = self._ExpandedName.localName()
     515              tns_prefix = bds.namespacePrefix(self._ExpandedName.namespace())
     516              if tns_prefix is not None:
     517                  val_type_qname = '%s:%s' % (tns_prefix, val_type_qname)
     518              bds.addAttribute(element, XSI.type, val_type_qname)
     519          self._toDOM_csc(bds, element)
     520          bds.finalize()
     521          return bds.document()
     522
     523 -    def toxml (self, encoding=None, bds=None, root_only=False):
     524          """Shorthand to get the object as an XML document.
     525
     526          If you want to set the default namespace, pass in a pre-configured
     527          C{bds}.
     528
     529          @param encoding: The encoding to be used.  See
     530          @C{xml.dom.Node.toxml()} for a description of why you should always
     531          pass @C{'utf-8'} here.  Because this method follows the contract of
     532          the corresponding C{xml.dom.Node} method, it does not automatically
     533          get the default PyXB output encoding.
     534
     535          @param bds: Optional L{pyxb.utils.domutils.BindingDOMSupport} instance
     536          to use for creation. If not provided (default), a new generic one is
     537          created.
     538          """
     539          dom = self.toDOM(bds)
     540          if root_only:
     541              dom = dom.documentElement
     542          return dom.toxml(encoding)
     543
     544 -    def _toDOM_csc (self, dom_support, parent):
     545          assert parent is not None
     546          if self.__xsiNil:
     547              dom_support.addAttribute(parent, XSI.nil, 'true')
     548          return getattr(super(_TypeBinding_mixin, self), '_toDOM_csc', lambda *_args,**_kw: dom_support)(dom_support, parent)
     549
     550 -    def _validateBinding_vx (self):
     551          """Override in subclasses for type-specific validation of instance
     552          content.
     553
     554          @return: C{True} if the instance validates
     555          @raise pyxb.BatchContentValidationError: complex content does not match model
     556          @raise pyxb.SimpleTypeValueError: simple content fails to satisfy constraints
     557          """
     558          raise NotImplementedError('%s._validateBinding_vx' % (type(self).__name__,))
     559
     560 -    def validateBinding (self):
     561          """Check whether the binding content matches its content model.
     562
     563          @return: C{True} if validation succeeds.
     564          @raise pyxb.BatchContentValidationError: complex content does not match model
     565          @raise pyxb.SimpleTypeValueError: attribute or simple content fails to satisfy constraints
     566          """
     567          if self._performValidation():
     568              self._validateBinding_vx()
     569          return True
     570
     571 -    def _finalizeContentModel (self):
     572          """Inform content model that all additions have been provided.
     573
     574          This is used to resolve any pending non-determinism when the content
     575          of an element is provided through a DOM assignment or through
     576          positional arguments in a constructor."""
     577          return self
     578
     579 -    def _postDOMValidate (self):
     580          self.validateBinding()
     581          return self
     582
     583      @classmethod
     584 -    def _Name (cls):
     585          """Return the best descriptive name for the type of the instance.
     586
     587          This is intended to be a human-readable value used in diagnostics, and
     588          is the expanded name if the type has one, or the Python type name if
     589          it does not."""
     590          if cls._ExpandedName is not None:
     591              return unicode(cls._ExpandedName)
     592          return unicode(cls)
     593
     594 -    def _diagnosticName (self):
     595          """The best name available for this instance in diagnostics.
     596
     597          If the instance is associated with an element, it is the element name;
     598          otherwise it is the best name for the type of the instance per L{_Name}."""
     599          if self.__element is None:
     600              return self._Name()
     601          return unicode(self.__element.name())
     602
     603 -class _DynamicCreate_mixin (pyxb.cscRoot):
     604      """Helper to allow overriding the implementation class.
     605
     606      Generally we'll want to augment the generated bindings by subclassing
     607      them, and adding functionality to the subclass.  This mix-in provides a
     608      way to communicate the existence of the superseding subclass back to the
     609      binding infrastructure, so that when it creates an instance it uses the
     610      subclass rather than the unaugmented binding class.
     611
     612      When a raw generated binding is subclassed, L{_SetSupersedingClass} should be
     613      invoked on the raw class passing in the superseding subclass.  E.g.::
     614
     615        class mywsdl (raw.wsdl):
     616          pass
     617        raw.wsdl._SetSupersedingClass(mywsdl)
     618
     619      """
     620
     621      @classmethod
     622 -    def __SupersedingClassAttribute (cls):
     623          return '_%s__SupersedingClass' % (cls.__name__,)
     624
     625      @classmethod
     626 -    def __AlternativeConstructorAttribute (cls):
     627          return '_%s__AlternativeConstructor' % (cls.__name__,)
     628
     629      @classmethod
     630 -    def _SupersedingClass (cls):
     631          """Return the class stored in the class reference attribute."""
     632          return getattr(cls, cls.__SupersedingClassAttribute(), cls)
     633
     634      @classmethod
     635 -    def _AlternativeConstructor (cls):
     636          """Return the class stored in the class reference attribute."""
     637          rv = getattr(cls, cls.__AlternativeConstructorAttribute(), None)
     638          if isinstance(rv, tuple):
     639              rv = rv[0]
     640          return rv
     641
     642      @classmethod
     643 -    def _SetSupersedingClass (cls, superseding):
     644          """Set the class reference attribute.
     645
     646          @param superseding: A Python class that is a subclass of this class.
     647          """
     648          assert (superseding is None) or issubclass(superseding, cls)
     649          if superseding is None:
     650              cls.__dict__.pop(cls.__SupersedingClassAttribute(), None)
     651          else:
     652              setattr(cls, cls.__SupersedingClassAttribute(), superseding)
     653          return superseding
     654
     655      @classmethod
     656 -    def _SetAlternativeConstructor (cls, alternative_constructor):
     657          attr = cls.__AlternativeConstructorAttribute()
     658          if alternative_constructor is None:
     659              cls.__dict__.pop(attr, None)
     660          else:
     661              # Need to use a tuple as the value: if you use an invokable, this
     662              # ends up converting it from a function to an unbound method,
     663              # which is not what we want.
     664              setattr(cls, attr, (alternative_constructor,))
     665          assert cls._AlternativeConstructor() == alternative_constructor
     666          return alternative_constructor
     667
     668      @classmethod
     669 -    def _DynamicCreate (cls, *args, **kw):
     670          """Invoke the constructor for this class or the one that supersedes it."""
     671          ctor = cls._AlternativeConstructor()
     672          if ctor is None:
     673              ctor = cls._SupersedingClass()
     674          try:
     675              return ctor(*args, **kw)
     676          except TypeError:
     677              raise pyxb.SimpleTypeValueError(ctor, args)
     678
     679 -class simpleTypeDefinition (_TypeBinding_mixin, utility._DeconflictSymbols_mixin, _DynamicCreate_mixin):
     680      """L{simpleTypeDefinition} is a base class that is part of the
     681      hierarchy of any class that represents the Python datatype for a
     682      L{SimpleTypeDefinition<pyxb.xmlschema.structures.SimpleTypeDefinition>}.
     683
     684      @note: This class, or a descendent of it, must be the first class
     685      in the method resolution order when a subclass has multiple
     686      parents.  Otherwise, constructor keyword arguments may not be
     687      removed before passing them on to Python classes that do not
     688      accept them.
     689      """
     690
     691      # A map from leaf classes in the facets module to instance of
     692      # those classes that constrain or otherwise affect the datatype.
     693      # Note that each descendent of simpleTypeDefinition has its own map.
     694      __FacetMap = {}
     695
     696      _ReservedSymbols = _TypeBinding_mixin._ReservedSymbols.union(set([ 'XsdLiteral', 'xsdLiteral',
     697                              'XsdSuperType', 'XsdPythonType', 'XsdConstraintsOK',
     698                              'xsdConstraintsOK', 'XsdValueLength', 'xsdValueLength',
     699                              'PythonLiteral', 'pythonLiteral',
     700                              'SimpleTypeDefinition' ]))
     701      """Symbols that remain the responsibility of this class.  Any
     702      public symbols in generated binding subclasses are deconflicted
     703      by providing an alternative name in the subclass.  (There
     704      currently are no public symbols in generated SimpleTypeDefinion
     705      bindings."""
     706
     707
     708      # Determine the name of the class-private facet map.  For the base class
     709      # this should produce the same attribute name as Python's privatization
     710      # scheme.
     711      __FacetMapAttributeNameMap = { }
     712      @classmethod
     713 -    def __FacetMapAttributeName (cls):
     714          """ """
     715          '''
     716          if cls == simpleTypeDefinition:
     717              return '_%s__FacetMap' % (cls.__name__.strip('_'),)
     718
     719          # It is not uncommon for a class in one namespace to extend a class of
     720          # the same name in a different namespace, so encode the namespace URI
     721          # in the attribute name (if it is part of a namespace).
     722          ns_uri = ''
     723          try:
     724              ns_uri = cls._ExpandedName.namespaceURI()
     725          except Exception:
     726              pass
     727          nm = '_' + utility.MakeIdentifier('%s_%s_FacetMap' % (ns_uri, cls.__name__.strip('_')))
     728          '''
     729          nm = cls.__FacetMapAttributeNameMap.get(cls)
     730          if nm is None:
     731              nm = cls.__name__
     732              if nm.endswith('_'):
     733                  nm += '1'
     734              if cls == simpleTypeDefinition:
     735                  nm = '_%s__FacetMap' % (nm,)
     736              else:
     737                  # It is not uncommon for a class in one namespace to extend a class of
     738                  # the same name in a different namespace, so encode the namespace URI
     739                  # in the attribute name (if it is part of a namespace).
     740                  ns_uri = ''
     741                  try:
     742                      ns_uri = cls._ExpandedName.namespaceURI()
     743                  except Exception:
     744                      pass
     745                  nm = '_' + utility.MakeIdentifier('%s_%s_FacetMap' % (ns_uri, nm))
     746              cls.__FacetMapAttributeNameMap[cls] = nm
     747          return nm
     748
     749      @classmethod
     750 -    def _FacetMap (cls):
     751          """Return a reference to the facet map for this datatype.
     752
     753          The facet map is a map from leaf facet classes to instances of those
     754          classes that constrain or otherwise apply to the lexical or value
     755          space of the datatype.  Classes may inherit their facet map from their
     756          superclass, or may create a new class instance if the class adds a new
     757          constraint type.
     758
     759          @raise AttributeError: if the facet map has not been defined"""
     760          return getattr(cls, cls.__FacetMapAttributeName())
     761
     762      @classmethod
     763 -    def _InitializeFacetMap (cls, *args):
     764          """Initialize the facet map for this datatype.
     765
     766          This must be called exactly once, after all facets belonging to the
     767          datatype have been created.
     768
     769          @raise pyxb.LogicError: if called multiple times (on the same class)
     770          @raise pyxb.LogicError: if called when a parent class facet map has not been initialized
     771          :return: the facet map"""
     772          fm = None
     773          try:
     774              fm = cls._FacetMap()
     775          except AttributeError:
     776              pass
     777          if fm is not None:
     778              raise pyxb.LogicError('%s facet map initialized multiple times: %s' % (cls.__name__, cls.__FacetMapAttributeName()))
     779
     780          # Search up the type hierarchy to find the nearest ancestor that has a
     781          # facet map.  This gets a bit tricky: if we hit the ceiling early
     782          # because the PSTD hierarchy re-based itself on a new Python type, we
     783          # have to jump to the XsdSuperType.
     784          source_class = cls
     785          while fm is None:
     786              # Assume we're staying in this hierarchy.  Include source_class in
     787              # the candidates, since we might have jumped to it.
     788              for super_class in source_class.mro():
     789                  assert super_class is not None
     790                  if (super_class == simpleTypeDefinition): # and (source_class.XsdSuperType() is not None):
     791                      break
     792                  if issubclass(super_class, simpleTypeDefinition):
     793                      try:
     794                          fm = super_class._FacetMap()
     795                          break
     796                      except AttributeError:
     797                          pass
     798              if fm is None:
     799                  try:
     800                      source_class = source_class.XsdSuperType()
     801                  except AttributeError:
     802                      source_class = None
     803                  if source_class is None:
     804                      fm = { }
     805          if fm is None:
     806              raise pyxb.LogicError('%s is not a child of simpleTypeDefinition' % (cls.__name__,))
     807          fm = fm.copy()
     808          for facet in args:
     809              fm[type(facet)] = facet
     810          setattr(cls, cls.__FacetMapAttributeName(), fm)
     811          return fm
     812
     813      @classmethod
     814 -    def _ConvertArguments_vx (cls, args, kw):
     815          return args
     816
     817      @classmethod
     818 -    def _ConvertArguments (cls, args, kw):
     819          """Pre-process the arguments.
     820
     821          This is used before invoking the parent constructor.  One application
     822          is to apply the whitespace facet processing; if such a request is in
     823          the keywords, it is removed so it does not propagate to the
     824          superclass.  Another application is to convert the arguments from a
     825          string to a list.  Binding-specific applications are performed in the
     826          overloaded L{_ConvertArguments_vx} method."""
     827          dom_node = kw.pop('_dom_node', None)
     828          from_xml = kw.get('_from_xml', dom_node is not None)
     829          if dom_node is not None:
     830              text_content = domutils.ExtractTextContent(dom_node)
     831              if text_content is not None:
     832                  args = (domutils.ExtractTextContent(dom_node),) + args
     833                  kw['_apply_whitespace_facet'] = True
     834          apply_whitespace_facet = kw.pop('_apply_whitespace_facet', from_xml)
     835          if (0 < len(args)) and isinstance(args[0], types.StringTypes) and apply_whitespace_facet:
     836              cf_whitespace = getattr(cls, '_CF_whiteSpace', None)
     837              if cf_whitespace is not None:
     838                  norm_str = unicode(cf_whitespace.normalizeString(args[0]))
     839                  args = (norm_str,) + args[1:]
     840          kw['_from_xml'] = from_xml
     841          return cls._ConvertArguments_vx(args, kw)
     842
     843      # Must override new, because new gets invoked before init, and usually
     844      # doesn't accept keywords.  In case it does (e.g., datetime.datetime),
     845      # only remove the ones that would normally be interpreted by this class.
     846      # Do the same argument conversion as is done in init.  Trap errors and
     847      # convert them to BadTypeValue errors.
     848      #
     849      # Note: We explicitly do not validate constraints here.  That's
     850      # done in the normal constructor; here, we might be in the process
     851      # of building a value that eventually will be legal, but isn't
     852      # yet.
     853 -    def __new__ (cls, *args, **kw):
     854          # PyXBFactoryKeywords
     855          kw.pop('_validate_constraints', None)
     856          kw.pop('_require_value', None)
     857          kw.pop('_element', None)
     858          kw.pop('_fallback_namespace', None)
     859          kw.pop('_apply_attributes', None)
     860          kw.pop('_nil', None)
     861          # ConvertArguments will remove _element and _apply_whitespace_facet
     862          dom_node = kw.get('_dom_node')
     863          args = cls._ConvertArguments(args, kw)
     864          kw.pop('_from_xml', dom_node is not None)
     865          kw.pop('_location', None)
     866          assert issubclass(cls, _TypeBinding_mixin)
     867          try:
     868              return super(simpleTypeDefinition, cls).__new__(cls, *args, **kw)
     869          except ValueError:
     870              raise pyxb.SimpleTypeValueError(cls, args)
     871          except OverflowError:
     872              raise pyxb.SimpleTypeValueError(cls, args)
     873
     874      # Validate the constraints after invoking the parent constructor,
     875      # unless told not to.
     876 -    def __init__ (self, *args, **kw):
     877          """Initialize a newly created STD instance.
     878
     879          Usually there is one positional argument, which is a value that can be
     880          converted to the underlying Python type.
     881
     882          @keyword _validate_constraints: If True (default if validation is
     883          enabled), the newly constructed value is checked against its
     884          constraining facets.
     885          @type _validate_constraints: C{bool}
     886
     887          @keyword _apply_attributes: If C{True} (default), any attributes
     888          present in the keywords or DOM node are applied.  Normally presence of
     889          such an attribute should produce an error; when creating simple
     890          content for a complex type we need the DOM node, but do not want to
     891          apply the attributes, so we bypass the application.
     892          """
     893          # PyXBFactoryKeywords
     894          validate_constraints = kw.pop('_validate_constraints', self._validationConfig.forBinding)
     895          require_value = kw.pop('_require_value', False)
     896          # Save DOM node so we can pull attributes off it
     897          dom_node = kw.get('_dom_node')
     898          location = kw.get('_location')
     899          if (location is None) and isinstance(dom_node, utility.Locatable_mixin):
     900              location = dom_node._location()
     901          apply_attributes = kw.pop('_apply_attributes', True)
     902          # _ConvertArguments handles _dom_node and _apply_whitespace_facet
     903          # TypeBinding_mixin handles _nil and _element
     904          args = self._ConvertArguments(args, kw)
     905          try:
     906              super(simpleTypeDefinition, self).__init__(*args, **kw)
     907          except OverflowError:
     908              raise pyxb.SimpleTypeValueError(type(self), args)
     909          if apply_attributes and (dom_node is not None):
     910              self._setAttributesFromKeywordsAndDOM(kw, dom_node)
     911          if require_value and (not self._constructedWithValue()):
     912              if location is None:
     913                  location = self._location()
     914              raise pyxb.SimpleContentAbsentError(self, location)
     915          if validate_constraints and not kw.pop('_nil', False):
     916              self.xsdConstraintsOK(location)
     917
     918      # The class attribute name used to store the reference to the STD
     919      # component instance must be unique to the class, not to this base class.
     920      # Otherwise we mistakenly believe we've already associated a STD instance
     921      # with a class (e.g., xsd:normalizedString) when in fact it's associated
     922      # with the superclass (e.g., xsd:string)
     923      @classmethod
     924 -    def __STDAttrName (cls):
     925          return '_%s__SimpleTypeDefinition' % (cls.__name__,)
     926
     927      @classmethod
     928 -    def _SimpleTypeDefinition (cls, std):
     929          """Set the L{pyxb.xmlschema.structures.SimpleTypeDefinition} instance
     930          associated with this binding."""
     931          attr_name = cls.__STDAttrName()
     932          if hasattr(cls, attr_name):
     933              old_value = getattr(cls, attr_name)
     934              if old_value != std:
     935                  raise pyxb.LogicError('%s: Attempt to override existing STD %s with %s' % (cls, old_value.name(), std.name()))
     936          setattr(cls, attr_name, std)
     937
     938      @classmethod
     939 -    def SimpleTypeDefinition (cls):
     940          """Return the SimpleTypeDefinition instance for the given
     941          class.
     942
     943          This should only be invoked when generating bindings.  An STD must
     944          have been associated with the class using L{_SimpleTypeDefinition}."""
     945          attr_name = cls.__STDAttrName()
     946          assert hasattr(cls, attr_name)
     947          return getattr(cls, attr_name)
     948
     949      @classmethod
     950 -    def XsdLiteral (cls, value):
     951          """Convert from a python value to a string usable in an XML
     952          document.
     953
     954          This should be implemented in the subclass."""
     955          raise pyxb.LogicError('%s does not implement XsdLiteral' % (cls,))
     956
     957 -    def xsdLiteral (self):
     958          """Return text suitable for representing the value of this
     959          instance in an XML document.
     960
     961          The base class implementation delegates to the object class's
     962          XsdLiteral method."""
     963          if self._isNil():
     964              return ''
     965          return self.XsdLiteral(self)
     966
     967      @classmethod
     968 -    def XsdSuperType (cls):
     969          """Find the nearest parent class in the PST hierarchy.
     970
     971          The value for anySimpleType is None; for all others, it's a
     972          primitive or derived PST descendent (including anySimpleType)."""
     973          for sc in cls.mro():
     974              if sc == cls:
     975                  continue
     976              if simpleTypeDefinition == sc:
     977                  # If we hit the PST base, this is a primitive type or
     978                  # otherwise directly descends from a Python type; return
     979                  # the recorded XSD supertype.
     980                  return cls._XsdBaseType
     981              if issubclass(sc, simpleTypeDefinition):
     982                  return sc
     983          raise pyxb.LogicError('No supertype found for %s' % (cls,))
     984
     985      @classmethod
     986 -    def _XsdConstraintsPreCheck_vb (cls, value):
     987          """Pre-extended class method to verify other things before
     988          checking constraints.
     989
     990          This is used for list types, to verify that the values in the
     991          list are acceptable, and for token descendents, to check the
     992          lexical/value space conformance of the input.
     993          """
     994          super_fn = getattr(super(simpleTypeDefinition, cls), '_XsdConstraintsPreCheck_vb', lambda *a,**kw: value)
     995          return super_fn(value)
     996
     997      # Cache of pre-computed sequences of class facets in the order required
     998      # for constraint validation
     999      __ClassFacetSequence = { }
    1000
    1001      @classmethod
    1002 -    def XsdConstraintsOK (cls, value, location=None):
    1003          """Validate the given value against the constraints on this class.
    1004
    1005          @raise pyxb.SimpleTypeValueError: if any constraint is violated.
    1006          """
    1007
    1008          value = cls._XsdConstraintsPreCheck_vb(value)
    1009
    1010          facet_values = cls.__ClassFacetSequence.get(cls)
    1011          if facet_values is None:
    1012              # Constraints for simple type definitions are inherited.  Check them
    1013              # from least derived to most derived.
    1014              classes = [ _x for _x in cls.mro() if issubclass(_x, simpleTypeDefinition) ]
    1015              classes.reverse()
    1016              cache_result = True
    1017              facet_values = []
    1018              for clazz in classes:
    1019                  # When setting up the datatypes, if we attempt to validate
    1020                  # something before the facets have been initialized (e.g., a
    1021                  # nonNegativeInteger used as a length facet for the parent
    1022                  # integer datatype), just ignore that for now.  Don't cache
    1023                  # the value, though, since a subsequent check after
    1024                  # initialization should succceed.
    1025                  try:
    1026                      clazz_facets = clazz._FacetMap().values()
    1027                  except AttributeError:
    1028                      cache_result = False
    1029                      clazz_facets = []
    1030                  for v in clazz_facets:
    1031                      if not (v in facet_values):
    1032                          facet_values.append(v)
    1033              if cache_result:
    1034                  cls.__ClassFacetSequence[cls] = facet_values
    1035          for f in facet_values:
    1036              if not f.validateConstraint(value):
    1037                  raise pyxb.SimpleFacetValueError(cls, value, f, location)
    1038          return value
    1039
    1040 -    def xsdConstraintsOK (self, location=None):
    1041          """Validate the value of this instance against its constraints."""
    1042          return self.XsdConstraintsOK(self, location)
    1043
    1044 -    def _validateBinding_vx (self):
    1045          if not self._isNil():
    1046              self._checkValidValue()
    1047          return True
    1048
    1049      @classmethod
    1050 -    def XsdValueLength (cls, value):
    1051          """Return the length of the given value.
    1052
    1053          The length is calculated by a subclass implementation of
    1054          _XsdValueLength_vx in accordance with
    1055          http://www.w3.org/TR/xmlschema-2/#rf-length.
    1056
    1057          The return value is a non-negative integer, or C{None} if length
    1058          constraints should be considered trivially satisfied (as with
    1059          QName and NOTATION).
    1060
    1061          @raise pyxb.LogicError: the provided value is not an instance of cls.
    1062          @raise pyxb.LogicError: an attempt is made to calculate a length for
    1063          an instance of a type that does not support length calculations.
    1064          """
    1065          assert isinstance(value, cls)
    1066          if not hasattr(cls, '_XsdValueLength_vx'):
    1067              raise pyxb.LogicError('Class %s does not support length validation' % (cls.__name__,))
    1068          return cls._XsdValueLength_vx(value)
    1069
    1070 -    def xsdValueLength (self):
    1071          """Return the length of this instance within its value space.
    1072
    1073          See XsdValueLength."""
    1074          return self.XsdValueLength(self)
    1075
    1076      @classmethod
    1077 -    def PythonLiteral (cls, value):
    1078          """Return a string which can be embedded into Python source to
    1079          represent the given value as an instance of this class."""
    1080          class_name = cls.__name__
    1081          return '%s(%s)' % (class_name, repr(value))
    1082
    1083 -    def pythonLiteral (self):
    1084          """Return a string which can be embedded into Python source to
    1085          represent the value of this instance."""
    1086          return self.PythonLiteral(self)
    1087
    1088 -    def _toDOM_csc (self, dom_support, parent):
    1089          assert parent is not None
    1090          dom_support.appendTextChild(self.xsdLiteral(), parent)
    1091          return getattr(super(simpleTypeDefinition, self), '_toDOM_csc', lambda *_args,**_kw: dom_support)(dom_support, parent)
    1092
    1093      @classmethod
    1094 -    def _IsSimpleTypeContent (cls):
    1095          """STDs have simple type content."""
    1096          return True
    1097
    1098      @classmethod
    1099 -    def _IsValidValue (self, value):
    1100          try:
    1101              self._CheckValidValue(value)
    1102              return True
    1103          except pyxb.PyXBException:
    1104              pass
    1105          return False
    1106
    1107      @classmethod
    1108 -    def _CheckValidValue (cls, value):
    1109
    1110          """NB: Invoking this on a value that is a list will, if necessary,
    1111          replace the members of the list with new values that are of the
    1112          correct item type.  This is permitted because only with lists is it
    1113          possible to bypass the normal content validation (by invoking
    1114          append/extend on the list instance)."""
    1115          if value is None:
    1116              raise pyxb.SimpleTypeValueError(cls, value)
    1117          value_class = cls
    1118          if issubclass(cls, STD_list):
    1119              if not isinstance(value, collections.Iterable):
    1120                  raise pyxb.SimpleTypeValueError(cls, value)
    1121              for v in value:
    1122                  if not cls._ItemType._IsValidValue(v):
    1123                      raise pyxb.SimpleListValueError(cls, v)
    1124          else:
    1125              if issubclass(cls, STD_union):
    1126                  value_class = None
    1127                  for mt in cls._MemberTypes:
    1128                      if mt._IsValidValue(value):
    1129                          value_class = mt
    1130                          break
    1131                  if value_class is None:
    1132                      raise pyxb.SimpleUnionValueError(cls, value)
    1133              #if not (isinstance(value, value_class) or issubclass(value_class, type(value))):
    1134              if not isinstance(value, value_class):
    1135                  raise pyxb.SimpleTypeValueError(cls, value)
    1136          value_class.XsdConstraintsOK(value)
    1137
    1138 -    def _checkValidValue (self):
    1139          self._CheckValidValue(self)
    1140
    1141 -    def _isValidValue (self):
    1142          self._IsValidValue(self)
    1143
    1144 -    def _setAttribute (self, attr_en, value_lex):
    1145          # Simple types have no attributes, but the parsing infrastructure
    1146          # might invoke this to delegate responsibility for notifying the user
    1147          # of the failure.
    1148          raise pyxb.AttributeOnSimpleTypeError(self, attr_en, value_lex)
    1149
    1150      @classmethod
    1151 -    def _description (cls, name_only=False, user_documentation=True):
    1152          name = cls._Name()
    1153          if name_only:
    1154              return name
    1155          desc = [ name, ' restriction of ', cls.XsdSuperType()._description(name_only=True) ]
    1156          if user_documentation and (cls._Documentation is not None):
    1157              desc.extend(["\n", cls._Documentation])
    1158          return ''.join(desc)
    1159
    1160 -class STD_union (simpleTypeDefinition):
    1161      """Base class for union datatypes.
    1162
    1163      This class descends only from simpleTypeDefinition.  A pyxb.LogicError is
    1164      raised if an attempt is made to construct an instance of a subclass of
    1165      STD_union.  Values consistent with the member types are constructed using
    1166      the Factory class method.  Values are validated using the _ValidatedMember
    1167      class method.
    1168
    1169      Subclasses must provide a class variable _MemberTypes which is a
    1170      tuple of legal members of the union."""
    1171
    1172      _MemberTypes = None
    1173      """A list of classes which are permitted as values of the union."""
    1174
    1175      # Ick: If we don't declare this here, this class's map doesn't get
    1176      # initialized.  Alternative is to not descend from simpleTypeDefinition.
    1177      # @todo Ensure that pattern and enumeration are valid constraints
    1178      __FacetMap = {}
    1179
    1180      @classmethod
    1181 -    def Factory (cls, *args, **kw):
    1182          """Given a value, attempt to create an instance of some member of this
    1183          union.  The first instance which can be legally created is returned.
    1184
    1185          @keyword _validate_constraints: If C{True} (default if validation is
    1186          enabled), any constructed value is checked against constraints applied
    1187          to the union as well as the member type.
    1188
    1189          @raise pyxb.SimpleTypeValueError: no member type will permit creation of
    1190          an instance from the parameters in C{args} and C{kw}.
    1191          """
    1192
    1193          used_cls = cls._SupersedingClass()
    1194          state = used_cls._PreFactory_vx(args, kw)
    1195
    1196          rv = None
    1197          # NB: get, not pop: preserve it for the member type invocations
    1198          validate_constraints = kw.get('_validate_constraints', cls._GetValidationConfig().forBinding)
    1199          assert isinstance(validate_constraints, bool)
    1200          if 0 < len(args):
    1201              arg = args[0]
    1202              try:
    1203                  rv = cls._ValidatedMember(arg)
    1204              except pyxb.SimpleTypeValueError:
    1205                  pass
    1206          if rv is None:
    1207              kw['_validate_constraints'] = True
    1208              for mt in cls._MemberTypes:
    1209                  try:
    1210                      rv = mt.Factory(*args, **kw)
    1211                      break
    1212                  except pyxb.SimpleTypeValueError:
    1213                      pass
    1214                  except (ValueError, OverflowError):
    1215                      pass
    1216                  except:
    1217                      pass
    1218          location = None
    1219          if kw is not None:
    1220              location = kw.get('_location')
    1221          if rv is not None:
    1222              if validate_constraints:
    1223                  cls.XsdConstraintsOK(rv, location)
    1224              rv._postFactory_vx(state)
    1225              return rv
    1226          # The constructor may take any number of arguments, so pass the whole thing.
    1227          # Should we also provide the keywords?
    1228          raise pyxb.SimpleUnionValueError(cls, args, location)
    1229
    1230      @classmethod
    1231 -    def _ValidatedMember (cls, value):
    1232          """Validate the given value as a potential union member.
    1233
    1234          @raise pyxb.SimpleTypeValueError: the value is not an instance of a
    1235          member type."""
    1236          if not isinstance(value, cls._MemberTypes):
    1237              for mt in cls._MemberTypes:
    1238                  try:
    1239                      # Force validation so we get the correct type, otherwise
    1240                      # first member will be accepted.
    1241                      value = mt.Factory(value, _validate_constraints=True)
    1242                      return value
    1243                  except (TypeError, pyxb.SimpleTypeValueError):
    1244                      pass
    1245              raise pyxb.SimpleUnionValueError(cls, value)
    1246          return value
    1247
    1248 -    def __new__ (self, *args, **kw):
    1249          raise pyxb.LogicError('%s: cannot construct instances of union' % (self.__class__.__name__,))
    1250
    1251 -    def __init__ (self, *args, **kw):
    1252          raise pyxb.LogicError('%s: cannot construct instances of union' % (self.__class__.__name__,))
    1253
    1254      @classmethod
    1255 -    def _description (cls, name_only=False, user_documentation=True):
    1256          name = cls._Name()
    1257          if name_only:
    1258              return name
    1259          desc = [ name, ', union of ']
    1260          desc.append(', '.join([ _td._description(name_only=True) for _td in cls._MemberTypes ]))
    1261          return ''.join(desc)
    1262
    1263      @classmethod
    1264 -    def XsdLiteral (cls, value):
    1265          """Convert from a binding value to a string usable in an XML document."""
    1266          return cls._ValidatedMember(value).xsdLiteral()
    1267
    1268
    1269 -class STD_list (simpleTypeDefinition, types.ListType):
    1270      """Base class for collection datatypes.
    1271
    1272      This class descends from the Python list type, and incorporates
    1273      simpleTypeDefinition.  Subclasses must define a class variable _ItemType
    1274      which is a reference to the class of which members must be instances."""
    1275
    1276      _ItemType = None
    1277      """A reference to the binding class for items within this list."""
    1278
    1279      # Ick: If we don't declare this here, this class's map doesn't get
    1280      # initialized.  Alternative is to not descend from simpleTypeDefinition.
    1281      __FacetMap = {}
    1282
    1283      @classmethod
    1284 -    def _ValidatedItem (cls, value, kw=None):
    1285          """Verify that the given value is permitted as an item of this list.
    1286
    1287          This may convert the value to the proper type, if it is
    1288          compatible but not an instance of the item type.  Returns the
    1289          value that should be used as the item, or raises an exception
    1290          if the value cannot be converted.
    1291
    1292          @param kw: optional dictionary of standard constructor keywords used
    1293          when exceptions must be built.  In particular, C{_location} may be
    1294          useful.
    1295          """
    1296          if isinstance(value, cls._ItemType):
    1297              pass
    1298          elif issubclass(cls._ItemType, STD_union):
    1299              value = cls._ItemType._ValidatedMember(value)
    1300          else:
    1301              try:
    1302                  value = cls._ItemType(value)
    1303              except (pyxb.SimpleTypeValueError, TypeError):
    1304                  location = None
    1305                  if kw is not None:
    1306                      location = kw.get('_location')
    1307                  raise pyxb.SimpleListValueError(cls, value, location)
    1308          return value
    1309
    1310      @classmethod
    1311 -    def _ConvertArguments_vx (cls, args, kw):
    1312          # If the first argument is a string, split it on spaces and use the
    1313          # resulting list of tokens.
    1314          if 0 < len(args):
    1315              arg1 = args[0]
    1316              if isinstance(arg1, types.StringTypes):
    1317                  args = (arg1.split(),) + args[1:]
    1318                  arg1 = args[0]
    1319              if isinstance(arg1, collections.Iterable):
    1320                  new_arg1 = [ cls._ValidatedItem(_v, kw) for _v in arg1 ]
    1321                  args = (new_arg1,) + args[1:]
    1322          super_fn = getattr(super(STD_list, cls), '_ConvertArguments_vx', lambda *a,**kw: args)
    1323          return super_fn(args, kw)
    1324
    1325      @classmethod
    1326 -    def _XsdValueLength_vx (cls, value):
    1327          return len(value)
    1328
    1329      @classmethod
    1330 -    def XsdLiteral (cls, value):
    1331          """Convert from a binding value to a string usable in an XML document."""
    1332          return ' '.join([ cls._ItemType.XsdLiteral(_v) for _v in value ])
    1333
    1334      @classmethod
    1335 -    def _description (cls, name_only=False, user_documentation=True):
    1336          name = cls._Name()
    1337          if name_only:
    1338              return name
    1339          desc = [ name, ', list of ', cls._ItemType._description(name_only=True) ]
    1340          return ''.join(desc)
    1341
    1342      # Convert a single value to the required type, if not already an instance
    1343      @classmethod
    1344 -    def __ConvertOne (cls, v):
    1345          return cls._ValidatedItem(v)
    1346
    1347      # Convert a sequence of values to the required type, if not already instances
    1348 -    def __convertMany (self, values):
    1349          return [ self._ValidatedItem(_v) for _v in values ]
    1350
    1351 -    def __setitem__ (self, key, value):
    1352          if isinstance(key, slice):
    1353              super(STD_list, self).__setitem__(key, self.__convertMany(value))
    1354          else:
    1355              super(STD_list, self).__setitem__(key, self._ValidatedItem(value))
    1356
    1357      #!python3>! required for python2 since deriving from built-in type
    1358 -    def __setslice__ (self, start, end, values):
    1359          super(STD_list, self).__setslice__(start, end, self.__convertMany(values))
    1360      #!python3<!
    1361
    1362 -    def __contains__ (self, item):
    1363          return super(STD_list, self).__contains__(self._ValidatedItem(item))
    1364
    1365      # Standard mutable sequence methods, per Python Library Reference "Mutable Sequence Types"
    1366
    1367 -    def append (self, x):
    1368          super(STD_list, self).append(self._ValidatedItem(x))
    1369
    1370 -    def extend (self, x, _from_xml=False):
    1371          super(STD_list, self).extend(self.__convertMany(x))
    1372
    1373 -    def count (self, x):
    1374          return super(STD_list, self).count(self._ValidatedItem(x))
    1375
    1376 -    def index (self, x, *args):
    1377          return super(STD_list, self).index(self._ValidatedItem(x), *args)
    1378
    1379 -    def insert (self, i, x):
    1380          super(STD_list, self).insert(i, self._ValidatedItem(x))
    1381
    1382 -    def remove (self, x):
    1383          super(STD_list, self).remove(self._ValidatedItem(x))
    1384
    1385 -class element (utility._DeconflictSymbols_mixin, _DynamicCreate_mixin):
    1386      """Class that represents a schema element within a binding.
    1387
    1388      This gets a little confusing.  Within a schema, the
    1389      L{pyxb.xmlschema.structures.ElementDeclaration} type represents an
    1390      U{element
    1391      declaration<http://www.w3.org/TR/xmlschema-1/#cElement_Declarations>}.
    1392      Those declarations may be global (have a name that is visible in the
    1393      namespace), or local (have a name that is visible only within a complex
    1394      type definition).  Further, local (but not global) declarations may have a
    1395      reference to a global declaration (which might be in a different
    1396      namespace).
    1397
    1398      Within a PyXB binding, the element declarations from the original complex
    1399      type definition that have the same
    1400      U{QName<http://www.w3.org/TR/1999/REC-xml-names-19990114/#dt-qname>}
    1401      (after deconflicting the
    1402      U{LocalPart<http://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-LocalPart>})
    1403      are associated with an attribute in the class for the complex type.  Each
    1404      of these attributes is defined via a
    1405      L{pyxb.binding.content.ElementDeclaration} which provides the mechanism by
    1406      which the binding holds values associated with that element.
    1407
    1408      Furthermore, in the FAC-based content model each schema element
    1409      declaration is associated with an
    1410      L{ElementUse<pyxb.binding.content.ElementUse>} instance to locate the
    1411      point in the schema where content came from.  Instances that refer to the
    1412      same schema element declaration share the same underlying
    1413      L{pyxb.binding.content.ElementDeclaration}.
    1414
    1415      This element isn't any of those elements.  This element is the type used
    1416      for an attribute which associates the name of a element with data required
    1417      to represent it, all within a particular scope (a module for global scope,
    1418      the binding class for a complex type definition for local scope).  From
    1419      the perspective of a PyXB user they look almost like a class, in that you
    1420      can call them to create instances of the underlying complex type.
    1421
    1422      Global and local elements are represented by instances of this class.
    1423      """
    1424
    1425 -    def name (self):
    1426          """The expanded name of the element within its scope."""
    1427          return self.__name
    1428      __name = None
    1429
    1430 -    def typeDefinition (self):
    1431          """The L{_TypeBinding_mixin} subclass for values of this element."""
    1432          return self.__typeDefinition._SupersedingClass()
    1433      __typeDefinition = None
    1434
    1435 -    def xsdLocation (self):
    1436          """The L{pyxb.utils.utility.Location} where the element appears in the schema."""
    1437          return self.__xsdLocation
    1438      __xsdLocation = None
    1439
    1440 -    def scope (self):
    1441          """The scope of the element.  This is either C{None}, representing a
    1442          top-level element, or an instance of C{complexTypeDefinition} for
    1443          local elements."""
    1444          return self.__scope
    1445      __scope = None
    1446
    1447 -    def nillable (self):
    1448          """Indicate whether values matching this element can have U{nil
    1449          <http://www.w3.org/TR/xmlschema-1/#xsi_nil>} set."""
    1450          return self.__nillable
    1451      __nillable = False
    1452
    1453 -    def abstract (self):
    1454          """Indicate whether this element is abstract (must use substitution
    1455          group members for matches)."""
    1456          return self.__abstract
    1457      __abstract = False
    1458
    1459 -    def documentation (self):
    1460          """Contents of any documentation annotation in the definition."""
    1461          return self.__documentation
    1462      __documentation = None
    1463
    1464 -    def defaultValue (self):
    1465          """The default value of the element.
    1466
    1467          C{None} if the element has no default value.
    1468
    1469          @note: A non-C{None} value is always an instance of a simple type,
    1470          even if the element has complex content."""
    1471          return self.__defaultValue
    1472      __defaultValue = None
    1473
    1474 -    def fixed (self):
    1475          """C{True} if the element content cannot be changed"""
    1476          return self.__fixed
    1477      __fixed = False
    1478
    1479 -    def substitutionGroup (self):
    1480          """The L{element} instance to whose substitution group this element
    1481          belongs.  C{None} if this element is not part of a substitution
    1482          group."""
    1483          return self.__substitutionGroup
    1484 -    def _setSubstitutionGroup (self, substitution_group):
    1485          self.__substitutionGroup = substitution_group
    1486          if substitution_group is not None:
    1487              self.substitutesFor = self._real_substitutesFor
    1488          return self
    1489      __substitutionGroup = None
    1490
    1491 -    def findSubstituendDecl (self, ctd_class):
    1492          ed = ctd_class._ElementMap.get(self.name())
    1493          if ed is not None:
    1494              return ed
    1495          if self.substitutionGroup() is None:
    1496              return None
    1497          return self.substitutionGroup().findSubstituendDecl(ctd_class)
    1498
    1499 -    def _real_substitutesFor (self, other):
    1500          """Determine whether an instance of this element can substitute for the other element.
    1501
    1502          See U{Substitution Group OK<http://www.w3.org/TR/xmlschema-1/#cos-equiv-derived-ok-rec>}.
    1503
    1504          @todo: Do something about blocking constraints.  This ignores them, as
    1505          does everything leading to this point.
    1506          """
    1507          if self.substitutionGroup() is None:
    1508              return False
    1509          if other is None:
    1510              return False
    1511          assert isinstance(other, element)
    1512          # On the first call, other is likely to be the local element.  We need
    1513          # the global one.
    1514          if other.scope() is not None:
    1515              other = other.name().elementBinding()
    1516              if other is None:
    1517                  return False
    1518              assert other.scope() is None
    1519          # Do both these refer to the same (top-level) element?
    1520          if self.name().elementBinding() == other:
    1521              return True
    1522          return (self.substitutionGroup() == other) or self.substitutionGroup().substitutesFor(other)
    1523
    1524 -    def substitutesFor (self, other):
    1525          """Stub replaced by _real_substitutesFor when element supports substitution groups."""
    1526          return False
    1527
    1528 -    def memberElement (self, name):
    1529          """Return a reference to the element instance used for the given name
    1530          within this element.
    1531
    1532          The type for this element must be a complex type definition."""
    1533          return self.typeDefinition()._UseForTag(name).elementBinding()
    1534
    1535 -    def __init__ (self, name, type_definition, scope=None, nillable=False, abstract=False, unicode_default=None, fixed=False, substitution_group=None, documentation=None, location=None):
    1536          """Create a new element binding.
    1537          """
    1538          assert isinstance(name, pyxb.namespace.ExpandedName)
    1539          self.__name = name
    1540          self.__typeDefinition = type_definition
    1541          self.__scope = scope
    1542          self.__nillable = nillable
    1543          self.__abstract = abstract
    1544          if unicode_default is not None:
    1545              # Override default None.  If this is a complex type with simple
    1546              # content, use the underlying simple type value.
    1547              self.__defaultValue = self.__typeDefinition.Factory(unicode_default, _from_xml=True)
    1548              if isinstance(self.__defaultValue, complexTypeDefinition):
    1549                  self.__defaultValue = self.__defaultValue.value()
    1550          self.__fixed = fixed
    1551          self.__substitutionGroup = substitution_group
    1552          self.__documentation = documentation
    1553          self.__xsdLocation = location
    1554          super(element, self).__init__()
    1555
    1556 -    def __call__ (self, *args, **kw):
    1557          """Invoke the Factory method on the type associated with this element.
    1558
    1559          @keyword _dom_node: This keyword is removed.  If present, it must be C{None}.
    1560
    1561          @note: Other keywords are passed to L{_TypeBinding_mixin.Factory}.
    1562
    1563          @raise pyxb.AbstractElementError: This element is abstract and no DOM
    1564          node was provided.
    1565          """
    1566          dom_node = kw.pop('_dom_node', None)
    1567          assert dom_node is None, 'Cannot pass DOM node directly to element constructor; use createFromDOM'
    1568          if '_element' in kw:
    1569              raise pyxb.LogicError('Cannot set _element in element-based instance creation')
    1570          kw['_element'] = self
    1571          # Can't create instances of abstract elements.
    1572          if self.abstract():
    1573              location = kw.get('_location')
    1574              if (location is None) and isinstance(dom_node, utility.Locatable_mixin):
    1575                  location = dom_node._location()
    1576              raise pyxb.AbstractElementError(self, location, args)
    1577          if self.__defaultValue is not None:
    1578              if 0 == len(args):
    1579                  # No initial value; use the default
    1580                  args = [ self.__defaultValue ]
    1581              elif self.__fixed:
    1582                  # Validate that the value is consistent with the fixed value
    1583                  if 1 < len(args):
    1584                      raise ValueError(*args)
    1585                  args = [ self.compatibleValue(args[0], **kw) ]
    1586          rv = self.typeDefinition().Factory(*args, **kw)
    1587          rv._setElement(self)
    1588          return rv
    1589
    1590 -    def compatibleValue (self, value, **kw):
    1591          """Return a variant of the value that is compatible with this element.
    1592
    1593          This mostly defers to L{_TypeBinding_mixin._CompatibleValue}.
    1594
    1595          @raise pyxb.SimpleTypeValueError: if the value is not both
    1596          type-consistent and value-consistent with the element's type.
    1597          """
    1598          # None is always None, unless there's a default.
    1599          if value is None:
    1600              return self.__defaultValue
    1601          is_plural = kw.pop('is_plural', False)
    1602          if is_plural:
    1603              if not isinstance(value, collections.Iterable):
    1604                  raise pyxb.SimplePluralValueError(self.typeDefinition(), value)
    1605              return [ self.compatibleValue(_v) for _v in value ]
    1606          if self.__fixed and (value != self.__defaultValue):
    1607              raise pyxb.ElementChangeError(self, value)
    1608          if isinstance(value, _TypeBinding_mixin) and (value._element() is not None) and value._element().substitutesFor(self):
    1609              return value
    1610          if self.abstract():
    1611              location = None
    1612              if isinstance(value, utility.Locatable_mixin):
    1613                  location = value._location()
    1614              raise pyxb.AbstractElementError(self, location, value)
    1615          return self.typeDefinition()._CompatibleValue(value, **kw)
    1616
    1617      @classmethod
    1618 -    def CreateDOMBinding (cls, node, element_binding, **kw):
    1619          """Create a binding from a DOM node.
    1620
    1621          @param node: The DOM node
    1622
    1623          @param element_binding: An instance of L{element} that would normally
    1624          be used to determine the type of the binding.  The actual type of
    1625          object returned is determined by the type definition associated with
    1626          the C{element_binding} and the value of any U{xsi:type
    1627          <http://www.w3.org/TR/xmlschema-1/#xsi_type>} attribute found in
    1628          C{node}, modulated by
    1629          L{XSI._InterpretTypeAttribute<pyxb.namespace.builtin._XMLSchema_instance._InterpretTypeAttribute>}.
    1630
    1631          @keyword _fallback_namespace: The namespace to use as the namespace for
    1632          the node, if the node name is unqualified.  This should be an absent
    1633          namespace.
    1634
    1635          @return: A binding for the DOM node.
    1636
    1637          @raises pyxb.UnrecognizedDOMRootNodeError: if no underlying element or
    1638          type for the node can be identified.
    1639          """
    1640
    1641          if xml.dom.Node.ELEMENT_NODE != node.nodeType:
    1642              raise ValueError('node is not an element')
    1643
    1644          fallback_namespace = kw.get('_fallback_namespace')
    1645
    1646          # Record the element to be associated with the created binding
    1647          # instance.
    1648          if '_element' in kw:
    1649              raise pyxb.LogicError('Cannot set _element in element-based instance creation')
    1650
    1651          type_class = None
    1652          if element_binding is not None:
    1653              # Can't create instances of abstract elements.  @todo: Is there any
    1654              # way this could be legal given an xsi:type attribute?  I'm pretty
    1655              # sure "no"...
    1656              if element_binding.abstract():
    1657                  location = kw.get('location')
    1658                  if (location is None) and isinstance(node, utility.Locatable_mixin):
    1659                      location = node._location()
    1660                  raise pyxb.AbstractElementError(element_binding, location, node)
    1661              kw['_element'] = element_binding
    1662              type_class = element_binding.typeDefinition()
    1663
    1664          # Get the namespace context for the value being created.  If none is
    1665          # associated, one will be created.  Do not make assumptions about the
    1666          # namespace context; if the user cared, she should have assigned a
    1667          # context before calling this.
    1668          ns_ctx = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node)
    1669          (did_replace, type_class) = XSI._InterpretTypeAttribute(XSI.type.getAttribute(node), ns_ctx, fallback_namespace, type_class)
    1670
    1671          if type_class is None:
    1672              raise pyxb.UnrecognizedDOMRootNodeError(node)
    1673
    1674          # Pass xsi:nil on to the constructor regardless of whether the element
    1675          # is nillable.  Another sop to SOAP-encoding WSDL fans who don't
    1676          # bother to provide valid schema for their message content.
    1677          is_nil = XSI.nil.getAttribute(node)
    1678          if is_nil is not None:
    1679              kw['_nil'] = pyxb.binding.datatypes.boolean(is_nil)
    1680
    1681          rv = type_class.Factory(_dom_node=node, **kw)
    1682          assert rv._element() == element_binding
    1683          rv._setNamespaceContext(pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node))
    1684          return rv._postDOMValidate()
    1685
    1686      # element
    1687      @classmethod
    1688 -    def AnyCreateFromDOM (cls, node, fallback_namespace):
    1689          """Create an instance of an element from a DOM node.
    1690
    1691          This method does minimal processing of C{node} and delegates to
    1692          L{CreateDOMBinding}.
    1693
    1694          @param node: An C{xml.dom.Node} representing a root element.  If the
    1695          node is a document, that document's root node will be substituted.
    1696          The name of the node is extracted as the name of the element to be
    1697          created, and the node and the name are passed to L{CreateDOMBinding}.
    1698
    1699          @param fallback_namespace: The value to pass as C{_fallback_namespace}
    1700          to L{CreateDOMBinding}
    1701
    1702          @return: As with L{CreateDOMBinding}"""
    1703          if xml.dom.Node.DOCUMENT_NODE == node.nodeType:
    1704              node = node.documentElement
    1705          expanded_name = pyxb.namespace.ExpandedName(node, fallback_namespace=fallback_namespace)
    1706          return cls.CreateDOMBinding(node, expanded_name.elementBinding(), _fallback_namespace=fallback_namespace)
    1707
    1708 -    def elementForName (self, name):
    1709          """Return the element that should be used if this element binding is
    1710          permitted and an element with the given name is encountered.
    1711
    1712          Normally, the incoming name matches the name of this binding, and
    1713          C{self} is returned.  If the incoming name is different, it is
    1714          expected to be the name of a global element which is within this
    1715          element's substitution group.  In that case, the binding corresponding
    1716          to the named element is return.
    1717
    1718          @return: An instance of L{element}, or C{None} if no element with the
    1719          given name can be found.
    1720          """
    1721
    1722          # Name match means OK.
    1723          if self.name() == name:
    1724              return self
    1725          # No name match means only hope is a substitution group, for which the
    1726          # element must be top-level.
    1727          top_elt = self.name().elementBinding()
    1728          if top_elt is None:
    1729              return None
    1730          # Members of the substitution group must also be top-level.  NB: If
    1731          # named_elt == top_elt, then the adoptName call below improperly
    1732          # associated the global namespace with a local element of the same
    1733          # name; cf. test-namespace-uu:testBad.
    1734          elt_en = top_elt.name().adoptName(name)
    1735          assert 'elementBinding' in elt_en.namespace()._categoryMap(), 'No element bindings in %s' % (elt_en.namespace(),)
    1736          named_elt = elt_en.elementBinding()
    1737          if (named_elt is None) or (named_elt == top_elt):
    1738              return None
    1739          if named_elt.substitutesFor(top_elt):
    1740              return named_elt
    1741          return None
    1742
    1743 -    def createFromDOM (self, node, fallback_namespace=None, **kw):
    1744          """Create an instance of this element using a DOM node as the source
    1745          of its content.
    1746
    1747          This method does minimal processing of C{node} and delegates to
    1748          L{_createFromDOM}.
    1749
    1750          @param node: An C{xml.dom.Node} representing a root element.  If the
    1751          node is a document, that document's root node will be substituted.
    1752          The name of the node is extracted as the name of the element to be
    1753          created, and the node and the name are passed to L{_createFromDOM}
    1754
    1755          @keyword fallback_namespace: Used as default for
    1756          C{_fallback_namespace} in call to L{_createFromDOM}
    1757
    1758          @note: Keyword parameters are passed to L{CreateDOMBinding}.
    1759
    1760          @return: As with L{_createFromDOM}
    1761          """
    1762          if xml.dom.Node.DOCUMENT_NODE == node.nodeType:
    1763              node = node.documentElement
    1764          if fallback_namespace is not None:
    1765              kw.setdefault('_fallback_namespace', fallback_namespace)
    1766          expanded_name = pyxb.namespace.ExpandedName(node, fallback_namespace=fallback_namespace)
    1767          return self._createFromDOM(node, expanded_name, **kw)
    1768
    1769 -    def _createFromDOM (self, node, expanded_name, **kw):
    1770          """Create an instance from a DOM node given the name of an element.
    1771
    1772          This method does minimal processing of C{node} and C{expanded_name}
    1773          and delegates to L{CreateDOMBinding}.
    1774
    1775          @param node: An C{xml.dom.Node} representing a root element.  If the
    1776          node is a document, that document's root node will be substituted.
    1777          The value is passed to L{CreateDOMBinding}.
    1778
    1779          @param expanded_name: The expanded name of the element to be used for
    1780          content.  This is passed to L{elementForName} to obtain the binding
    1781          that is passed to L{CreateDOMBinding}, superseding any identification
    1782          that might be inferred from C{node}.  If no name is available, use
    1783          L{createFromDOM}.
    1784
    1785          @note: Keyword parameters are passed to L{CreateDOMBinding}.
    1786
    1787          @return: As with L{CreateDOMBinding}.
    1788          """
    1789          if xml.dom.Node.DOCUMENT_NODE == node.nodeType:
    1790              node = node.documentElement
    1791          return element.CreateDOMBinding(node, self.elementForName(expanded_name), **kw)
    1792
    1793 -    def __str__ (self):
    1794          return 'Element %s' % (self.name(),)
    1795
    1796 -    def _description (self, name_only=False, user_documentation=True):
    1797          name = unicode(self.name())
    1798          if name_only:
    1799              return name
    1800          desc = [ name, ' (', self.typeDefinition()._description(name_only=True), ')' ]
    1801          if self.scope() is not None:
    1802              desc.extend([', local to ', self.scope()._description(name_only=True) ])
    1803          if self.nillable():
    1804              desc.append(', nillable')
    1805          if self.substitutionGroup() is not None:
    1806              desc.extend([', substitutes for ', self.substitutionGroup()._description(name_only=True) ])
    1807          if user_documentation and (self.documentation() is not None):
    1808              desc.extend(["\n", self.documentation() ])
    1809          return u''.join(desc)
    1810
    1811 -class enumeration_mixin (pyxb.cscRoot):
    1812      """Marker in case we need to know that a PST has an enumeration constraint facet."""
    1813
    1814      @classmethod
    1815 -    def values (cls):
    1816          """Return a list of values that the enumeration can take."""
    1817          return cls._CF_enumeration.values()
    1818
    1819      @classmethod
    1820 -    def itervalues (cls):
    1821          """Return a generator for the values that the enumeration can take."""
    1822          return cls._CF_enumeration.itervalues()
    1823
    1824      @classmethod
    1825 -    def items (cls):
    1826          """Return the associated L{pyxb.binding.facet._EnumerationElement} instances."""
    1827          return cls._CF_enumeration.items()
    1828
    1829      @classmethod
    1830 -    def iteritems (cls):
    1831          """Generate the associated L{pyxb.binding.facet._EnumerationElement} instances."""
    1832          return cls._CF_enumeration.iteritems()
    1833
    1834 -class _Content (object):
    1835      """Base for any wrapper added to L{complexTypeDefinition.orderedContent}."""
    1836
    1837 -    def __getValue (self):
    1838          """The value of the content.
    1839
    1840          This is a unicode string for L{NonElementContent}, and (ideally) an
    1841          instance of L{_TypeBinding_mixin} for L{ElementContent}."""
    1842          return self.__value
    1843      __value = None
    1844      value = property(__getValue)
    1845
    1846      @classmethod
    1847 -    def ContentIterator (cls, input):
    1848          """Return an iterator that filters and maps a sequence of L{_Content}
    1849          instances.
    1850
    1851          The returned iterator will filter out sequence members that are not
    1852          instances of the class from which the iterator was created.  Further,
    1853          only the L{value} field of the sequence member is returned.
    1854
    1855          Thus the catenated text of the non-element content of an instance can
    1856          be obtained with::
    1857
    1858             text = u''.join(NonElementContent.ContentIterator(instance.orderedContent()))
    1859
    1860          See also L{pyxb.NonElementContent}
    1861          """
    1862          class _Iterator:
    1863              def __init__ (self, input):
    1864                  self.__input = iter(input)
    1865              def __iter__ (self):
    1866                  return self
    1867              def next (self):
    1868                  while True:
    1869                      content = self.__input.next()
    1870                      if isinstance(content, cls):
    1871                          return content.value
    1872          return _Iterator(input)
    1873
    1874 -    def __init__ (self, value):
    1875          self.__value = value
    1876
    1877 -class ElementContent (_Content):
    1878      """Marking wrapper for element content.
    1879
    1880      The value should be translated into XML and made a child of its parent."""
    1881
    1882 -    def __getElementDeclaration (self):
    1883          """The L{pyxb.binding.content.ElementDeclaration} associated with the element content.
    1884          This may be C{None} if the value is a wildcard."""
    1885          return self.__elementDeclaration
    1886      __elementDeclaration = None
    1887
    1888      elementDeclaration = property(__getElementDeclaration)
    1889
    1890 -    def __init__ (self, value, element_declaration=None, instance=None, tag=None):
    1891          """Create a wrapper associating a value with its element declaration.
    1892
    1893          Normally the element declaration is determined by consulting the
    1894          content model when creating a binding instance.  When manipulating the
    1895          preferred content list, this may be inconvenient to obtain; in that case
    1896          provide the C{instance} in which the content appears immediately,
    1897          along with the C{tag} that is used for the Python attribute that holds
    1898          the element.
    1899
    1900          @param value: the value of the element.  Should be an instance of
    1901          L{_TypeBinding_mixin}, but for simple types might be a Python native
    1902          type.
    1903
    1904          @keyword element_declaration: The
    1905          L{pyxb.binding.content.ElementDeclaration} associated with the element
    1906          value.  Should be C{None} if the element matches wildcard content.
    1907
    1908          @keyword instance: Alternative path to providing C{element_declaration}
    1909          @keyword tag: Alternative path to providing C{element_declaration}
    1910          """
    1911
    1912          import pyxb.binding.content
    1913          super(ElementContent, self).__init__(value)
    1914          if instance is not None:
    1915              if not isinstance(instance, complexTypeDefinition):
    1916                  raise pyxb.UsageError('Unable to determine element declaration')
    1917              element_declaration = instance._UseForTag(tag)
    1918          assert (element_declaration is None) or isinstance(element_declaration, pyxb.binding.content.ElementDeclaration)
    1919          self.__elementDeclaration = element_declaration
    1920
    1921 -class NonElementContent (_Content):
    1922      """Marking wrapper for non-element content.
    1923
    1924      The value will be unicode text, and should be appended as character
    1925      data."""
    1926 -    def __init__ (self, value):
    1927          super(NonElementContent, self).__init__(unicode(value))
    1928
    1929 -class complexTypeDefinition (_TypeBinding_mixin, utility._DeconflictSymbols_mixin, _DynamicCreate_mixin):
    1930      """Base for any Python class that serves as the binding for an
    1931      XMLSchema complexType.
    1932
    1933      Subclasses should define a class-level _AttributeMap variable which maps
    1934      from the unicode tag of an attribute to the AttributeUse instance that
    1935      defines it.  Similarly, subclasses should define an _ElementMap variable.
    1936      """
    1937
    1938      _CT_EMPTY = 'EMPTY'                 #<<< No content
    1939      _CT_SIMPLE = 'SIMPLE'               #<<< Simple (character) content
    1940      _CT_MIXED = 'MIXED'                 #<<< Children may be elements or other (e.g., character) content
    1941      _CT_ELEMENT_ONLY = 'ELEMENT_ONLY'   #<<< Expect only element content.
    1942
    1943      _ContentTypeTag = None
    1944
    1945      _TypeDefinition = None
    1946      """Subclass of simpleTypeDefinition that corresponds to the type content.
    1947      Only valid if _ContentTypeTag is _CT_SIMPLE"""
    1948
    1949      # A value that indicates whether the content model for this type supports
    1950      # wildcard elements.  Supporting classes should override this value.
    1951      _HasWildcardElement = False
    1952
    1953      # Map from expanded names to ElementDeclaration instances
    1954      _ElementMap = { }
    1955      """Map from expanded names to ElementDeclaration instances."""
    1956
    1957      # Per-instance map from tags to attribute values for wildcard attributes.
    1958      # Value is C{None} if the type does not support wildcard attributes.
    1959      __wildcardAttributeMap = None
    1960
    1961 -    def wildcardAttributeMap (self):
    1962          """Obtain access to wildcard attributes.
    1963
    1964          The return value is C{None} if this type does not support wildcard
    1965          attributes.  If wildcard attributes are allowed, the return value is a
    1966          map from QNames to the unicode string value of the corresponding
    1967          attribute.
    1968
    1969          @todo: The map keys should be namespace extended names rather than
    1970          QNames, as the in-scope namespace may not be readily available to the
    1971          user.
    1972          """
    1973          return self.__wildcardAttributeMap
    1974
    1975      # Per-instance list of DOM nodes interpreted as wildcard elements.
    1976      # Value is None if the type does not support wildcard elements.
    1977      __wildcardElements = None
    1978
    1979 -    def wildcardElements (self):
    1980          """Obtain access to wildcard elements.
    1981
    1982          The return value is C{None} if the content model for this type does not
    1983          support wildcard elements.  If wildcard elements are allowed, the
    1984          return value is a list of values corresponding to conformant
    1985          unrecognized elements, in the order in which they were encountered.
    1986          If the containing binding was created from an XML document and enough
    1987          information was present to determine the binding of the member
    1988          element, the value is a binding instance.  Otherwise, the value is the
    1989          original DOM Element node.
    1990          """
    1991          return self.__wildcardElements
    1992
    1993 -    def __init__ (self, *args, **kw):
    1994          """Create a new instance of this binding.
    1995
    1996          Arguments are used as transition values along the content model.
    1997          Keywords are passed to the constructor of any simple content, or used
    1998          to initialize attribute and element values whose L{id
    1999          <content.ElementDeclaration.id>} (not L{name <content.ElementDeclaration.name>})
    2000          matches the keyword.
    2001
    2002          @keyword _dom_node: The node to use as the source of binding content.
    2003          @type _dom_node: C{xml.dom.Element}
    2004
    2005          @keyword _location: An optional instance of
    2006          L{pyxb.utils.utility.Location} showing the origin the binding.  If
    2007          C{None}, a value from C{_dom_node} is used if available.
    2008
    2009          @keyword _from_xml: See L{_TypeBinding_mixin.Factory}
    2010
    2011          @keyword _finalize_content_model: If C{True} the constructor invokes
    2012          L{_TypeBinding_mixin._finalizeContentModel} prior to return.  The
    2013          value defaults to C{False} when content is assigned through keyword
    2014          parameters (bypassing the content model) or neither a C{_dom_node} nor
    2015          positional element parameters have been provided, and to C{True} in
    2016          all other cases.
    2017          """
    2018
    2019          fallback_namespace = kw.pop('_fallback_namespace', None)
    2020          is_nil = False
    2021          dom_node = kw.pop('_dom_node', None)
    2022          location = kw.pop('_location', None)
    2023          from_xml = kw.pop('_from_xml', dom_node is not None)
    2024          do_finalize_content_model = kw.pop('_finalize_content_model', None)
    2025          if dom_node is not None:
    2026              if (location is None) and isinstance(dom_node, pyxb.utils.utility.Locatable_mixin):
    2027                  location = dom_node._location()
    2028              if xml.dom.Node.DOCUMENT_NODE == dom_node.nodeType:
    2029                  dom_node = dom_node.documentElement
    2030              #kw['_validate_constraints'] = False
    2031              is_nil = XSI.nil.getAttribute(dom_node)
    2032              if is_nil is not None:
    2033                  is_nil = kw['_nil'] = pyxb.binding.datatypes.boolean(is_nil)
    2034          if location is not None:
    2035              self._setLocation(location)
    2036          if self._AttributeWildcard is not None:
    2037              self.__wildcardAttributeMap = { }
    2038          if self._HasWildcardElement:
    2039              self.__wildcardElements = []
    2040          if self._Abstract:
    2041              raise pyxb.AbstractInstantiationError(type(self), location, dom_node)
    2042          super(complexTypeDefinition, self).__init__(**kw)
    2043          self.reset()
    2044          self._setAttributesFromKeywordsAndDOM(kw, dom_node)
    2045          did_set_kw_elt = False
    2046          for fu in self._ElementMap.itervalues():
    2047              iv = kw.pop(fu.id(), None)
    2048              if iv is not None:
    2049                  did_set_kw_elt = True
    2050                  fu.set(self, iv)
    2051          if do_finalize_content_model is None:
    2052              do_finalize_content_model = not did_set_kw_elt
    2053          if kw and kw.pop('_strict_keywords', True):
    2054              [ kw.pop(_fkw, None) for _fkw in self._PyXBFactoryKeywords ]
    2055              if kw:
    2056                  raise pyxb.UnprocessedKeywordContentError(self, kw)
    2057          if 0 < len(args):
    2058              if did_set_kw_elt:
    2059                  raise pyxb.UsageError('Cannot mix keyword and positional args for element initialization')
    2060              self.extend(args, _from_xml=from_xml, _location=location)
    2061          elif self._CT_SIMPLE == self._ContentTypeTag:
    2062              value = self._TypeDefinition.Factory(_require_value=not self._isNil(), _dom_node=dom_node, _location=location, _nil=self._isNil(), _apply_attributes=False, *args)
    2063              if value._constructedWithValue():
    2064                  self.append(value)
    2065          elif dom_node is not None:
    2066              self.extend(dom_node.childNodes[:], fallback_namespace)
    2067          else:
    2068              do_finalize_content_model = False
    2069          if do_finalize_content_model:
    2070              self._finalizeContentModel()
    2071
    2072      # Specify the symbols to be reserved for all CTDs.
    2073      _ReservedSymbols = _TypeBinding_mixin._ReservedSymbols.union(set([ 'wildcardElements', 'wildcardAttributeMap',
    2074                               'xsdConstraintsOK', 'content', 'orderedContent', 'append', 'extend', 'value', 'reset' ]))
    2075
    2076      # None, or a reference to a pyxb.utils.fac.Automaton instance that defines
    2077      # the content model for the type.
    2078      _Automaton = None
    2079
    2080      @classmethod
    2081 -    def _AddElement (cls, element):
    2082          """Method used by generated code to associate the element binding with a use in this type.
    2083
    2084          This is necessary because all complex type classes appear in the
    2085          module prior to any of the element instances (which reference type
    2086          classes), so the association must be formed after the element
    2087          instances are available."""
    2088          return cls._UseForTag(element.name())._setElementBinding(element)
    2089
    2090      @classmethod
    2091 -    def _UseForTag (cls, tag, raise_if_fail=True):
    2092          """Return the ElementDeclaration object corresponding to the element name.
    2093
    2094          @param tag: The L{ExpandedName} of an element in the class."""
    2095          try:
    2096              rv = cls._ElementMap[tag]
    2097          except KeyError:
    2098              if raise_if_fail:
    2099                  raise
    2100              rv = None
    2101          return rv
    2102
    2103 -    def __childrenForDOM (self):
    2104          """Generate a list of children in the order in which they should be
    2105          added to the parent when creating a DOM representation of this
    2106          object.
    2107
    2108          @note: This is only used when L{pyxb.RequireValidWhenGenerating} has
    2109          disabled validation.  Consequently, it may not generate valid XML.
    2110          """
    2111          order = []
    2112          for ed in self._ElementMap.itervalues():
    2113              value = ed.value(self)
    2114              if value is None:
    2115                  continue
    2116              if isinstance(value, list) and ed.isPlural():
    2117                  order.extend([ ElementContent(_v, ed) for _v in value ])
    2118                  continue
    2119              order.append(ElementContent(value, ed))
    2120          return order
    2121
    2122 -    def _validatedChildren (self):
    2123          """Provide the child elements and non-element content in an order
    2124          consistent with the content model.
    2125
    2126          Returns a sequence of tuples representing a valid path through the
    2127          content model where each transition corresponds to one of the member
    2128          element instances within this instance.  The tuple is a pair
    2129          comprising the L{content.ElementDeclaration} instance and the value for the
    2130          transition.
    2131
    2132          If the content of the instance does not validate against the content
    2133          model, an exception is raised.
    2134
    2135          @return: C{None} or a list as described above.
    2136          """
    2137          if self._ContentTypeTag in (self._CT_EMPTY, self._CT_SIMPLE):
    2138              return []
    2139          self._resetAutomaton()
    2140          return self.__automatonConfiguration.sequencedChildren()
    2141
    2142 -    def _symbolSet (self):
    2143          """Return a map from L{content.ElementDeclaration} instances to a list of
    2144          values associated with that use.
    2145
    2146          This is used as the set of symbols available for transitions when
    2147          validating content against a model.  Note that the original
    2148          L{content.ElementUse} that may have validated the assignment of the
    2149          symbol to the content is no longer available, which may result in a
    2150          different order being generated by the content model.  Preservation of
    2151          the original order mitigates this risk.
    2152
    2153          The value C{None} is used to provide the wildcard members, if any.
    2154
    2155          If an element use has no associated values, it must not appear in the
    2156          returned map.
    2157
    2158          @raise pyxb.SimpleTypeValueError: when unable to convert element
    2159          content to the binding declaration type.
    2160          """
    2161          rv = { }
    2162          for eu in self._ElementMap.itervalues():
    2163              value = eu.value(self)
    2164              if value is None:
    2165                  continue
    2166              converter = eu.elementBinding().compatibleValue
    2167              if eu.isPlural():
    2168                  if 0 < len(value):
    2169                      rv[eu] = [ converter(_v) for _v in value ]
    2170              else:
    2171                  rv[eu] = [ converter(value)]
    2172          wce = self.__wildcardElements
    2173          if (wce is not None) and (0 < len(wce)):
    2174              rv[None] = wce[:]
    2175          return rv
    2176
    2177 -    def _validateAttributes (self):
    2178          for au in self._AttributeMap.itervalues():
    2179              au.validate(self)
    2180
    2181 -    def _validateBinding_vx (self):
    2182          if self._isNil():
    2183              if (self._IsSimpleTypeContent() and (self.__content is not None)) or self.__content:
    2184                  raise pyxb.ContentInNilInstanceError(self, self.__content)
    2185              return True
    2186          if self._IsSimpleTypeContent() and (self.__content is None):
    2187              raise pyxb.SimpleContentAbsentError(self, self._location())
    2188          order = self._validatedChildren()
    2189          for content in order:
    2190              if isinstance (content, NonElementContent):
    2191                  continue
    2192              if isinstance(content.value, _TypeBinding_mixin):
    2193                  content.value.validateBinding()
    2194              elif content.elementDeclaration is not None:
    2195                  _log.warning('Cannot validate value %s in field %s', content.value, content.elementDeclaration.id())
    2196          self._validateAttributes()
    2197          return True
    2198
    2199 -    def _setAttribute (self, attr_en, value_lex):
    2200          au = self._AttributeMap.get(attr_en)
    2201          if au is None:
    2202              if self._AttributeWildcard is None:
    2203                  raise pyxb.UnrecognizedAttributeError(type(self), attr_en, self)
    2204              self.__wildcardAttributeMap[attr_en] = value_lex
    2205          else:
    2206              au.set(self, value_lex, from_xml=True)
    2207          return au
    2208
    2209 -    def xsdConstraintsOK (self, location=None):
    2210          """Validate the content against the simple type.
    2211
    2212          @return: C{True} if the content validates against its type.
    2213          @raise pyxb.NotSimpleContentError: this type does not have simple content.
    2214          @raise pyxb.SimpleContentAbsentError: the content of this type has not been set
    2215          """
    2216          # @todo: type check
    2217          if self._CT_SIMPLE != self._ContentTypeTag:
    2218              raise pyxb.NotSimpleContentError(self)
    2219          if self._isNil():
    2220              return True
    2221          if self.__content is None:
    2222              if location is None:
    2223                  location = self._location()
    2224              raise pyxb.SimpleContentAbsentError(self, location)
    2225          return self.value().xsdConstraintsOK(location)
    2226
    2227      # __content is used in two ways: when complex content is used, it is as
    2228      # documented in L{orderedContent}.  When simple content is used, it is as
    2229      # documented in L{value}.
    2230      __content = None
    2231
    2232 -    def orderedContent (self):
    2233          """Return the element and non-element content of the instance in order.
    2234
    2235          This must be a complex type with complex content.  The return value is
    2236          a list of the element and non-element content in a preferred order.
    2237
    2238          The returned list contains L{element<ElementContent>} and
    2239          L{non-element<NonElementContent>} content in the order which it was
    2240          added to the instance.  This may have been through parsing a document,
    2241          constructing an instance using positional arguments, invoking the
    2242          L{append} or L{extend} methods, or assigning directly to an instance
    2243          attribute associated with an element binding.
    2244
    2245          @note: Be aware that assigning directly to an element attribute does not
    2246          remove any previous value for the element from the content list.
    2247
    2248          @note: Be aware that element values directly appended to an instance
    2249          attribute with list type (viz., that corresponds to an element that
    2250          allows more than one occurrence) will not appear in the ordered
    2251          content list.
    2252
    2253          The order in the list may influence the generation of documents
    2254          depending on L{pyxb.ValidationConfig} values that apply to an
    2255          instance.  Non-element content is emitted immediately prior to the
    2256          following element in this list.  Any trailing non-element content is
    2257          emitted after the last element in the content.  The list should
    2258          include all element content.  Element content in this list that is not
    2259          present within an element member of the binding instance may result in
    2260          an error, or may be ignored.
    2261
    2262          @note: The returned value is mutable, allowing the caller to change
    2263          the order to be used.
    2264
    2265          @raise pyxb.NotComplexContentError: this is not a complex type with mixed or element-only content
    2266          """
    2267          if self._ContentTypeTag in (self._CT_EMPTY, self._CT_SIMPLE):
    2268              raise pyxb.NotComplexContentError(self)
    2269          return self.__content
    2270
    2271      @classmethod
    2272 -    def __WarnOnContent (cls):
    2273          if cls.__NeedWarnOnContent:
    2274              import traceback
    2275              cls.__NeedWarnOnContent = False
    2276              _log.warning('Deprecated complexTypeDefinition method "content" invoked\nPlease use "orderedContent"\n%s', ''.join(traceback.format_stack()[:-2]))
    2277              pass
    2278      __NeedWarnOnContent = True
    2279
    2280 -    def content (self):
    2281          """Legacy interface for ordered content.
    2282
    2283          This version does not accurately distinguish non-element content from
    2284          element content that happens to have unicode type.
    2285
    2286          @deprecated: use L{orderedContent}."""
    2287          self.__WarnOnContent()
    2288          if self._ContentTypeTag in (self._CT_EMPTY, self._CT_SIMPLE):
    2289              raise pyxb.NotComplexContentError(self)
    2290          return [ _v.value for _v in self.__content ]
    2291
    2292 -    def value (self):
    2293          """Return the value of the element.
    2294
    2295          This must be a complex type with simple content.  The returned value
    2296          is expected to be an instance of some L{simpleTypeDefinition} class.
    2297
    2298          @raise pyxb.NotSimpleContentError: this is not a complex type with simple content
    2299          """
    2300          if self._CT_SIMPLE != self._ContentTypeTag:
    2301              raise pyxb.NotSimpleContentError(self)
    2302          return self.__content
    2303
    2304 -    def _resetContent (self, reset_elements=False):
    2305          if reset_elements:
    2306              for eu in self._ElementMap.itervalues():
    2307                  eu.reset(self)
    2308          nv = None
    2309          if self._ContentTypeTag in (self._CT_MIXED, self._CT_ELEMENT_ONLY):
    2310              nv = []
    2311          return self.__setContent(nv)
    2312
    2313      __automatonConfiguration = None
    2314 -    def _resetAutomaton (self):
    2315          if self._Automaton is not None:
    2316              if self.__automatonConfiguration is None:
    2317                  import pyxb.binding.content
    2318                  self.__automatonConfiguration = pyxb.binding.content.AutomatonConfiguration(self)
    2319              self.__automatonConfiguration.reset()
    2320          return self.__automatonConfiguration
    2321
    2322 -    def _automatonConfiguration (self):
    2323          """For whitebox testing use only"""
    2324          return self.__automatonConfiguration
    2325
    2326 -    def reset (self):
    2327          """Reset the instance.
    2328
    2329          This resets all element and attribute fields, and discards any
    2330          recorded content.  It resets the content model automaton to its
    2331          initial state.
    2332
    2333          @see: Manipulate the return value of L{orderedContent} if your intent is
    2334          to influence the generation of documents from the binding instance
    2335          without changing its (element) content.
    2336          """
    2337
    2338          self._resetContent(reset_elements=True)
    2339          for au in self._AttributeMap.itervalues():
    2340              au.reset(self)
    2341          self._resetAutomaton()
    2342          return self
    2343
    2344      @classmethod
    2345 -    def _ElementBindingDeclForName (cls, element_name):
    2346          """Determine what the given name means as an element in this type.
    2347
    2348          Normally, C{element_name} identifies an element definition within this
    2349          type.  If so, the returned C{element_decl} identifies that definition,
    2350          and the C{element_binding} is extracted from that use.
    2351
    2352          It may also be that the C{element_name} does not appear as an element
    2353          definition, but that it identifies a global element.  In that case,
    2354          the returned C{element_binding} identifies the global element.  If,
    2355          further, that element is a member of a substitution group which does
    2356          have an element definition in this class, then the returned
    2357          C{element_decl} identifies that definition.
    2358
    2359          If a non-C{None} C{element_decl} is returned, there will be an
    2360          associated C{element_binding}.  However, it is possible to return a
    2361          non-C{None} C{element_binding}, but C{None} as the C{element_decl}.  In
    2362          that case, the C{element_binding} can be used to create a binding
    2363          instance, but the content model will have to treat it as a wildcard.
    2364
    2365          @param element_name: The name of the element in this type, either an
    2366          expanded name or a local name if the element has an absent namespace.
    2367
    2368          @return: C{( element_binding, element_decl )}
    2369          """
    2370          element_decl = cls._ElementMap.get(element_name)
    2371          element_binding = None
    2372          if element_decl is None:
    2373              try:
    2374                  element_binding = element_name.elementBinding()
    2375              except pyxb.NamespaceError:
    2376                  pass
    2377              if element_binding is not None:
    2378                  element_decl = element_binding.findSubstituendDecl(cls)
    2379          else:
    2380              element_binding = element_decl.elementBinding()
    2381          return (element_binding, element_decl)
    2382
    2383 -    def append (self, value, **kw):
    2384          """Add the value to the instance.
    2385
    2386          The value should be a DOM node or other value that is or can be
    2387          converted to a binding instance, or a string if the instance allows
    2388          mixed content.  The value must be permitted by the content model.
    2389
    2390          @raise pyxb.ContentValidationError: the value is not permitted at the current
    2391          state of the content model.
    2392          """
    2393
    2394          # @todo: Allow caller to provide default element use; it's available
    2395          # in saxer.
    2396          element_decl = kw.get('_element_decl', None)
    2397          maybe_element = kw.get('_maybe_element', True)
    2398          location = kw.get('_location', None)
    2399          if self._isNil():
    2400              raise pyxb.ContentInNilInstanceError(self, value, location)
    2401          fallback_namespace = kw.get('_fallback_namespace', None)
    2402          require_validation = kw.get('_require_validation', self._validationConfig.forBinding)
    2403          from_xml = kw.get('_from_xml', False)
    2404          element_binding = None
    2405          if element_decl is not None:
    2406              from pyxb.binding import content
    2407              assert isinstance(element_decl, content.ElementDeclaration)
    2408              element_binding = element_decl.elementBinding()
    2409              assert element_binding is not None
    2410          # Convert the value if it's XML and we recognize it.
    2411          if isinstance(value, xml.dom.Node):
    2412              from_xml = True
    2413              assert maybe_element
    2414              assert element_binding is None
    2415              node = value
    2416              require_validation = pyxb.GlobalValidationConfig.forBinding
    2417              if xml.dom.Node.COMMENT_NODE == node.nodeType:
    2418                  # @todo: Note that we're allowing comments inside the bodies
    2419                  # of simple content elements, which isn't really Hoyle.
    2420                  return self
    2421              if node.nodeType in (xml.dom.Node.TEXT_NODE, xml.dom.Node.CDATA_SECTION_NODE):
    2422                  value = node.data
    2423                  maybe_element = False
    2424              else:
    2425                  # Do type conversion here
    2426                  assert xml.dom.Node.ELEMENT_NODE == node.nodeType
    2427                  expanded_name = pyxb.namespace.ExpandedName(node, fallback_namespace=fallback_namespace)
    2428                  (element_binding, element_decl) = self._ElementBindingDeclForName(expanded_name)
    2429                  if element_binding is not None:
    2430                      # If we have an element binding, we need to use it because
    2431                      # it knows how to resolve substitution groups.
    2432                      value = element_binding._createFromDOM(node, expanded_name, _fallback_namespace=fallback_namespace)
    2433                  else:
    2434                      # If we don't have an element binding, we might still be
    2435                      # able to convert this if it has an xsi:type attribute
    2436                      # that names a valid type.
    2437                      xsi_type = XSI.type.getAttribute(node)
    2438                      try_create = False
    2439                      if xsi_type is not None:
    2440                          ns_ctx = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node)
    2441                          (try_create, type_class) = XSI._InterpretTypeAttribute(xsi_type, ns_ctx, fallback_namespace, None)
    2442                      if try_create:
    2443                          value = element.CreateDOMBinding(node, None, _fallback_namespace=fallback_namespace)
    2444                      else:
    2445                          _log.warning('Unable to convert DOM node %s at %s to binding', expanded_name, getattr(node, 'location', '[UNAVAILABLE]'))
    2446          if (not maybe_element) and isinstance(value, basestring) and (self._ContentTypeTag in (self._CT_EMPTY, self._CT_ELEMENT_ONLY)):
    2447              if (0 == len(value.strip())) and not self._isNil():
    2448                  return self
    2449          if maybe_element and (self.__automatonConfiguration is not None):
    2450              # Allows element content.
    2451              if not require_validation:
    2452                  if element_decl is not None:
    2453                      element_decl.setOrAppend(self, value)
    2454                      return self
    2455                  if self.__wildcardElements is not None:
    2456                      self._appendWildcardElement(value)
    2457                      return self
    2458                  raise pyxb.StructuralBadDocumentError(container=self, content=value)
    2459              # Attempt to place the value based on the content model
    2460              num_cand = self.__automatonConfiguration.step(value, element_decl)
    2461              if 1 <= num_cand:
    2462                  # Resolution was successful (possibly non-deterministic)
    2463                  return self
    2464          # We couldn't place this thing.  If it's element content, it has
    2465          # to be placed.  Is it element content?
    2466          #
    2467          # If it's bound to an element, it's element content.
    2468          #
    2469          # Complex type instance?  Element content.
    2470          #
    2471          # Uninterpretable DOM nodes or binding wrappers?  Element content.
    2472          #
    2473          # Simple type definition?  Well, if the thing we're trying to fill
    2474          # accepts mixed content or has simple content, technically we
    2475          # could convert the value to text and use it.  So that's not
    2476          # element content.
    2477          if ((element_binding is not None)
    2478              or isinstance(value, (xml.dom.Node, complexTypeDefinition, pyxb.BIND))
    2479              or (isinstance(value, simpleTypeDefinition) and not (self._IsSimpleTypeContent() or self._IsMixed()))):
    2480              # Element content.  If it has an automaton we can provide more
    2481              # information.  If it doesn't, it must consume text and we should
    2482              # use a different exception.
    2483              if self.__automatonConfiguration:
    2484                  raise pyxb.UnrecognizedContentError(self, self.__automatonConfiguration, value, location)
    2485              raise pyxb.NonElementValidationError(value, location)
    2486
    2487          # We have something that doesn't seem to be an element.  Are we
    2488          # expecting simple content?
    2489          if self._IsSimpleTypeContent():
    2490              if self.__content is not None:
    2491                  raise pyxb.ExtraSimpleContentError(self, value)
    2492              if not self._isNil():
    2493                  if not isinstance(value, self._TypeDefinition):
    2494                      value = self._TypeDefinition.Factory(value, _from_xml=from_xml)
    2495                  self.__setContent(value)
    2496                  if require_validation:
    2497                      # NB: This only validates the value, not any associated
    2498                      # attributes, which is correct to be parallel to complex
    2499                      # content validation.
    2500                      self.xsdConstraintsOK(location)
    2501              return self
    2502
    2503          # Do we allow non-element content?
    2504          if not self._IsMixed():
    2505              raise pyxb.MixedContentError(self, value, location)
    2506
    2507          # It's character information.
    2508          self._addContent(NonElementContent(value))
    2509          return self
    2510
    2511 -    def _appendWildcardElement (self, value):
    2512          self._addContent(ElementContent(value, None))
    2513          self.__wildcardElements.append(value)
    2514
    2515 -    def extend (self, value_list, _fallback_namespace=None, _from_xml=False, _location=None):
    2516          """Invoke L{append} for each value in the list, in turn."""
    2517          [ self.append(_v, _fallback_namespace=_fallback_namespace, _from_xml=_from_xml, _location=_location) for _v in value_list ]
    2518          return self
    2519
    2520 -    def __setContent (self, value):
    2521          self.__content = value
    2522          return self.__content
    2523
    2524 -    def _addContent (self, wrapped_value):
    2525          # This assert is inadequate in the case of plural/non-plural elements with an STD_list base type.
    2526          # Trust that validation elsewhere was done correctly.
    2527          #assert self._IsMixed() or (not self._performValidation()) or isinstance(child, _TypeBinding_mixin) or isinstance(child, types.StringTypes), 'Unrecognized child %s type %s' % (child, type(child))
    2528          assert not (self._ContentTypeTag in (self._CT_EMPTY, self._CT_SIMPLE))
    2529          assert isinstance(wrapped_value, _Content)
    2530          self.__content.append(wrapped_value)
    2531          if isinstance(wrapped_value, ElementContent):
    2532              value = wrapped_value.value
    2533              ed = wrapped_value.elementDeclaration
    2534              if isinstance(value, _TypeBinding_mixin) and (ed is not None) and (value._element() is None):
    2535                  assert isinstance(ed.elementBinding(), element)
    2536                  value._setElement(ed.elementBinding())
    2537
    2538      @classmethod
    2539 -    def _IsMixed (cls):
    2540          return (cls._CT_MIXED == cls._ContentTypeTag)
    2541
    2542 -    def _finalizeContentModel (self):
    2543          # Override parent implementation.
    2544          if self.__automatonConfiguration:
    2545              self.__automatonConfiguration.resolveNondeterminism()
    2546
    2547 -    def _postDOMValidate (self):
    2548          # It's probably finalized already, but just in case...
    2549          self._finalizeContentModel()
    2550          if self._validationConfig.forBinding:
    2551              # @todo isNil should verify that no content is present.
    2552              if (not self._isNil()) and (self.__automatonConfiguration is not None):
    2553                  if not self.__automatonConfiguration.isAccepting():
    2554                      if self._IsSimpleTypeContent():
    2555                          raise pyxb.SimpleContentAbsentError(self, self._location())
    2556                      self.__automatonConfiguration.diagnoseIncompleteContent()
    2557              self._validateAttributes()
    2558          return self
    2559
    2560 -    def _setDOMFromAttributes (self, dom_support, element):
    2561          """Add any appropriate attributes from this instance into the DOM element."""
    2562          for au in self._AttributeMap.itervalues():
    2563              if pyxb.GlobalValidationConfig.forDocument:
    2564                  au.validate(self)
    2565              au.addDOMAttribute(dom_support, self, element)
    2566          return element
    2567
    2568 -    def _toDOM_csc (self, dom_support, parent):
    2569          """Create a DOM element with the given tag holding the content of this instance."""
    2570          element = parent
    2571          self._setDOMFromAttributes(dom_support, element)
    2572          if self._isNil():
    2573              pass
    2574          elif self._CT_EMPTY == self._ContentTypeTag:
    2575              pass
    2576          elif self._CT_SIMPLE == self._ContentTypeTag:
    2577              if self.__content is None:
    2578                  raise pyxb.SimpleContentAbsentError(self, self._location())
    2579              dom_support.appendTextChild(self.value().xsdLiteral(), element)
    2580          else:
    2581              if pyxb.GlobalValidationConfig.forDocument:
    2582                  order = self._validatedChildren()
    2583              else:
    2584                  order = self.__childrenForDOM()
    2585              for content in order:
    2586                  assert content.value != self
    2587                  if isinstance(content, NonElementContent):
    2588                      dom_support.appendTextChild(content.value, element)
    2589                      continue
    2590                  if content.elementDeclaration is None:
    2591                      if isinstance(content.value, xml.dom.Node):
    2592                          dom_support.appendChild(content.value, element)
    2593                      else:
    2594                          content.value.toDOM(dom_support, parent)
    2595                  else:
    2596                      content.elementDeclaration.toDOM(dom_support, parent, content.value)
    2597              mixed_content = self.orderedContent()
    2598              for mc in mixed_content:
    2599                  pass
    2600          return getattr(super(complexTypeDefinition, self), '_toDOM_csc', lambda *_args,**_kw: dom_support)(dom_support, parent)
    2601
    2602      @classmethod
    2603 -    def _IsSimpleTypeContent (cls):
    2604          """CTDs with simple content are simple; other CTDs are not."""
    2605          return cls._CT_SIMPLE == cls._ContentTypeTag
    2606
    2607      @classmethod
    2608 -    def _description (cls, name_only=False, user_documentation=True):
    2609          name = cls._Name()
    2610          if name_only:
    2611              return name
    2612          desc = [ name ]
    2613          if cls._CT_EMPTY == cls._ContentTypeTag:
    2614              desc.append(', empty content')
    2615          elif cls._CT_SIMPLE == cls._ContentTypeTag:
    2616              desc.extend([', simple content type ', cls._TypeDefinition._description(name_only=True)])
    2617          else:
    2618              if cls._CT_MIXED == cls._ContentTypeTag:
    2619                  desc.append(', mixed content')
    2620              else:
    2621                  assert cls._CT_ELEMENT_ONLY == cls._ContentTypeTag
    2622                  desc.append(', element-only content')
    2623          if (0 < len(cls._AttributeMap)) or (cls._AttributeWildcard is not None):
    2624              desc.append("\nAttributes:\n  ")
    2625              desc.append("\n  ".join([ _au._description(user_documentation=False) for _au in cls._AttributeMap.itervalues() ]))
    2626              if cls._AttributeWildcard is not None:
    2627                  desc.append("\n  Wildcard attribute(s)")
    2628          if (0 < len(cls._ElementMap)) or cls._HasWildcardElement:
    2629              desc.append("\nElements:\n  ")
    2630              desc.append("\n  ".join([ _eu._description(user_documentation=False) for _eu in cls._ElementMap.itervalues() ]))
    2631              if cls._HasWildcardElement:
    2632                  desc.append("\n  Wildcard element(s)")
    2633          return ''.join(desc)
    2634
    2635  ## Local Variables:
    2636  ## fill-column:78
    2637  ## End:
    2638