File Coverage

blib/lib/SOAP/Message.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package SOAP::Message;
2              
3             require 5;
4 1     1   35580 use strict;
  1         3  
  1         48  
5              
6 1     1   6 use vars qw($VERSION);
  1         2  
  1         59  
7 1     1   7484 use XML::XPath;
  0            
  0            
8             use XML::XPath::XMLParser;
9              
10             $VERSION = '0.01';
11              
12             =head1 NAME
13              
14             SOAP::Message - Really simple SOAP
15              
16             =head1 DESCRIPTION
17              
18             Simple SOAP for the unwashed masses
19              
20             =head1 SYNOPSIS
21              
22             use SOAP::Message;
23              
24             ## Procedural interface
25              
26             # Make SOAP
27            
28             my $message = SOAP::Message::create(
29            
30             version => '1.1',
31             body => $xml_data,
32            
33             );
34            
35             # Receive SOAP
36            
37             my ( $header,$body ) = SOAP::Message::parse( $incoming );
38              
39             ## OO interface
40            
41             # Set some defaults up...
42            
43             my $object = SOAP::Message->new( version => '1.2', prefix => 'SOAP' );
44              
45             # Then just continue as normal...
46            
47             my $message = $object->create( body => $body, header => $header );
48            
49             # And for convenience...
50            
51             my ( $header, $body ) = $object->parse( $incoming );
52              
53             =head1 OVERVIEW
54              
55             90% of using SOAP appears to be jumping through many hoops to do something
56             pretty simple - putting an XML wrapper around another piece of XML, or removing
57             the XML wrapper around a piece of XML.
58              
59             That's all this package does. And not particularly cleverly. And that's all it
60             wants to do. Chances are it handles everything you need it to.
61              
62             =head1 METHODS
63              
64             =head2 create
65              
66             Creates a new SOAP message. Accepts:
67              
68             B - which can either be C<1.1> or C<1.2>. Defaults to C<1.1>. This affects what the namespace will be:
69              
70             http://schemas.xmlsoap.org/soap/envelope/ - 1.1
71             http://www.w3.org/2003/05/soap-envelope - 1.2
72              
73             Optional.
74              
75             B - which is the message body, and can be anything you fancy. Optional.
76              
77             B
- which is the header, and can be anything you want. Optional.
78              
79             B - which is the prefix we use. Defaults to 'env'. Common examples
80             C, C, C and so on. Optional. We don't perform any validation
81             on this.
82              
83             Returns a string containing your SOAP message.
84              
85             =cut
86              
87              
88             sub create {
89            
90             my $self = shift;
91            
92             my %options;
93              
94             # Check here to see if we're being called as OO. If the first argument
95             # is a ref, assume it's an object, and load up the defaults, then any
96             # arguments to this function. If it's not, stick it back on the list
97             # passed to the function, and use that list as our options.
98            
99             if ( ref( $self ) ) {
100            
101             %options = (%$self, @_);
102            
103             } else {
104            
105             %options = ($self, @_);
106            
107             }
108            
109             # Default the prefix ( )
110            
111             my $prefix = $options{'prefix'} || 'env';
112             $options{'header'} = '' unless $options{'header'};
113             $options{'body'} = '' unless $options{'body'};
114              
115             # Work out the correct namespace
116            
117             $options{'version'} = '1.1' unless $options{'version'};
118            
119             my $namespace = "http://schemas.xmlsoap.org/soap/envelope/";
120            
121             if ( $options{'version'} eq '1.2' ) {
122            
123             $namespace = "http://www.w3.org/2003/05/soap-envelope";
124            
125             }
126              
127             # That's all folks!
128              
129             return qq!
130             <$prefix:Envelope xmlns:$prefix = "$namespace">
131             <$prefix:Header>! . $options{'header'} . qq!
132             <$prefix:Body>! . $options{'body'} . qq!
133            
134             !;
135            
136             }
137              
138             =head2 parse
139              
140             Parses a SOAP message in a string. Returns a list containing the
141             header and the body as strings.
142              
143             =cut
144              
145             sub parse {
146              
147             my $data = shift;
148            
149             # This method isn't enhanced by OO, so if the first argument was a ref,
150             # silently drop it and grab the next.
151            
152             $data = shift if ref( $data ); # Handle OO calls
153            
154             # Open up our parser...
155            
156             my $xp = XML::XPath->new( xml => $data );
157            
158             # This means that when the namespace is set to X, we can assume the prefix
159             # is going to be Y... This simplifies our XPath expressions a little.
160            
161             $xp->set_namespace( ver1 => 'http://schemas.xmlsoap.org/soap/envelope/');
162             $xp->set_namespace( ver2 => 'http://www.w3.org/2003/05/soap-envelope' ) ;
163              
164             # Grab the Header and the Body
165              
166             my $header_nodes =
167             $xp->find('/ver1:Envelope/ver1:Header/* | /ver2:Envelope/ver2:Header/*');
168            
169             my $body_nodes
170             = $xp->find('/ver1:Envelope/ver1:Body/* | /ver2:Envelope/ver2:Body/*');
171              
172             my $header = '';
173             my $body = '';
174            
175             # Serialize them
176            
177             for ($header_nodes->get_nodelist) { $header .= $_->toString }
178             for ($body_nodes->get_nodelist) { $body .= $_->toString }
179              
180             # That's all done
181              
182             return( $body, $header );
183              
184             }
185              
186             =head2 xml_parse
187              
188             Like C, but returns C objects instead.
189              
190             =cut
191              
192             sub xml_parse {
193              
194             # This method isn't enhanced by OO, so if the first argument was a ref,
195             # silently drop it and grab the next.
196            
197             my $data = shift;
198             $data = shift if ref( $data ); # Handle OO calls
199            
200             # Open up our parser...
201            
202             my $xp = XML::XPath->new( xml => $data );
203            
204             # This means that when the namespace is set to X, we can assume the prefix
205             # is going to be Y... This simplifies our XPath expressions a little.
206            
207             $xp->set_namespace( ver1 => 'http://schemas.xmlsoap.org/soap/envelope/');
208             $xp->set_namespace( ver2 => 'http://www.w3.org/2003/05/soap-envelope' ) ;
209              
210             # Grab the Header and the Body
211              
212             my $header_nodes =
213             $xp->find('/ver1:Envelope/ver1:Header/* | /ver2:Envelope/ver2:Header/*');
214            
215             my $body_nodes
216             = $xp->find('/ver1:Envelope/ver1:Body/* | /ver2:Envelope/ver2:Body/*');
217              
218             return ($header_nodes, $body_nodes);
219              
220             }
221              
222              
223             =head2 new
224              
225             Accepts the same arguments as C, and sets them as the defaults for
226             subsequent calls to C.
227              
228             =cut
229              
230             sub new {
231            
232             my $class = shift;
233            
234             my $self = { @_ };
235            
236             bless $self, $class;
237            
238             return $self;
239            
240             }
241              
242             =head1 AUTHOR
243              
244             Peter Sergeant - C
245              
246             =cut
247              
248             1;