1Net::XMPP::Namespaces(3U)ser Contributed Perl DocumentatiNoent::XMPP::Namespaces(3)
2
3
4
6 Net::XMPP::Namespaces - In depth discussion on how namespaces are han‐
7 dled
8
10 Net::XMPP::Namespaces provides an depth look at how Net::XMPP handles
11 namespacs, and how to add your own custom ones. It also serves as the
12 storage bin for all of the Namespace information Net::XMPP requires.
13
15 XMPP as a protocol is very well defined. There are three main top
16 level packets (message, iq, and presence). There is also a way to
17 extend the protocol in a very clear and strucutred way, via namespaces.
18
19 Two major ways that namespaces are used in Jabber is for making the
20 <iq/> a generic wrapper, and as a way for adding data to any packet via
21 a child tag <x/>. We will use <x/> to represent the packet, but in
22 reality it could be any child tag: <foo/>, <data/>, <error/>, etc.
23
24 The Info/Query <iq/> packet uses namespaces to determine the type of
25 information to access. Usually there is a <query/> tag in the <iq/>
26 that represents the namespace, but in fact it can be any tag. The
27 definition of the Query portion, is the first tag that has a namespace.
28
29 <iq type="get"><query xmlns="..."/></iq>
30
31 or
32
33 <iq type="get"><foo xmlns="..."/></iq>
34
35 After that Query stanza can be any number of other stanzas (<x/> tags)
36 you want to include. The Query packet is represented and available by
37 calling GetQuery() or GetChild(), and the other namespaces are
38 available by calling GetChild().
39
40 The X tag is just a way to piggy back data on other packets. Like
41 embedding the timestamp for a message using jabber:x:delay, or signing
42 you presence for encryption using jabber:x:signed.
43
44 To this end, Net::XMPP has sought to find a way to easily, and clearly
45 define the functions needed to access the XML for a namespace. We will
46 go over the full docs, and then show two examples of real namespaces so
47 that you can see what we are talking about.
48
49 Overview
50
51 To avoid a lot of nasty modules populating memory that are not used,
52 and to avoid having to change 15 modules when a minor change is
53 introduced, the Net::XMPP modules have taken AUTOLOADing to the
54 extreme. Namespaces.pm is nothing but a set of function calls that
55 generates a big hash of hashes. The hash is accessed by the Stanza.pm
56 AUTOLOAD function to do something. (This will make sense, I promise.)
57
58 Before going on, I highly suggest you read a Perl book on AUTOLOAD and
59 how it works. From this point on I will assume that you understand it.
60
61 When you create a Net::XMPP::IQ object and add a Query to it (NewChild)
62 several things are happening in the background. The argument to
63 NewChild is the namespace you want to add. (custom-namespace)
64
65 Now that you have a Query object to work with you will call the GetXXX
66 functions, and SetXXX functions to set the data. There are no defined
67 GetXXX and SetXXXX functions. You cannot look in the Namespaces.pm
68 file and find them. Instead you will find something like this:
69
70 &add_ns(ns => "mynamespace",
71 tag => "mytag",
72 xpath => {
73 JID => { type=>'jid', path => '@jid' },
74 Username => { path => 'username/text()' },
75 Test => { type => 'master' }
76 }
77 );
78
79 When the GetUsername() function is called, the AUTOLOAD function looks
80 in the Namespaces.pm hash for a "Username" key. Based on the "type" of
81 the field (scalar being the default) it will use the "path" as an XPath
82 to retrieve the data and call the XPathGet() method in Stanza.pm.
83
84 Confused yet?
85
86 Net::XMPP private namespaces
87
88 Now this is where this starts to get a little sticky. When you see a
89 namespace with __netxmpp__, or __netjabber__ from Net::Jabber, at the
90 beginning it is usually something custom to Net::XMPP and NOT part of
91 the actual XMPP protocol.
92
93 There are some places where the structure of the XML allows for
94 multiple children with the same name. The main places you will see
95 this behavior is where you have multiple tags with the same name and
96 those have children under them (jabber:iq:roster).
97
98 In jabber:iq:roster, the <item/> tag can be repeated multiple times,
99 and is sort of like a mini-namespace in itself. To that end, we treat
100 it like a seperate namespace and defined a __netxmpp__:iq:roster:item
101 namespace to hold it. What happens is this, in my code I define that
102 the <item/>s tag is "item" and anything with that tag name is to create
103 a new Net::XMPP::Stanza object with the namespace
104 __netxmpp__:iq:roster:item which then becomes a child of the
105 jabber:iq:roster Stanza object. Also, when you want to add a new item
106 to a jabber:iq:roster project you call NewQuery with the private
107 namespace.
108
109 I know this sounds complicated. And if after reading this entire
110 document it is still complicated, email me, ask questions, and I will
111 monitor it and adjust these docs to answer the questions that people
112 ask.
113
114 add_ns()
115
116 To repeat, here is an example call to add_ns():
117
118 &add_ns(ns => "mynamespace",
119 tag => "mytag",
120 xpath => {
121 JID => { type=>'jid', path => '@jid' },
122 Username => { path => 'username/text()' },
123 Test => { type => 'master' }
124 }
125 );
126
127 ns - This is the new namespace that you are trying to add.
128
129 tag - This is the root tag to use for objects based on this namespace.
130
131 xpath - The hash reference passed in the add_ns call to each name of
132 entry tells Net::XMPP how to handle subsequent GetXXXX(), SetXXXX(),
133 DefinedXXXX(), RemoveXXXX(), AddXXXX() calls. The basic options you
134 can pass in are:
135
136 type - This tells Stanza how to handle the call. The possible
137 values are:
138
139 array - The value to set and returned is an an array
140 reference. For example, <group/> in jabber:iq:roster.
141
142 child - This tells Stanza that it needs to look for the
143 __netxmpp__ style namesapced children. AddXXX() adds
144 a new child, and GetXXX() will return a new Stanza
145 object representing the packet.
146
147 flag - This is for child elements that are tags by themselves:
148 <foo/>. Since the presence of the tag is what is
149 important, and there is no cdata to store, we just call
150 it a flag.
151
152 jid - The value is a Jabber ID. GetXXX() will return a
153 Net::XMPP::JID object unless you pass it "jid", then it
154 returns a string.
155
156 master - The GetXXX() and SetXXX() calls return and take a
157 hash representing all of the GetXXX() and SetXXX()
158 calls. For example:
159
160 SetTest(foo=>"bar",
161 bar=>"baz");
162
163 Translates into:
164
165 SetFoo("bar");
166 SetBar("baz");
167
168 GetTest() would return a hash containing what the
169 packet contains:
170
171 { foo=>"bar", bar=>"baz" }
172
173 raw - This will stick whatever raw XML you specify directly
174 into the Stanza at the point where the path specifies.
175
176 scalar - This will set and get a scalar value. This is the
177 main workhorse as attributes and CDATA is represented
178 by a scalar. This is the default setting if you do
179 not provide one.
180
181 special - The special type is unique in that instead of a
182 string "special", you actually give it an array:
183
184 [ "special" , <subtype> ]
185
186 This allows Net::XMPP to be able to handle the
187 SetXXXX() call in a special manner according to your
188 choosing. Right now this is mainly used by
189 jabber:iq:time to automatically set the time info in
190 the correct format, and jabber:iq:version to set the
191 machine OS and add the Net::Jabber version to the
192 return packet. You will likely NOT need to use
193 this, but I wanted to mention it.
194
195 timestamp - If you call SetXXX() but do not pass it anything,
196 or pass it "", then Net::XMPP will place a
197 timestamp in the xpath location.
198
199 path - This is the XPath path to where the bit data lives. The
200 difference. Now, this is not full XPath due to the nature
201 of how it gets used. Instead of providing a rooted path
202 all the way to the top, it's a relative path ignoring what
203 the parent is. For example, if the "tag" you specified was
204 "foo", and the path is "bar/text()", then the XPath will be
205 rooted in the XML of the <foo/> packet. It will set and get
206 the CDATA from:
207
208 <foo><bar>xxxxx</bar></foo>
209
210 For a flag and a child type, just specify the child element.
211 Take a look at the code in this file for more help on what
212 this means. Also, read up on XPath if you don't already know
213 what it is.
214
215 child - This is a hash reference that tells Net::XMPP how to handle
216 adding and getting child objects. The keys for the hash are
217 as follows:
218
219 ns - the real or custom (__netxmpp__) namesapce to use for
220 this child packet.
221
222 skip_xmlns => 1 - this tells Net::XMPP not to add an
223 xmlns='' into the XML for the child
224 object.
225
226 specify_name => 1 - allows you to call NewChild("ns","tag")
227 and specify the tag to use for the child
228 object. This, IMHO, is BAD XML
229 practice. You should always know what
230 the tag of the child is and use an
231 attribute or CDATA to change the type
232 of the stanza. You do not want to use
233 this.
234
235 tag - If you use specify_name, then this is the default tag
236 to use. You do not want to use this.
237
238 calls - Array reference telling Net::XMPP what functions to create
239 for this name. For most of the types above you will get
240 Get, Set, Defined, and Remove. For child types you need to
241 decide how you API will look and specify them yourself:
242
243 ["Get","Defined"]
244 ["Add"]
245 ["Get","Add","Defined"]
246
247 It all depends on how you want your API to look.
248
249 Once more... The following:
250
251 &add_ns(ns => "mynamespace",
252 tag => "mytag",
253 xpath => {
254 JID => { type=>'jid', path => '@jid' },
255 Username => { path => 'username/text()' },
256 Test => { type => 'master' }
257 }
258 );
259
260 generates the following API calls:
261
262 GetJID()
263 SetJID()
264 DefinedJID()
265 RemoveJID()
266 GetUsername()
267 SetUsername()
268 DefinedUsername()
269 RemoveUsername()
270 GetTest()
271 SetTest()
272
273 Wrap Up
274
275 Well. I hope that I have not scared you off from writing a custom
276 namespace for you application and use Net::XMPP. Look in the
277 Net::XMPP::Protocol manpage for an example on using the add_ns()
278 function to register your custom namespace so that Net::XMPP can
279 properly handle it.
280
282 Ryan Eatmon
283
285 This module is free software, you can redistribute it and/or modify it
286 under the LGPL.
287
288
289
290perl v5.8.8 2007-04-02 Net::XMPP::Namespaces(3)