.. _contentModel:

Content Model
=============

PyXB's content model is used to complete the link between the
:ref:`componentModel` and the :ref:`bindingModel`.  These classes are the
ones that:

- determine what Python class attribute is used to store which XML
  element or attribute; 
- distinguish those elements that can occur at most once from those that
  require an aggregation; and
- ensure that the ordering and occurrence constraints imposed by the XML
  `model group <http://www.w3.org/TR/xmlschema-1/#Model_Groups>`_ are
  satisfied, when XML is converted to Python instances and vice-versa.

Associating XML and Python Objects
----------------------------------

The classes involved in the content model are in the
:api:`pyxb.binding.content` module.  Their relationships to binding classes
are displayed in the following diagram.

.. image:: Images/ContentBindingRelations.jpg

In the standard code generation template, both element and attribute values
are stored in Python class fields.  As noted in
:ref:`binding_deconflictingNames` it is necessary to ensure an attribute and
an element which have the same name in their containing complex type have
distinct names in the Python class corresponding to that type.  Use
information for each of these is maintained in the type class.  This use
information comprises:

- the original :api:`name <pyxb.binding.content.AttributeUse.name>` of the element/attribute in the XML
- its :api:`deconflicted name <pyxb.binding.content.AttributeUse.id>` in Python
- the private name by which the value is stored in the Python instance dictionary

Other information is specific to the type of use.  The
:api:`pyxb.binding.basis.complexTypeDefinition` retains maps from the
component's name the attribute use or element use instance corresponding to
the component's use.

.. _attributeUse:

Attribute Uses
^^^^^^^^^^^^^^

The information associated with an `attribute use
<http://www.w3.org/TR/xmlschema-1/#cAttributeUse>`_ is recorded in an
:api:`pyxb.binding.content.AttributeUse` instance.  This class provides:

- The :api:`type <pyxb.binding.content.AttributeUse.dataType>` of the
  attribute, as a subclass of :api:`pyxb.binding.basis.simpleTypeDefinition`

- The :api:`default value <pyxb.binding.content.AttributeUse.defaultValue>` of
  the attribute

- Whether the `attribute use
  <http://www.w3.org/TR/xmlschema-1/#cAttributeUse>`_ is 
  :api:`required <pyxb.binding.content.AttributeUse.required>`
  or :api:`prohibited <pyxb.binding.content.AttributeUse.prohibited>`

- Whether the value of the attribute in a binding instance was :api:`provided
  <pyxb.binding.content.AttributeUse.provided>` by an external source or set
  to the default value

- Whether the attribute value is :api:`fixed <pyxb.binding.content.AttributeUse.fixed>`

- Methods to :api:`read <pyxb.binding.content.AttributeUse.value>`, :api:`set
  <pyxb.binding.content.AttributeUse.set>`, and :api:`reset
  <pyxb.binding.content.AttributeUse.reset>` the value of the attribute in a
  given binding instance.

A :api:`map <pyxb.binding.basis.complexTypeDefinition._AttributeMap>` is used
to map from expanded names to AttributeUse instances.  This map is defined
within the class definition itself.

.. _elementUse:

Element Uses
^^^^^^^^^^^^

The element analog to an attribute use is an `element declaration
<http://www.w3.org/TR/xmlschema-1/#cElement_Declarations>`_, and the
corresponding information is stored in a
:api:`pyxb.binding.content.ElementUse` instance.  This class provides:

- The :api:`element binding <pyxb.binding.content.ElementUse.elementBinding>`
  that defines the properties of the referenced element, including its type

- Whether the use allows :api:`multiple occurrences
  <pyxb.binding.content.ElementUse.isPlural>`

- The :api:`default value <pyxb.binding.content.ElementUse.defaultValue>` of
  the element.  Currently this is either C{None} or an empty list, depending
  on :api:`pyxb.binding.content.ElementUse.isPlural`

- Methods to :api:`read <pyxb.binding.content.ElementUse.value>`, :api:`set
  <pyxb.binding.content.ElementUse.set>`, :api:`append to
  <pyxb.binding.content.ElementUse.append>` (only for plural elements), and
  :api:`reset <pyxb.binding.content.ElementUse.reset>` the value of the
  element in a given binding instance

- The :api:`setOrAppend <pyxb.binding.content.ElementUse.setOrAppend>` method,
  which is most commonly used to provide new content to a value

A :api:`map <pyxb.binding.basis.complexTypeDefinition._ElementMap>` is used to
map from expanded names to ElementUse instances.  This map is defined within
the class definition itself.

Content Model Description
-------------------------

The relations among the classes defining the content model are displayed in
the following diagram.

.. image:: Images/ContentModel.jpg

Each complex type binding class has a :api:`_ContentModel
<pyxb.binding.content.ParticleModel>` which defines constraints on the content
of an instance of the class.  The content model includes occurrence
constraints and information on subterms, which either XML `model groups
<http://www.w3.org/TR/xmlschema-1/#Model_Groups>`_  or element uses.

See the :api:`validation method <pyxb.binding.content.ParticleModel.validate>`
for details on how all this really works.

.. ignored
   ## Local Variables:
   ## fill-column:78
   ## indent-tabs-mode:nil
   ## End:

