:mod:`dip.io.codecs.xml`
========================
.. module:: dip.io.codecs.xml

The :mod:`dip.io.codecs.xml` module implements support for XML encoders and
decoders used with :term:`streaming storage`.


:class:`IXmlDecoder`
--------------------
.. class:: IXmlDecoder

    Base class: :class:`~dip.model.Interface`

    The IXmlDecoder interface defines the interface to be implemented by
    models being decoded by the :class:`~dip.io.codecs.XmlCodec` codec.


:class:`IXmlEncoder`
--------------------
.. class:: IXmlEncoder

    Base class: :class:`~dip.model.Interface`

    The IXmlEncoder interface defines the interface to be implemented by
    models being encoded by the :class:`~dip.io.codecs.XmlCodec` codec.


:class:`XmlCodec`
-----------------
.. class:: XmlCodec

    Base class: :class:`~dip.model.Model`

    The XmlCodec class implements a codec that decodes and encodes
    instances of :class:`~dip.model.Model` as XML.  The codec does not set the
    :attr:`~dip.io.ICodec.format` attribute.  This should be defined in a
    sub-class or passed as an argument when the codec is created.

    .. attribute:: decoder = Any()

        The decoder itself.  It must have a ``decode`` method with the same
        signature as the :class:`~dip.io.ICodec.decode` method.

    .. attribute:: decoder_interface = IXmlDecoder

        The decoder interface.

    .. attribute:: encoder = Any()

        The encoder itself.  It must have a ``decode`` method with the same
        signature as the :class:`~dip.io.ICodec.encode` method.

    .. attribute:: encoder_interface = IXmlEncoder

        The encoder interface.

    .. method:: XmlCodec.decode(model, source, location)

        A model is decoded from a byte stream.
        
        :param model:
            is the model.
        :param source:
            is an iterator that will return the byte stream to be decoded.
        :param location:
            is the storage location where the encoded model is being read from.
            It is mainly used for error reporting.
        :return:
            the decoded model.  This may be the original model populated from
            the storage location, or it may be a different model (of an
            appropriate type) created from the storage location.

    .. method:: XmlCodec.encode(model, location)

        A model is encoded as a byte stream.
        
        :param model:
            is the model.
        :param location:
            is the storage location where the encoded model will be written to.
            It is mainly used for error reporting.
        :return:
            a generator that will return sections of the encoded byte stream.


:class:`XmlDecoder`
-------------------
.. class:: XmlDecoder

    Base class: :class:`~dip.model.Model`

    The XmlDecoder class implements a model decoder that decodes a
    :class:`~dip.model.Model` instance from XML.

    .. attribute:: format = Str()

        The identifier of the format.

    .. method:: XmlDecoder.decode(model, source, location)

        A model is decoded from an XML byte stream.
        
        :param model:
            is the model to populate from the decoded byte stream.
        :param source:
            is an iterator that will return the byte stream to be decoded.
        :param location:
            is the storage location where the encoded model is being read from.
            It is mainly used for error reporting.
        :return:
            the decoded model.

    .. method:: XmlDecoder.decode_attribute(model, model_types, reader, source, location)

        Decode the current element as an attribute.
        
        :param model:
            is the model to populate from the decoded byte stream.
        :param model_types:
            is the dict of the model's types.
        :param reader:
            is the :class:`~PyQt4.QtCore.QXmlStreamReader` instance.
        :param source:
            is an iterator that will return the byte stream to be decoded.
        :param location:
            is the storage location where the encoded model is being read from.
            It is mainly used for error reporting.

    .. method:: XmlDecoder.decode_document_element(model, reader, location)

        Decode the document element (i.e. the outermost element).
        
        :param model:
            is the model to populate from the decoded byte stream.
        :param reader:
            is the :class:`~PyQt4.QtCore.QXmlStreamReader` instance.
        :param location:
            is the storage location where the encoded model is being read from.
            It is mainly used for error reporting.

    .. method:: XmlDecoder.decode_model(model, reader, source, location)

        Decode the next element as a model.
        
        :param model:
            is the model to populate from the decoded byte stream.
        :param reader:
            is the :class:`~PyQt4.QtCore.QXmlStreamReader` instance.
        :param source:
            is an iterator that will return the byte stream to be decoded.
        :param location:
            is the storage location where the encoded model is being read
            from.  It is mainly used for error reporting.


:class:`XmlEncoder`
-------------------
.. class:: XmlEncoder

    Base class: :class:`~dip.model.Model`

    The XmlEncoder class implements a model encoder that encodes a
    :class:`~dip.model.Model` instance as XML.
    
    Note that, by default, pickle is used to encode any attributes that don't
    have a value corresponding to a fundamental Python type (i.e.
    :class:`~dip.model.Int`, :class:`~dip.model.List` etc.).  It is
    recommended (but not required) that the model is defined fully in terms of
    these fundamental types or that the encoder is sub-classed to handle
    attributes with non-fundamental types explicitly.

    .. attribute:: declaration = Str('<?xml version="1.0" encoding="UTF-8"?>')

        The XML declaration.

    .. attribute:: document_start = Str()

        The text to open the outermost element.

    .. attribute:: document_end = Str('</DipModel>')

        The text to close the outermost element.

    .. attribute:: encoding = Str('utf8')

        The encoding to use.

    .. attribute:: exclude = List(Str())

        The list of names of attributes to exclude.

    .. attribute:: format = Str()

        The identifier of the format.

    .. attribute:: include = List(Str())

        The list of names of attributes to include.  If this is empty then all
        attributes are included unless they have been explicitly excluded.

    .. attribute:: indentation_spaces = Int(2)

        The number of spaces used for a single level of indentation.

    .. method:: XmlEncoder.encode(model, location)

        A model is encoded as an XML byte stream.
        
        :param model:
            is the model to encode.
        :param location:
            is the storage location where the encoded model will be written to.
            It is mainly used for error reporting.
        :return:
            the next section of the encoded XML byte stream.

    .. method:: XmlEncoder.encode_attribute(model, name, value, attribute_type, location, indent_level)

        A single attribute is encoded as an XML byte stream.
        
        :param model:
            is the model containing the attribute to encode.
        :param name:
            is the name of the attribute.  It may be '' if the value is a
            member of a collection attribute.
        :param value:
            is the value of the attribute.
        :param attribute_type:
            is the type of the attribute.
        :param location:
            is the storage location where the encoded attribute will be
            written to.  It is mainly used for error reporting.
        :param indent_level:
            is the current indentation level as a number.
        :return:
            the next section of the encoded XML byte stream.

    .. method:: XmlEncoder.encode_model(model, location, indent_level)

        A model is encoded as an XML byte stream.
        
        :param model:
            is the model to encode.
        :param location:
            is the storage location where the encoded model will be written
            to.  It is mainly used for error reporting.
        :param indent_level:
            is the current indentation level as a number.

    .. staticmethod:: XmlEncoder.escape(value)

        Replace any characters with their corresponding entities.
        
        :param value:
            is the string to escape.
        :return:
            the escaped string.

    .. method:: XmlEncoder.indentation(indent_level)

        Return a string that will indent a line to a particular level.
        
        :param indent_level:
            is the indentation level as a number.
        :return:
            the string.
