Update docs for tostring
[slixmpp.git] / docs / api / xmlstream / stanzabase.rst
blobafed7655d143273654cb0a7a5ab140c9ee8808fa
1 .. _stanzabase:
3 ==========
4 stanzabase
5 ==========
7 .. module:: sleekxmpp.xmlstream.stanzabase
9 The :mod:`sleekmxpp.xmlstream.stanzabase` module provides a wrapper for the
10 standard :mod:`xml.etree.cElementTree` module that makes working with XML
11 less painful. Instead of having to manually move up and down an element
12 tree and insert subelements and attributes, you can interact with an object
13 that behaves like a normal dictionary or JSON object, which silently maps
14 keys to XML attributes and elements behind the scenes.
16 Overview
17 --------
19 The usefulness of this layer grows as the XML you have to work with
20 becomes nested. The base unit here, :class:`ElementBase`, can map to a
21 single XML element, or several depending on how advanced of a mapping
22 is desired from interface keys to XML structures. For example, a single
23 :class:`ElementBase` derived class could easily describe:
25 .. code-block:: xml
27     <message to="user@example.com" from="friend@example.com">
28       <body>Hi!</body>
29       <x:extra>
30         <x:item>Custom item 1</x:item>
31         <x:item>Custom item 2</x:item>
32         <x:item>Custom item 3</x:item>
33       </x:extra>
34     </message>
36 If that chunk of XML were put in the :class:`ElementBase` instance
37 ``msg``, we could extract the data from the XML using::
39     >>> msg['extra']
40     ['Custom item 1', 'Custom item 2', 'Custom item 3']
42 Provided we set up the handler for the ``'extra'`` interface to load the
43 ``<x:item>`` element content into a list.
45 The key concept is that given an XML structure that will be repeatedly
46 used, we can define a set of :term:`interfaces` which when we read from,
47 write to, or delete, will automatically manipulate the underlying XML
48 as needed. In addition, some of these interfaces may in turn reference
49 child objects which expose interfaces for particularly complex child
50 elements of the original XML chunk.
52 .. seealso::
53     :ref:`create-stanza-interfaces`.
55 Because the :mod:`sleekxmpp.xmlstream.stanzabase` module was developed
56 as part of an `XMPP <http://xmpp.org>`_ library, these chunks of XML are
57 referred to as :term:`stanzas <stanza>`, and in SleekXMPP we refer to a
58 subclass of :class:`ElementBase` which defines the interfaces needed for
59 interacting with a given :term:`stanza` a :term:`stanza object`.
61 To make dealing with more complicated and nested :term:`stanzas <stanza>`
62 or XML chunks easier, :term:`stanza objects <stanza object>` can be
63 composed in two ways: as iterable child objects or as plugins. Iterable
64 child stanzas, or :term:`substanzas`, are accessible through a special
65 ``'substanzas'`` interface. This option is useful for stanzas which
66 may contain more than one of the same kind of element. When there is
67 only one child element, the plugin method is more useful. For plugins,
68 a parent stanza object delegates one of its XML child elements to the
69 plugin stanza object. Here is an example:
71 .. code-block:: xml
73     <iq type="result">
74       <query xmlns="http://jabber.org/protocol/disco#info">
75         <identity category="client" type="bot" name="SleekXMPP Bot" />
76       </query>
77     </iq>
79 We can can arrange this stanza into two objects: an outer, wrapper object for
80 dealing with the ``<iq />`` element and its attributes, and a plugin object to
81 control the ``<query />`` payload element. If we give the plugin object the
82 name ``'disco_info'`` (using its :attr:`ElementBase.plugin_attrib` value), then
83 we can access the plugin as so::
85     >>> iq['disco_info']
86     '<query xmlns="http://jabber.org/protocol/disco#info">
87       <identity category="client" type="bot" name="SleekXMPP Bot" />
88     </query>'
90 We can then drill down through the plugin object's interfaces as desired::
92     >>> iq['disco_info']['identities']
93     [('client', 'bot', 'SleekXMPP Bot')]
95 Plugins may also add new interfaces to the parent stanza object as if they
96 had been defined by the parent directly, and can also override the behaviour
97 of an interface defined by the parent.
99 .. seealso::
101     - :ref:`create-stanza-plugins`
102     - :ref:`create-extension-plugins`
103     - :ref:`override-parent-interfaces`
104      
106 Registering Stanza Plugins
107 --------------------------
109 .. autofunction:: register_stanza_plugin
111 ElementBase
112 -----------
114 .. autoclass:: ElementBase
115     :members:
116     :private-members:
117     :special-members:
119 StanzaBase
120 ----------
122 .. autoclass:: StanzaBase
123     :members: