1SOAP::Serializer(3) User Contributed Perl Documentation SOAP::Serializer(3)
2
3
4
6 SOAP::Serializer - the means by which the toolkit manages the expres‐
7 sion 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 creat‐
22 ing a basic object and initializing it with default values, the
23 constructor can also take names and values for most of the accessor
24 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 cre‐
30 ates the full SOAP envelope based on the input passed in to it. The
31 data arguments passed in the list of parameters to the method are
32 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 names‐
99 pace with the SOAP Envelope. The first parameter is the namespace,
100 the second parameter to this subroutine is an optional prefix. If a
101 prefix is not provided, one will be generated automatically for
102 you. All namespaces registered with the serializer get declared in
103 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 "as_MyMod‐
121 ule__MyPackage" has been defined. If so, then it will pass $foo to that
122 subroutine along with other data known about the "SOAP::Data" element
123 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 (':') substi‐
135 tuded 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 param‐
145 eter will be the "SOAP::Data" element's name, type, and attribute
146 set respectively. If on the other hand, the value/object being
147 encoded is not part of a "SOAP::Data" object, as in the code below:
148
149 $foo = MyModule::MyPackage->new;
150 my $client = SOAP::Lite
151 ->uri($NS)
152 ->proxy($HOST);
153 $som = $client->someMethod($foo);
154
155 Then the second and third parameters will be the class name of the
156 value/object being encoded (e.g. "MyModule::MyPackage" in the exam‐
157 ple above), and the fourth parameter will be an empty hash.
158
159 Output
160 The encoding subroutine must return an array containing three ele‐
161 ments: 1) the name of the XML element, 2) a hash containing the
162 attributes to be placed into the element, and 3) the value of the
163 element.
164
166 When the type of an element has not been declared explicitly,
167 SOAP::Lite must "guess" at the object's type. That is due to the fact
168 that the only form of introspection that Perl provides (through the use
169 of the "ref" subroutine) does not provide enough information to
170 "SOAP::Serializer" to allow SOAP::Lite to determine the exact type of
171 an element being serialized.
172
173 To work around this limitation, the "SOAP::Serializer::typelookup" hash
174 was created. This hash is populated with all the data types that the
175 current "SOAP::Serializer" can auto detect. Users and developers are
176 free to modify the contents of this hash allowing them to register new
177 data types with the system.
178
179 When "SOAP::Serializer" is asked to encode an object into XML, it goes
180 through the following steps. First, "SOAP::Serializer" checks to see if
181 a type has been explicitly stated for the current object. If a type has
182 been provided "SOAP::Serializer" checks to see if an "as_TypeName" sub‐
183 routine as been defined for that type. If such a subroutine exists,
184 then "SOAP::Serializer" passes the object to it to be encoded. If the
185 subroutine does not exist, or the type has not been provided, then
186 "SOAP::Serializer" must attempt to "guess" the type of the object being
187 serialized.
188
189 To do so, "SOAP::Serializer" runs in sequence a set of tests stored in
190 the "SOAP::Serializer::typelookup" hash. "SOAP::Serializer" continues
191 to run each test until one of the tests returns true, indicating that
192 the type of the object has been detected. When the type of the object
193 has been detected, then "SOAP::Serializer" passes the object to the
194 encoding subroutine that corresponds with the test that was passed. If
195 all the tests fail, and the type was not determined, then "SOAP::Seri‐
196 alizer" will as a last resort encode the object based on one of the
197 four basic data types known to Perl: REF, SCALAR, ARRAY and HASH.
198
199 The following table contains the set of data types detectable by
200 "SOAP::Lite" by default and the order in which their corresponding test
201 subroutine will be run, according to their precedence value.
202
203 Table 1 - Autotyping Precedence
204
205 TYPENAME PRECEDENCE VALUE
206 ----------------------------
207 base64 10
208 int 20
209 long 25
210 float 30
211 gMonth 35
212 gDay 40
213 gYear 45
214 gMonthDay 50
215 gYearMonth 55
216 date 60
217 time 70
218 dateTime 75
219 duration 80
220 boolean 90
221 anyURI 95
222 string 100
223
224 REGISTERING A NEW DATA TYPE
225
226 To register a new data type that can be automatically detected by
227 "SOAP::Lite" and then serialized into XML, the developer must provide
228 the following four things:
229
230 · The name of the new data type.
231
232 · A subroutine that is capable of detecting whether a value passed to
233 it is of the corresponding data type.
234
235 · A number representing the test subroutine's precedence relative to
236 all the other types' test subroutinestypes. See Table 1 - Autotyp‐
237 ing Precedence.
238
239 · A subroutine that is capable of providing "SOAP::Serializer" with
240 the information necessary to serialize an object of the correspond‐
241 ing data type into XML.
242
243 EXAMPLE 1
244
245 If, for example, you wish to create a new datatype called "uriRefer‐
246 ence" for which you would like Perl values to be automatically detected
247 and serialized into, then you follow these steps.
248
249 Step 1: Write a Test Subroutine
250
251 The test subroutine will have passed to it by "SOAP::Serializer" a
252 value to be tested. The test subroutine must return 1 if the value
253 passed to it is of the corresponding type, or else it must return 0.
254
255 sub SOAP::Serializer::uriReferenceTest {
256 my ($value) = @_;
257 return 1 if ($value =~ m!^http://!);
258 return 0;
259 }
260
261 Step 2: Write an Encoding Subroutine
262
263 The encoding subroutine provides "SOAP::Serializer" with the data nec‐
264 essary to encode the value passed to it into XML. The encoding subrou‐
265 tine name's should be of the following format: "as_"<Type Name>.
266
267 The encoding subroutine will have passed to it by "SOAP::Serializer"
268 four parameters: the value to be encoded, the name of the element being
269 encoded, the assumed type of the element being encoded, and a reference
270 to a hash containing the attributes of the element being encoded. The
271 encoding subroutine must return an array representing the encoded
272 datatype. "SOAP::Serializer" will use the contents of this array to
273 generate the corresponding XML of the value being encoded, or serial‐
274 ized. This array contains the following 3 elements: the name of the XML
275 element, a hash containing the attributes to be placed into the ele‐
276 ment, and the value of the element.
277
278 sub SOAP::Serializer::as_uriReference {
279 my $self = shift;
280 my($value, $name, $type, $attr) = @_;
281 return [$name, {'xsi:type' => 'xsd:uriReference', %$attr}, $value];
282 }
283
284 Step 3: Register the New Data Type
285
286 To register the new data type, simply add the type to the "SOAP::Seri‐
287 alizer::typelookup" hash using the type name as the key, and an array
288 containing the precedence value, the test subroutine, and the encoding
289 subroutine.
290
291 $s->typelookup->{uriReference}
292 = [11, \&uriReferenceTest, 'as_uriReference'];
293
294 Tip: As a short hand, you could just as easily use an anonymous test
295 subroutine when registering the new datatype in place of the "urlRefer‐
296 enceTest" subroutine above. For example:
297
298 $s->typelookup->{uriReference}
299 = [11, sub { $_[0] =~ m!^http://! }, 'as_uriReference'];
300
301 Once complete, "SOAP::Serializer" will be able to serialize the follow‐
302 ing "SOAP::Data" object into XML:
303
304 $elem = SOAP::Data->name("someUri" => 'http://yahoo.com')->type('uriReference');
305
306 "SOAP::Serializer" will also be able to automatically determine and
307 serialize the following untyped "SOAP::Data" object into XML:
308
309 $elem = SOAP::Data->name("someUri" => 'http://yahoo.com');
310
312 Special thanks to O'Reilly publishing which has graciously allowed
313 SOAP::Lite to republish and redistribute large excerpts from Program‐
314 ming Web Services with Perl, mainly the SOAP::Lite reference found in
315 Appendix B.
316
318 Copyright (C) 2000-2004 Paul Kulchenko. All rights reserved.
319
320 This library is free software; you can redistribute it and/or modify it
321 under the same terms as Perl itself.
322
324 Paul Kulchenko (paulclinger@yahoo.com)
325
326 Randy J. Ray (rjray@blackperl.com)
327
328 Byrne Reese (byrne@majordojo.com)
329
330
331
332perl v5.8.8 2006-06-15 SOAP::Serializer(3)