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