1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 """General base classes for PyXMPP objects."""
20
21 __revision__="$Id: objects.py 714 2010-04-05 10:20:10Z jajcus $"
22 __docformat__="restructuredtext en"
23
24 import libxml2
25 from pyxmpp.xmlextra import common_doc
26
28 """Base class for objects that may be used as XMPP stanza payload and don't keep
29 internal XML representation, only parsed values.
30
31 Provides `as_xml` method. Derived classes must override `xml_element_name` and
32 `xml_element_namespace` class attributes and the `complete_xml_element` method.
33
34 Please note that not all classes derived from `StanzaPayloadObject` should be
35 used directly as stanza payload. Some of them are parts of higher level objects.
36
37 :Cvariables:
38 - `xml_element_name`: name for the XML element provided by the class.
39 - `xml_element_namespace`: namespace URI for the XML element provided
40 by the class.
41 :Types:
42 - `xml_element_name`: `unicode`
43 - `xml_element_namespace`: `unicode`
44 """
45 xml_element_name = None
46 xml_element_namespace = None
47
48 - def as_xml(self, parent = None, doc = None):
49 """Get the XML representation of `self`.
50
51 New document will be created if no `parent` and no `doc` is given.
52
53 :Parameters:
54 - `parent`: the parent for the XML element.
55 - `doc`: the document where the element should be created. If not
56 given and `parent` is provided then autodetection is attempted.
57 If that fails, then `common_doc` is used.
58 :Types:
59 - `parent`: `libxml2.xmlNode`
60 - `doc`: `libxml2.xmlDoc`
61 :return: the new XML element or document created.
62 :returntype: `libxml2.xmlNode` or `libxml2.xmlDoc`"""
63 if parent:
64 if not doc:
65 n = parent
66 while n:
67 if n.type == "xml_document":
68 doc = n
69 break
70 n = n.parent
71 if not doc:
72 doc = common_doc
73 try:
74 ns = parent.searchNsByHref(doc, self.xml_element_namespace)
75 except libxml2.treeError:
76 ns = None
77 xmlnode = parent.newChild(ns,self.xml_element_name,None)
78 if not ns:
79 ns = xmlnode.newNs(self.xml_element_namespace,None)
80 xmlnode.setNs(ns)
81 doc1 = doc
82 else:
83 if doc:
84 doc1 = doc
85 else:
86 doc1 = libxml2.newDoc("1.0")
87 xmlnode = doc1.newChild(None,self.xml_element_name, None)
88 ns = xmlnode.newNs(self.xml_element_namespace, None)
89 xmlnode.setNs(ns)
90
91 self.complete_xml_element(xmlnode, doc1)
92
93 if doc or parent:
94 return xmlnode
95 doc1.setRootElement(xmlnode)
96 return doc1
97
99 """Complete the XML node with `self` content.
100
101 Should be overriden in classes derived from `StanzaPayloadObject`.
102
103 :Parameters:
104 - `xmlnode`: XML node with the element being built. It has already
105 right name and namespace, but no attributes or content.
106 - `doc`: document to which the element belongs.
107 :Types:
108 - `xmlnode`: `libxml2.xmlNode`
109 - `doc`: `libxml2.xmlDoc`"""
110 pass
111
113 """Base class for objects that may be used as XMPP stanza payload and maintain
114 an internal XML representation of self.
115
116 Provides `as_xml` method. Objects of derived classes must have the `xmlnode` attribute.
117
118 Please note that not all classes derived from `StanzaPayloadWrapperObject` should be
119 used directly as stanza payload. Some of them are parts of higher level objects.
120
121 :Ivariables:
122 - `xmlnode`: XML node of the object.
123 :Types:
124 - `xmlnode`: `libxml2.xmlNode`
125 """
126
127 - def as_xml(self, parent = None, doc = None):
128 """Get the XML representation of `self`.
129
130 New document will be created if no `parent` and no `doc` is given.
131
132 :Parameters:
133 - `parent`: the parent for the XML element.
134 - `doc`: the document where the element should be created. If not
135 given and `parent` is provided then autodetection is attempted.
136 If that fails, then `common_doc` is used.
137 :Types:
138 - `parent`: `libxml2.xmlNode`
139 - `doc`: `libxml2.xmlDoc`
140
141 :return: the new XML element (copy of `self.xmlnode`) or document
142 created (containg the copy as the root element).
143 :returntype: `libxml2.xmlNode` or `libxml2.xmlDoc`"""
144 if parent:
145 if not doc:
146 n = parent
147 while n:
148 if n.type == "xml_document":
149 doc = n
150 break
151 n = n.parent
152 if not doc:
153 doc = common_doc
154 copy=self.xmlnode.docCopyNode(doc,True)
155 parent.addChild(copy)
156 return copy
157 else:
158 if not doc:
159 doc1=libxml2.newDoc("1.0")
160 else:
161 doc1=doc
162 xmlnode=doc1.addChild(self.xmlnode.docCopyNode(doc,True))
163 doc1.setRootElement(xmlnode)
164 if doc:
165 return xmlnode
166 return doc1
167
168
169