1Net::XMPP::Namespaces(3Upsme)r Contributed Perl DocumentaNteito:n:XMPP::Namespaces(3pm)
2
3
4

NAME

6       Net::XMPP::Namespaces - In depth discussion on how namespaces are
7       handled
8

SYNOPSIS

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

DESCRIPTION

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

AUTHOR

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)
Impressum