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