1SOAP::Serializer(3) User Contributed Perl Documentation SOAP::Serializer(3)
2
3
4
6 SOAP::Serializer - the means by which the toolkit manages the
7 expression of data as XML
8
10 The SOAP::Serializer class is the means by which the toolkit manages
11 the expression of data as XML. The object that a SOAP::Lite instance
12 uses by default is generally enough for the task, with no need for the
13 application to create its own. The main purpose of this class is to
14 provide a place for applications to extend the serializer by defining
15 additional methods for handling new datatypes.
16
18 new(optional key/value pairs)
19 $serialize = SOAP::Serializer->new( );
20
21 This is the constructor method for the class. In addition to
22 creating a basic object and initializing it with default values,
23 the constructor can also take names and values for most of the
24 accessor methods that the class supports.
25
26 envelope(method, data arguments)
27 $serialize->envelope(fault => $fault_obj);
28
29 Provides the core purpose for the SOAP::Serializer class. It
30 creates the full SOAP envelope based on the input passed in to it.
31 The data arguments passed in the list of parameters to the method
32 are divided into two sublists: any parameters that are SOAP::Header
33 objects or derivatives of go into one list, while the remainder go
34 into the other. The nonheader objects are used as the content for
35 the message body, with the body itself being largely dependent on
36 the value of the first argument in the list. This argument is
37 expected to be a string and should be one of the following:
38
39 context
40 $serialize->context->packager();
41
42 This provides access to the calling context of "SOAP::Serializer".
43 In a client side context the often means a reference to an instance
44 of SOAP::Lite. In a server side context this means a reference to a
45 SOAP::Server instance.
46
47 method
48 The envelope is being created to encapsulate a RPC-style method
49 call.
50
51 response
52 The message being created is that of a response stemming from a
53 RPC-style method call.
54
55 fault
56 For this specifier, the envelope being created is to transmit a
57 fault.
58
59 freeform
60 This identifier is used as a general-case encoding style for
61 messages that don't fit into any of the previous cases. The
62 arguments are encoded into the envelope's Body tag without any
63 sort of context sensitivity.
64
65 Any value other than these four results in an error.
66
67 envprefix(optional value)
68 $serialize->envprefix('env');
69
70 Gets or sets the prefix that labels the SOAP envelope namespace.
71 This defaults to SOAP-ENV.
72
73 encprefix(optional value)
74 $serialize->envprefix('enc');
75
76 Gets or sets the prefix that labels the SOAP encoding namespace.
77 Defaults to SOAP-ENC.
78
79 soapversion(optional value)
80 $serialize->soapversion('1.2');
81
82 If no parameter is given, returns the current version of SOAP that
83 is being used as the basis for serializing messages. If a parameter
84 is given, attempts to set that as the version of SOAP being used.
85 The value should be either 1.1 or 1.2. When the SOAP version is
86 being set, the package selects new URNs for envelope and encoding
87 spaces and also calls the xmlschema method to set the appropriate
88 schema definition.
89
90 xmlschema(optional value)
91 $serialize->xmlschema($xml_schema_1999);
92
93 Gets or sets the URN for the schema being used to express the
94 structure of the XML generated by the serializer. If setting the
95 value, the input must be the full URN for the new schema and is
96 checked against the list of known SOAP schemas.
97
98 register_ns
99 The register_ns subroutine allows users to register a global
100 namespace with the SOAP Envelope. The first parameter is the
101 namespace, the second parameter to this subroutine is an optional
102 prefix. If a prefix is not provided, one will be generated
103 automatically for you. All namespaces registered with the
104 serializer get declared in the <soap:Envelope /> element.
105
106 find_prefix
107 The find_prefix subroutine takes a namespace as a parameter and
108 returns the assigned prefix to that namespace. This eliminates the
109 need to declare and redeclare namespaces within an envelope. This
110 subroutine is especially helpful in determining the proper prefix
111 when assigning a type to a SOAP::Data element. A good example of
112 how this might be used is as follows:
113
114 SOAP::Data->name("foo" => $inputParams{'foo'})
115 ->type($client->serializer->find_prefix('urn:Foo').':Foo');
116
118 When serializing an object, or blessed hash reference, into XML,
119 "SOAP::Serializer" first checks to see if a subroutine has been defined
120 for the corresponding class name. For example, in the code below,
121 "SOAP::Serializer" will check to see if a subroutine called
122 "as_MyModule__MyPackage" has been defined. If so, then it will pass
123 $foo to that subroutine along with other data known about the
124 "SOAP::Data" element being encoded.
125
126 $foo = MyModule::MyPackage->new;
127 my $client = SOAP::Lite
128 ->uri($NS)
129 ->proxy($HOST);
130 $som = $client->someMethod(SOAP::Data->name("foo" => $foo));
131
133 Naming Convention
134 The subroutine should always be prepended with "as_" followed by
135 the type's name. The type's name must have all colons (':')
136 substituted with an underscore ('_').
137
138 Input
139 The input to "as_TypeName" will have at least one parameter, and at
140 most four parameters. The first parameter will always be the value
141 or the object to be encoded. The following three parameters depend
142 upon the context of the value/object being encoded.
143
144 If the value/object being encoded was part of a "SOAP::Data" object
145 (as in the above example), then the second, third and fourth
146 parameter will be the "SOAP::Data" element's name, type, and
147 attribute set respectively. If on the other hand, the value/object
148 being encoded is not part of a "SOAP::Data" object, as in the code
149 below:
150
151 $foo = MyModule::MyPackage->new;
152 my $client = SOAP::Lite
153 ->uri($NS)
154 ->proxy($HOST);
155 $som = $client->someMethod($foo);
156
157 Then the second and third parameters will be the class name of the
158 value/object being encoded (e.g. "MyModule::MyPackage" in the
159 example above), and the fourth parameter will be an empty hash.
160
161 Output
162 The encoding subroutine must return an array containing three
163 elements: 1) the name of the XML element, 2) a hash containing the
164 attributes to be placed into the element, and 3) the value of the
165 element.
166
168 When the type of an element has not been declared explicitly,
169 SOAP::Lite must "guess" at the object's type. That is due to the fact
170 that the only form of introspection that Perl provides (through the use
171 of the "ref" subroutine) does not provide enough information to
172 "SOAP::Serializer" to allow SOAP::Lite to determine the exact type of
173 an element being serialized.
174
175 To work around this limitation, the "SOAP::Serializer::typelookup" hash
176 was created. This hash is populated with all the data types that the
177 current "SOAP::Serializer" can auto detect. Users and developers are
178 free to modify the contents of this hash allowing them to register new
179 data types with the system.
180
181 When "SOAP::Serializer" is asked to encode an object into XML, it goes
182 through the following steps. First, "SOAP::Serializer" checks to see if
183 a type has been explicitly stated for the current object. If a type has
184 been provided "SOAP::Serializer" checks to see if an "as_TypeName"
185 subroutine as been defined for that type. If such a subroutine exists,
186 then "SOAP::Serializer" passes the object to it to be encoded. If the
187 subroutine does not exist, or the type has not been provided, then
188 "SOAP::Serializer" must attempt to "guess" the type of the object being
189 serialized.
190
191 To do so, "SOAP::Serializer" runs in sequence a set of tests stored in
192 the "SOAP::Serializer::typelookup" hash. "SOAP::Serializer" continues
193 to run each test until one of the tests returns true, indicating that
194 the type of the object has been detected. When the type of the object
195 has been detected, then "SOAP::Serializer" passes the object to the
196 encoding subroutine that corresponds with the test that was passed. If
197 all the tests fail, and the type was not determined, then
198 "SOAP::Serializer" will as a last resort encode the object based on one
199 of the four basic data types known to Perl: REF, SCALAR, ARRAY and
200 HASH.
201
202 The following table contains the set of data types detectable by
203 "SOAP::Lite" by default and the order in which their corresponding test
204 subroutine will be run, according to their precedence value.
205
206 Table 1 - Autotyping Precedence
207
208 TYPENAME PRECEDENCE VALUE
209 ----------------------------
210 base64 10
211 int 20
212 long 25
213 float 30
214 gMonth 35
215 gDay 40
216 gYear 45
217 gMonthDay 50
218 gYearMonth 55
219 date 60
220 time 70
221 dateTime 75
222 duration 80
223 boolean 90
224 anyURI 95
225 string 100
226
227 REGISTERING A NEW DATA TYPE
228 To register a new data type that can be automatically detected by
229 "SOAP::Lite" and then serialized into XML, the developer must provide
230 the following four things:
231
232 · The name of the new data type.
233
234 · A subroutine that is capable of detecting whether a value passed to
235 it is of the corresponding data type.
236
237 · A number representing the test subroutine's precedence relative to
238 all the other types' test subroutinestypes. See Table 1 -
239 Autotyping Precedence.
240
241 · A subroutine that is capable of providing "SOAP::Serializer" with
242 the information necessary to serialize an object of the
243 corresponding data type into XML.
244
245 EXAMPLE 1
246
247 If, for example, you wish to create a new datatype called
248 "uriReference" for which you would like Perl values to be automatically
249 detected and serialized into, then you follow these steps.
250
251 Step 1: Write a Test Subroutine
252
253 The test subroutine will have passed to it by "SOAP::Serializer" a
254 value to be tested. The test subroutine must return 1 if the value
255 passed to it is of the corresponding type, or else it must return 0.
256
257 sub SOAP::Serializer::uriReferenceTest {
258 my ($value) = @_;
259 return 1 if ($value =~ m!^http://!);
260 return 0;
261 }
262
263 Step 2: Write an Encoding Subroutine
264
265 The encoding subroutine provides "SOAP::Serializer" with the data
266 necessary to encode the value passed to it into XML. The encoding
267 subroutine name's should be of the following format: "as_"<Type Name>.
268
269 The encoding subroutine will have passed to it by "SOAP::Serializer"
270 four parameters: the value to be encoded, the name of the element being
271 encoded, the assumed type of the element being encoded, and a reference
272 to a hash containing the attributes of the element being encoded. The
273 encoding subroutine must return an array representing the encoded
274 datatype. "SOAP::Serializer" will use the contents of this array to
275 generate the corresponding XML of the value being encoded, or
276 serialized. This array contains the following 3 elements: the name of
277 the XML element, a hash containing the attributes to be placed into the
278 element, and the value of the element.
279
280 sub SOAP::Serializer::as_uriReference {
281 my $self = shift;
282 my($value, $name, $type, $attr) = @_;
283 return [$name, {'xsi:type' => 'xsd:uriReference', %$attr}, $value];
284 }
285
286 Step 3: Register the New Data Type
287
288 To register the new data type, simply add the type to the
289 "SOAP::Serializer::typelookup" hash using the type name as the key, and
290 an array containing the precedence value, the test subroutine, and the
291 encoding subroutine.
292
293 $s->typelookup->{uriReference}
294 = [11, \&uriReferenceTest, 'as_uriReference'];
295
296 Tip: As a short hand, you could just as easily use an anonymous test
297 subroutine when registering the new datatype in place of the
298 "urlReferenceTest" subroutine above. For example:
299
300 $s->typelookup->{uriReference}
301 = [11, sub { $_[0] =~ m!^http://! }, 'as_uriReference'];
302
303 Once complete, "SOAP::Serializer" will be able to serialize the
304 following "SOAP::Data" object into XML:
305
306 $elem = SOAP::Data->name("someUri" => 'http://yahoo.com')->type('uriReference');
307
308 "SOAP::Serializer" will also be able to automatically determine and
309 serialize the following untyped "SOAP::Data" object into XML:
310
311 $elem = SOAP::Data->name("someUri" => 'http://yahoo.com');
312
314 Special thanks to O'Reilly publishing which has graciously allowed
315 SOAP::Lite to republish and redistribute large excerpts from
316 Programming Web Services with Perl, mainly the SOAP::Lite reference
317 found in Appendix B.
318
320 Copyright (C) 2000-2004 Paul Kulchenko. All rights reserved.
321
322 This library is free software; you can redistribute it and/or modify it
323 under the same terms as Perl itself.
324
326 Paul Kulchenko (paulclinger@yahoo.com)
327
328 Randy J. Ray (rjray@blackperl.com)
329
330 Byrne Reese (byrne@majordojo.com)
331
332
333
334perl v5.32.0 2020-07-28 SOAP::Serializer(3)