Compare commits

..

6 Commits

Author SHA1 Message Date
Martin Kutter
40e0e67e84 import SOAP-WSDL 2.00_07 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00_07
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00_07.tar.gz
2009-12-12 19:47:45 -08:00
Martin Kutter
25548e6296 import SOAP-WSDL 2.00_06 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00_06
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00_06.tar.gz
2009-12-12 19:47:44 -08:00
Martin Kutter
a78d6d15b5 import SOAP-WSDL 2.00_05 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00_05
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00_05.tar.gz
2009-12-12 19:47:43 -08:00
Martin Kutter
5c42b1d8f6 import SOAP-WSDL 2.00_04 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00_04
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00_04.tar.gz
2009-12-12 19:47:43 -08:00
Martin Kutter
21b5330a8d import SOAP-WSDL 2.00_03 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00_03
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00_03.tar.gz
2009-12-12 19:47:42 -08:00
Martin Kutter
7716d4349a import SOAP-WSDL 2.00_02 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00_02
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00_02.tar.gz
2009-12-12 19:47:41 -08:00
161 changed files with 8780 additions and 4511 deletions

View File

@@ -2,21 +2,39 @@ use Module::Build;
Module::Build->new(
dist_abstract => 'SOAP with WSDL support',
dist_name => 'SOAP-WSDL',
dist_version => '2.00_01',
dist_version => '2.00_07',
module_name => 'SOAP::WSDL',
license => 'artistic',
requires => {
'SOAP::Lite' => 0,
'XML::XPath' => 0,
'XML::LibXML' => 0,
'XML::SAX::Base' => 0,
'XML::SAX::ParserFactory' => 0,
'Class::Std' => q/v0.0.8/,
'Class::Std::Storable' => 0,
'SOAP::Lite' => 0,
'List::Util' => 0,
'File::Basename' => 0,
'File::Path' => 0,
'XML::XPath' => 0,
'XML::LibXML' => 0,
'XML::SAX::Base' => 0,
'XML::SAX::ParserFactory' => 0,
'XML::Parser::Expat' => 0,
},
buildrequires => { 'Test::More' => 0,
'SOAP::Lite' => 0,
'XML::XPath' => 0,
'XML::LibXML' => 0,
'XML::SAX::Base' => 0,
'XML::SAX::ParserFactory' => 0,
buildrequires => {
'Benchmark' => 0,
'Cwd' => 0,
'Test::More' => 0,
'SOAP::Lite' => 0,
'Class::Std' => 0.0.8,
'Class::Std::Storable' => 0,
'List::Util' => 0,
'File::Basename' => 0,
'File::Path' => 0,
'XML::Simple' => 0,
'XML::LibXML' => 0,
'XML::Parser::Expat' => 0,
'XML::SAX::Base' => 0,
'XML::SAX::ParserFactory' => 0,
'Pod::Simple::Text' => 0,
'XML::SAX::ParserFactory' => 0,
},
recursive_test_files => 1,
)->create_build_script;

58
CHANGES
View File

@@ -1,57 +1 @@
$Log: CHANGES,v $
Revision 1.19 2004/07/27 13:00:03 lsc
- added missing test file
Revision 1.18 2004/07/16 07:43:05 lsc
fixed test scripts for windows
Revision 1.17 2004/07/05 08:19:49 lsc
- added wsdl_checkoccurs
Revision 1.16 2004/07/04 09:01:14 lsc
- change <definitions> element lookup from find('/definitions') and find('wsdl:definitions') to find('/*[1]') to process arbitrary default (wsdl) namespaces correctly
- fixed test output in test 06
Revision 1.15 2004/07/02 12:28:31 lsc
- documentation update
- cosmetics
Revision 1.14 2004/07/02 10:53:36 lsc
- API change:
- call now behaves (almost) like SOAP::Lite::call
- call() takes a list (hash) as second argument
- call does no longer support the "dispatch" option
- dispatching calls can be suppressed by passing
"no_dispatch => 1" to new()
- dispatching calls can be suppressed by calling
$soap->no_dispatch(1);
and re-enabled by calling
$soap->no_dispatch(0);
- Updated test skripts to reflect API change.
Revision 1.13 2004/06/30 12:08:40 lsc
- added IServiceInstance (ecmed) to acceptance tests
- refined documentation
Revision 1.12 2004/06/26 14:13:29 lsc
- refined file caching
- added descriptive output to test scripts
Revision 1.11 2004/06/26 07:55:40 lsc
- fixed "freeze" caching bug
- improved test scripts to test file system caching (and show the difference)
Revision 1.10 2004/06/26 06:30:33 lsc
- added filesystem caching using Cache::FileCache
Revision 1.9 2004/06/24 12:27:23 lsc
Cleanup
Revision 1.8 2004/06/11 19:49:15 lsc
- moved .t files to more self-describing names
- changed WSDL.pm to accept AXIS wsdl files
- implemented XPath query result caching on all absolute queries
Revision 1.7 2004/06/07 13:01:16 lsc
added changelog to pod
See perldoc SOAP::WSDL

39
HACKING
View File

@@ -1,7 +1,7 @@
Development of SOAP::WSDL takes place on sourceforge.net.
There's a svn repository available at
https://svn.sourceforge.net/svnroot/soap-wsdl
https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl
Engagement in the further development of this module is highly encouraged -
many people have already contributed, and many more probably will.
@@ -13,14 +13,33 @@ you as co-author.
The (my) current roadmap for SOAP::WSDL is:
1.2*: Bugfixes and support for more XSD variants
1.3: Bindings support
Development of the 1.* tree has stopped - I won't get past 1.2x anymore...
2.*: WSDL -> Perl Class factory with offline WSDL processing
May 2007,
1.* Development of the 1.* tree has stopped - I won't get past 1.2x anymore...
2.* WSDL -> Perl Class factory with offline WSDL processing
2.01
- WSDL support for the most common type definitions
- Online-facility (SOAP::WSDL) using WSDL object tree directly
- usable code generator
- full namespace support when processing WSDL
- high performance when parsing WSDL messages - get nearly as fast as
XML::Simple...
2.02
- Support for Apache-SOAP datatypes
- support for embedded atomic simpleType/complexType definitions
- Caching of WSDL object tree + generated code (when using SOAP::WSDL).
- Online-facility (SOAP::WSDL) using code generator via cache directory
Somewhere on the TODO list (in no particular order):
- validation
- typemaps for use with the type="tns:MyComplexType" XML attribute
- external entities support when parsing WSDL
- support all these XML Schema variants
- support creating XML Schmema definitions via SOAP::WSDL::XSD::* ('minimal conformant')
- support other Schema definition languages than XML::Schema (maybe RelaxNG?)
- factor out SOAP::WSDL::XSD into it's own namespace (maybe just XSD ?)
July 2007,
Martin Kutter

117
MANIFEST
View File

@@ -1,5 +1,29 @@
bin/wsdl2perl.pl
Build.PL
CHANGES
example/fortune.pl
example/lib/MyElements/CountCookies.pm
example/lib/MyElements/CountCookiesResponse.pm
example/lib/MyElements/GetCitiesByCountry.pm
example/lib/MyElements/GetCitiesByCountryResponse.pm
example/lib/MyElements/GetFortuneCookie.pm
example/lib/MyElements/GetFortuneCookieResponse.pm
example/lib/MyElements/GetSpecificCookie.pm
example/lib/MyElements/GetSpecificCookieResponse.pm
example/lib/MyElements/GetWeather.pm
example/lib/MyElements/GetWeatherResponse.pm
example/lib/MyElements/int.pm
example/lib/MyElements/readNodeCount.pm
example/lib/MyElements/readNodeCountResponse.pm
example/lib/MyElements/string.pm
example/lib/MyInterfaces/FullerData_x0020_Fortune_x0020_Cookie.pm
example/lib/MyInterfaces/GlobalWeather.pm
example/lib/MyTypemaps/FullerData_x0020_Fortune_x0020_Cookie.pm
example/lib/MyTypemaps/GlobalWeather.pm
example/weather.pl
example/wsdl/FortuneCookie.xml
example/wsdl/genericbarcode.xml
example/wsdl/globalweather.xml
HACKING
lib/SOAP/WSDL.pm
lib/SOAP/WSDL/Base.pm
@@ -8,9 +32,14 @@ lib/SOAP/WSDL/Client.pm
lib/SOAP/WSDL/Client/Base.pm
lib/SOAP/WSDL/Definitions.pm
lib/SOAP/WSDL/Envelope.pm
lib/SOAP/WSDL/Expat/MessageParser.pm
lib/SOAP/WSDL/Expat/MessageStreamParser.pm
lib/SOAP/WSDL/Manual.pod
lib/SOAP/WSDL/Manual/Glossary.pod
lib/SOAP/WSDL/Message.pm
lib/SOAP/WSDL/Operation.pm
lib/SOAP/WSDL/OpMessage.pm
lib/SOAP/WSDL/Parser.pod
lib/SOAP/WSDL/Part.pm
lib/SOAP/WSDL/Port.pm
lib/SOAP/WSDL/PortType.pm
@@ -28,6 +57,52 @@ lib/SOAP/WSDL/XSD/Schema.pm
lib/SOAP/WSDL/XSD/Schema/Builtin.pm
lib/SOAP/WSDL/XSD/SimpleType.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/anySimpleType.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/anyType.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/anyURI.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/base64Binary.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/boolean.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/byte.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/date.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/dateTime.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/decimal.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/double.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/duration.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/ENTITY.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/float.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/gDay.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/gMonth.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/gMonthDay.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/gYear.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/gYearMonth.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/hexBinary.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/ID.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/IDREF.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/IDREFS.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/int.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/integer.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/language.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/list.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/long.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/Name.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/NCName.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/negativeInteger.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKEN.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKENS.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/nonNegativeInteger.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/nonPositiveInteger.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/normalizedString.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/NOTATION.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/positiveInteger.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/QName.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/short.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/string.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/time.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/token.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedByte.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedInt.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedLong.pm
lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedShort.pm
lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm
lib/SOAP/WSDL/XSD/Typelib/Element.pm
lib/SOAP/WSDL/XSD/Typelib/SimpleType.pm
@@ -50,6 +125,9 @@ t/013_complexType.t
t/014_sax_typelib.t
t/015_to_typemap.t
t/016_client_object.t
t/017_generator.t
t/020_storable.t
t/098_pod.t
t/acceptance/results/03_complexType-all.xml
t/acceptance/results/03_complexType-sequence.xml
t/acceptance/results/04_element-simpleType.xml
@@ -75,25 +153,7 @@ t/acceptance/wsdl/contributed/ETest.wsdl
t/acceptance/wsdl/contributed/OITest.wsdl
t/acceptance/wsdl/contributed/tools.wsdl
t/acceptance/wsdl/email_account.wsdl
t/attic/01_use.t
t/attic/02_port.t
t/attic/03_complexType-all.t
t/attic/03_complexType-choice.t
t/attic/03_complexType-complexContent.t
t/attic/03_complexType-group.t
t/attic/03_complexType-sequence.t
t/attic/03_complexType-simpleContent.t
t/attic/04_element-complexType.t
t/attic/04_element-simpleType.t
t/attic/04_element.t
t/attic/05_simpleType-list.t
t/attic/05_simpleType-restriction.t
t/attic/05_simpleType-union.t
t/attic/10_performance.t
t/attic/11_helloworld.NET.t
t/attic/12_binding.pl
t/attic/97_pod.t
t/attic/98_pod_coverage.t
t/Expat/01_expat.t
t/lib/MyComplexType.pm
t/lib/MyElement.pm
t/lib/MySimpleType.pm
@@ -101,3 +161,22 @@ t/lib/Test/SOAPMessage.pm
t/lib/Typelib/Base.pm
t/lib/Typelib/TEnqueueMessage.pm
t/lib/Typelib/TMessage.pm
t/SOAP/WSDL/01_use.t
t/SOAP/WSDL/02_port.t
t/SOAP/WSDL/03_complexType-all.t
t/SOAP/WSDL/03_complexType-choice.t
t/SOAP/WSDL/03_complexType-complexContent.t
t/SOAP/WSDL/03_complexType-group.t
t/SOAP/WSDL/03_complexType-sequence.t
t/SOAP/WSDL/03_complexType-simpleContent.t
t/SOAP/WSDL/04_element-complexType.t
t/SOAP/WSDL/04_element-simpleType.t
t/SOAP/WSDL/04_element.t
t/SOAP/WSDL/05_simpleType-list.t
t/SOAP/WSDL/05_simpleType-restriction.t
t/SOAP/WSDL/05_simpleType-union.t
t/SOAP/WSDL/10_performance.t
t/SOAP/WSDL/11_helloworld.NET.t
t/SOAP/WSDL/12_binding.pl
t/SOAP/WSDL/XSD/Typelib/Builtin/001_string.t
TODO

114
META.yml
View File

@@ -1,13 +1,18 @@
---
name: SOAP-WSDL
version: 2.00_01
version: 2.00_07
author:
- "Replace the whitespace in the e-mail adresses by '@'."
abstract: SOAP with WSDL support
license: artistic
requires:
Class::Std: v0.0.8
Class::Std::Storable: 0
File::Basename: 0
File::Path: 0
List::Util: 0
SOAP::Lite: 0
XML::LibXML: 0
XML::Parser::Expat: 0
XML::SAX::Base: 0
XML::SAX::ParserFactory: 0
XML::XPath: 0
@@ -18,7 +23,7 @@ meta-spec:
provides:
SOAP::WSDL:
file: lib/SOAP/WSDL.pm
version: 1.21
version: 2.00_05
SOAP::WSDL::Base:
file: lib/SOAP/WSDL/Base.pm
SOAP::WSDL::Binding:
@@ -27,11 +32,14 @@ provides:
file: lib/SOAP/WSDL/Client.pm
SOAP::WSDL::Client::Base:
file: lib/SOAP/WSDL/Client/Base.pm
version: 0.1
SOAP::WSDL::Definitions:
file: lib/SOAP/WSDL/Definitions.pm
SOAP::WSDL::Envelope:
file: lib/SOAP/WSDL/Envelope.pm
SOAP::WSDL::Expat::MessageParser:
file: lib/SOAP/WSDL/Expat/MessageParser.pm
SOAP::WSDL::Expat::MessageStreamParser:
file: lib/SOAP/WSDL/Expat/MessageStreamParser.pm
SOAP::WSDL::Message:
file: lib/SOAP/WSDL/Message.pm
SOAP::WSDL::OpMessage:
@@ -46,8 +54,6 @@ provides:
file: lib/SOAP/WSDL/PortType.pm
SOAP::WSDL::SAX::MessageHandler:
file: lib/SOAP/WSDL/SAX/MessageHandler.pm
SOAP::WSDL::SAX::WSDLHandler:
file: lib/SOAP/WSDL/SAX/WSDLHandler.pm
SOAP::WSDL::SOAP::Typelib::Fault11:
file: lib/SOAP/WSDL/SOAP/Typelib/Fault11.pm
SOAP::WSDL::Service:
@@ -73,97 +79,97 @@ provides:
SOAP::WSDL::XSD::Typelib::Builtin:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
SOAP::WSDL::XSD::Typelib::Builtin::ENTITY:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/ENTITY.pm
SOAP::WSDL::XSD::Typelib::Builtin::ID:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/ID.pm
SOAP::WSDL::XSD::Typelib::Builtin::IDREF:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/IDREF.pm
SOAP::WSDL::XSD::Typelib::Builtin::IDREFS:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/IDREFS.pm
SOAP::WSDL::XSD::Typelib::Builtin::NCName:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/NCName.pm
SOAP::WSDL::XSD::Typelib::Builtin::NMTOKEN:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKEN.pm
SOAP::WSDL::XSD::Typelib::Builtin::NMTOKENS:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKENS.pm
SOAP::WSDL::XSD::Typelib::Builtin::NOTATION:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/NOTATION.pm
SOAP::WSDL::XSD::Typelib::Builtin::Name:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/Name.pm
SOAP::WSDL::XSD::Typelib::Builtin::QName:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/QName.pm
SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/anySimpleType.pm
SOAP::WSDL::XSD::Typelib::Builtin::anyType:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/anyType.pm
SOAP::WSDL::XSD::Typelib::Builtin::anyURI:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/anyURI.pm
SOAP::WSDL::XSD::Typelib::Builtin::base64Binary:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/base64Binary.pm
SOAP::WSDL::XSD::Typelib::Builtin::boolean:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/boolean.pm
SOAP::WSDL::XSD::Typelib::Builtin::byte:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/byte.pm
SOAP::WSDL::XSD::Typelib::Builtin::date:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/date.pm
SOAP::WSDL::XSD::Typelib::Builtin::dateTime:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/dateTime.pm
SOAP::WSDL::XSD::Typelib::Builtin::decimal:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/decimal.pm
SOAP::WSDL::XSD::Typelib::Builtin::double:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/double.pm
SOAP::WSDL::XSD::Typelib::Builtin::duration:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/duration.pm
SOAP::WSDL::XSD::Typelib::Builtin::float:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/float.pm
SOAP::WSDL::XSD::Typelib::Builtin::gDay:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/gDay.pm
SOAP::WSDL::XSD::Typelib::Builtin::gMonth:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/gMonth.pm
SOAP::WSDL::XSD::Typelib::Builtin::gMonthDay:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/gMonthDay.pm
SOAP::WSDL::XSD::Typelib::Builtin::gYear:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/gYear.pm
SOAP::WSDL::XSD::Typelib::Builtin::gYearMonth:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
SOAP::WSDL::XSD::Typelib::Builtin::hex64Binary:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/gYearMonth.pm
SOAP::WSDL::XSD::Typelib::Builtin::hexBinary:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/hexBinary.pm
SOAP::WSDL::XSD::Typelib::Builtin::int:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/int.pm
SOAP::WSDL::XSD::Typelib::Builtin::integer:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/integer.pm
SOAP::WSDL::XSD::Typelib::Builtin::language:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/language.pm
SOAP::WSDL::XSD::Typelib::Builtin::list:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/list.pm
SOAP::WSDL::XSD::Typelib::Builtin::long:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/long.pm
SOAP::WSDL::XSD::Typelib::Builtin::negativeInteger:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/negativeInteger.pm
SOAP::WSDL::XSD::Typelib::Builtin::nonNegativeInteger:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/nonNegativeInteger.pm
SOAP::WSDL::XSD::Typelib::Builtin::nonPositiveInteger:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/nonPositiveInteger.pm
SOAP::WSDL::XSD::Typelib::Builtin::normalizedString:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/normalizedString.pm
SOAP::WSDL::XSD::Typelib::Builtin::positiveInteger:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
SOAP::WSDL::XSD::Typelib::Builtin::qName:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/positiveInteger.pm
SOAP::WSDL::XSD::Typelib::Builtin::short:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/short.pm
SOAP::WSDL::XSD::Typelib::Builtin::string:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/string.pm
SOAP::WSDL::XSD::Typelib::Builtin::time:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/time.pm
SOAP::WSDL::XSD::Typelib::Builtin::token:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/token.pm
SOAP::WSDL::XSD::Typelib::Builtin::unsignedByte:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedByte.pm
SOAP::WSDL::XSD::Typelib::Builtin::unsignedInt:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedInt.pm
SOAP::WSDL::XSD::Typelib::Builtin::unsignedLong:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedLong.pm
SOAP::WSDL::XSD::Typelib::Builtin::unsignedShort:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedShort.pm
SOAP::WSDL::XSD::Typelib::ComplexType:
file: lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm
SOAP::WSDL::XSD::Typelib::Element:

2
README
View File

@@ -1,4 +1,2 @@
This is a developer release - everything may (and most things will) change.
You should not expect the SOAP::WSDL to survive - it will probably be replaced
by SOAP::WSDL::Client.

27
TODO Normal file
View File

@@ -0,0 +1,27 @@
- remove benchmarks from tests. Create benchmark/ directory and store benchmarks in.
- SOAP::WSDL::Definitions::create creates bad interface docs. Fix it.
- add tests for SOAP::WSDL::Definitions::create
- test for correct creation
- test against web service (fullerdata.com?)
- Improve docs
- Remove SOAP::Lite dependency - for now, just support HTTP(s) via LWP::UserAgent.
- write inheritance Test for all XSD::Typelib::Builtin::* classes
- Check & probably fix simpleType support.
The WS at http://www.webservicex.net/genericbarcode.asmx?wsdl should make up a good example for simpleType
definitions.
- update all Builtin Types to new constructor BEGIN block (Class::Std unfortunately is way slow)
- DONE.
- Remove useless (but on CPAN annoying) doc from Builtin::* classes
- DONE
- add example WS scripts
- DONE.
- SOAP::WSDL::XSD::Typelib::Builtin::string does not unescape XML builtin entities on get_value()
- WONTFIX.
Entities are unescaped by XML parser.
If you want the plain value, you have to use get_value, as XML conversion is overloaded on stringification.
- Make callin WS easier: implent WS-I-based SOAP::WSDL::Client::WSI
- WONTFIX - SOAP::WSDL::Base should behave equal
- add capability to create request objects based on input part definitions to SOAP::WSDL::Client::Base
- DONE.

134
bin/wsdl2perl.pl Normal file
View File

@@ -0,0 +1,134 @@
#!/usr/bin/perl -w
use strict;
use warnings;
use Fcntl;
use IO::File;
use Pod::Usage;
use Getopt::Long;
use LWP::Simple qw(get);
use SOAP::WSDL::SAX::WSDLHandler;
use XML::LibXML;
my %opt = (
url => '',
prefix => undef,
type_prefix => 'MyTypes::',
element_prefix => 'MyElements::',
typemap_prefix => 'MyTypemaps::',
interface_prefix => 'MyInterfaces::',
base_path => 'lib/',
);
GetOptions(\%opt,
qw(
url|u=s
prefix|p=s
type_prefix|t=s
element_prefix|e=s
typemap_prefix|m=s
base_path|b=s
typemap_include|mi=s
help|h
)
);
my $url = $ARGV[0];
pod2usage( -exit => 1 , verbose => 2 ) if ($opt{help});
pod2usage( -exit => 1 , verbose => 1 ) if not ($url);
my $handler = SOAP::WSDL::SAX::WSDLHandler->new();
my $parser = XML::LibXML->new();
my $xml = get($url) or die "Could not load WSDL schema $url\n";
$parser->set_handler( $handler );
$parser->parse_string( $xml );
my $wsdl = $handler->get_data();
if ($opt{typemap_include}) {
my $fh = IO::File->new($opt{typemap_include} , O_RDONLY)
or die "cannot open typemap_include file $opt{typemap_include}\n";
$opt{custom_types} = join q{}, $fh->getlines();
$fh->close();
delete $opt{typemap_include};
}
$wsdl->create({ %opt });
=pod
=head1 NAME
wsdl2perl.pl - create perl bindings for SOAP webservices.
=head1 SYNOPSIS
wsdl2perl.pl -t TYPE_PREFIX -e ELEMENT_PREFIX -m TYPEMAP_PREFIX \
-i INTERFACE_PREFIX -b BASE_DIR URL
=head1 OPTIONS
NAME SHORT DESCRITPION
----------------------------------------------------------------------------
prefix p Prefix for both type and element classes.
type_prefix t Prefix for type classes. Should end with '::'
Default: MyTypes::
element_prefix e Prefix for element classes. Should end with '::'
Default: MyElements::
typemap_prefix m Prefix for typemap classes. Should end with '::'
Default: MyTypemaps::
interface_prefix i Prefix for interface classes. Should end with '::'
Default: MyInterfaces::
base_path b Path to create classes in.
Default: ./lib
typemap_include mi File to include in typemap.
help h Show help content
=head1 DESCRIPTION
Generates a interface class for a SOAP web service described by a WSDL
definition.
The following classes are created:
=over
=item * A interface class for every service
Interface classes are what you will mainly deal with: They provide a method
for accessing every web service method.
=item * A typemap for every service
Typemaps are used internally by SOAP::WSDL for parsing the SOAP message into
object trees.
If the WSDL definition is incomplete, you may need to add some lines to
your typemap. Especially definitions for faults are sometimes left out.
Additional typemap content may be included by passing a file name as
typemap_include (mi) option.
=item * A type class for every element, complexType or simpleType definition
You may need to write additional type classes if your WSDL is incomplete.
For writing your own lib classes, see L<SOAP::WSDL::XSD::Typelib::Element>,
L<SOAP::WSDL::XSD::Typelib::ComplexType> and L<SOAP::WSDL::XSD::Typelib::SimpleType>.
=back
=head1 LICENSE
Copyright 2007 Martin Kutter.
This file is part of SOAP-WSDL. You may distribute/modify it under
the same terms as perl itself
=head1 AUTHOR
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=cut

33
example/fortune.pl Normal file
View File

@@ -0,0 +1,33 @@
# Accessing the fortune cookie service at
# www.fullerdata.com/FortuneCookie/FortuneCookie.asmx
#
# I have no connection to www.fullerdata.com
#
# Use this script at your own risk.
# Run before:
# D:\Eigene Dateien\Martin\SOAP-WSDL\trunk>perl -I../lib wsdl2perl.pl "file:///D:/
# Eigene Dateien/Martin/SOAP-WSDL/trunk/bin/FortuneCookie.xml"
use lib 'lib/';
use MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie;
use MyElements::GetFortuneCookie;
my $cookieService = MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie->new();
my $cookie = $cookieService->GetFortuneCookie();
if ($cookie) {
print $cookie->get_GetFortuneCookieResult()->get_value, "\n";
}
else {
print $cookie;
}
$cookie = $cookieService->GetSpecificCookie({ index => 23 });
if ($cookie) {
print $cookie
->get_GetSpecificCookieResult(), "\n";
}
else {
print $cookie;
}

View File

@@ -0,0 +1,71 @@
package MyElements::CountCookies;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="CountCookies"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
__PACKAGE__->_factory(
[ qw() ],
{
},
{
}
);
sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' }
__PACKAGE__->__set_name('CountCookies');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
1;
__END__
=pod
=head1 NAME MyElements::CountCookies
=head1 SYNOPSIS
=head1 DESCRIPTION
Type class for the XML element CountCookies.
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=head1 Object structure
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
=cut

View File

@@ -0,0 +1,85 @@
package MyElements::CountCookiesResponse;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="CountCookiesResponse"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
my %CountCookiesResult_of :ATTR(:get<CountCookiesResult>);
__PACKAGE__->_factory(
[ qw(
CountCookiesResult
) ],
{
CountCookiesResult => \%CountCookiesResult_of,
},
{
CountCookiesResult => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
}
);
sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' }
__PACKAGE__->__set_name('CountCookiesResponse');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
1;
__END__
=pod
=head1 NAME MyElements::CountCookiesResponse
=head1 SYNOPSIS
=head1 DESCRIPTION
Type class for the XML element CountCookiesResponse.
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
CountCookiesResult
=head1 Object structure
CountCookiesResult => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
'CountCookiesResponse'=> {
'CountCookiesResult' => $someValue,
},
=cut

View File

@@ -0,0 +1,85 @@
package MyElements::GetCitiesByCountry;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="GetCitiesByCountry"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
my %CountryName_of :ATTR(:get<CountryName>);
__PACKAGE__->_factory(
[ qw(
CountryName
) ],
{
CountryName => \%CountryName_of,
},
{
CountryName => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
}
);
sub get_xmlns { 'http://www.webserviceX.NET' }
__PACKAGE__->__set_name('GetCitiesByCountry');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
1;
__END__
=pod
=head1 NAME MyElements::GetCitiesByCountry
=head1 SYNOPSIS
=head1 DESCRIPTION
Type class for the XML element GetCitiesByCountry.
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
CountryName
=head1 Object structure
CountryName => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
'GetCitiesByCountry'=> {
'CountryName' => $someValue,
},
=cut

View File

@@ -0,0 +1,85 @@
package MyElements::GetCitiesByCountryResponse;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="GetCitiesByCountryResponse"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
my %GetCitiesByCountryResult_of :ATTR(:get<GetCitiesByCountryResult>);
__PACKAGE__->_factory(
[ qw(
GetCitiesByCountryResult
) ],
{
GetCitiesByCountryResult => \%GetCitiesByCountryResult_of,
},
{
GetCitiesByCountryResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
}
);
sub get_xmlns { 'http://www.webserviceX.NET' }
__PACKAGE__->__set_name('GetCitiesByCountryResponse');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
1;
__END__
=pod
=head1 NAME MyElements::GetCitiesByCountryResponse
=head1 SYNOPSIS
=head1 DESCRIPTION
Type class for the XML element GetCitiesByCountryResponse.
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
GetCitiesByCountryResult
=head1 Object structure
GetCitiesByCountryResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
'GetCitiesByCountryResponse'=> {
'GetCitiesByCountryResult' => $someValue,
},
=cut

View File

@@ -0,0 +1,71 @@
package MyElements::GetFortuneCookie;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="GetFortuneCookie"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
__PACKAGE__->_factory(
[ qw() ],
{
},
{
}
);
sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' }
__PACKAGE__->__set_name('GetFortuneCookie');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
1;
__END__
=pod
=head1 NAME MyElements::GetFortuneCookie
=head1 SYNOPSIS
=head1 DESCRIPTION
Type class for the XML element GetFortuneCookie.
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=head1 Object structure
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
=cut

View File

@@ -0,0 +1,85 @@
package MyElements::GetFortuneCookieResponse;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="GetFortuneCookieResponse"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
my %GetFortuneCookieResult_of :ATTR(:get<GetFortuneCookieResult>);
__PACKAGE__->_factory(
[ qw(
GetFortuneCookieResult
) ],
{
GetFortuneCookieResult => \%GetFortuneCookieResult_of,
},
{
GetFortuneCookieResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
}
);
sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' }
__PACKAGE__->__set_name('GetFortuneCookieResponse');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
1;
__END__
=pod
=head1 NAME MyElements::GetFortuneCookieResponse
=head1 SYNOPSIS
=head1 DESCRIPTION
Type class for the XML element GetFortuneCookieResponse.
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
GetFortuneCookieResult
=head1 Object structure
GetFortuneCookieResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
'GetFortuneCookieResponse'=> {
'GetFortuneCookieResult' => $someValue,
},
=cut

View File

@@ -0,0 +1,85 @@
package MyElements::GetSpecificCookie;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="GetSpecificCookie"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
my %index_of :ATTR(:get<index>);
__PACKAGE__->_factory(
[ qw(
index
) ],
{
index => \%index_of,
},
{
index => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
}
);
sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' }
__PACKAGE__->__set_name('GetSpecificCookie');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
1;
__END__
=pod
=head1 NAME MyElements::GetSpecificCookie
=head1 SYNOPSIS
=head1 DESCRIPTION
Type class for the XML element GetSpecificCookie.
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
index
=head1 Object structure
index => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
'GetSpecificCookie'=> {
'index' => $someValue,
},
=cut

View File

@@ -0,0 +1,85 @@
package MyElements::GetSpecificCookieResponse;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="GetSpecificCookieResponse"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
my %GetSpecificCookieResult_of :ATTR(:get<GetSpecificCookieResult>);
__PACKAGE__->_factory(
[ qw(
GetSpecificCookieResult
) ],
{
GetSpecificCookieResult => \%GetSpecificCookieResult_of,
},
{
GetSpecificCookieResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
}
);
sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' }
__PACKAGE__->__set_name('GetSpecificCookieResponse');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
1;
__END__
=pod
=head1 NAME MyElements::GetSpecificCookieResponse
=head1 SYNOPSIS
=head1 DESCRIPTION
Type class for the XML element GetSpecificCookieResponse.
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
GetSpecificCookieResult
=head1 Object structure
GetSpecificCookieResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
'GetSpecificCookieResponse'=> {
'GetSpecificCookieResult' => $someValue,
},
=cut

View File

@@ -0,0 +1,97 @@
package MyElements::GetWeather;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="GetWeather"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
my %CityName_of :ATTR(:get<CityName>);
my %CountryName_of :ATTR(:get<CountryName>);
__PACKAGE__->_factory(
[ qw(
CityName
CountryName
) ],
{
CityName => \%CityName_of,
CountryName => \%CountryName_of,
},
{
CityName => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
CountryName => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
}
);
sub get_xmlns { 'http://www.webserviceX.NET' }
__PACKAGE__->__set_name('GetWeather');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
1;
__END__
=pod
=head1 NAME MyElements::GetWeather
=head1 SYNOPSIS
=head1 DESCRIPTION
Type class for the XML element GetWeather.
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
CityName
CountryName
=head1 Object structure
CityName => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
CountryName => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
'GetWeather'=> {
'CityName' => $someValue,
'CountryName' => $someValue,
},
=cut

View File

@@ -0,0 +1,85 @@
package MyElements::GetWeatherResponse;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="GetWeatherResponse"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
my %GetWeatherResult_of :ATTR(:get<GetWeatherResult>);
__PACKAGE__->_factory(
[ qw(
GetWeatherResult
) ],
{
GetWeatherResult => \%GetWeatherResult_of,
},
{
GetWeatherResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
}
);
sub get_xmlns { 'http://www.webserviceX.NET' }
__PACKAGE__->__set_name('GetWeatherResponse');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
1;
__END__
=pod
=head1 NAME MyElements::GetWeatherResponse
=head1 SYNOPSIS
=head1 DESCRIPTION
Type class for the XML element GetWeatherResponse.
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
GetWeatherResult
=head1 Object structure
GetWeatherResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
'GetWeatherResponse'=> {
'GetWeatherResult' => $someValue,
},
=cut

View File

@@ -0,0 +1,60 @@
package MyElements::int;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
#
# <element name="int" type="s:int"/> definition
#
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::Builtin::int
);
sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' }
__PACKAGE__->__set_name('int');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
1;
__END__
=pod
=head1 NAME MyElements::int
=head1 SYNOPSIS
=head1 DESCRIPTION
Type class for the XML element int.
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=head1 Object structure
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
'int' => $someValue,
=cut

View File

@@ -0,0 +1,71 @@
package MyElements::readNodeCount;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="readNodeCount"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
__PACKAGE__->_factory(
[ qw() ],
{
},
{
}
);
sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' }
__PACKAGE__->__set_name('readNodeCount');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
1;
__END__
=pod
=head1 NAME MyElements::readNodeCount
=head1 SYNOPSIS
=head1 DESCRIPTION
Type class for the XML element readNodeCount.
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=head1 Object structure
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
=cut

View File

@@ -0,0 +1,85 @@
package MyElements::readNodeCountResponse;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="readNodeCountResponse"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
my %readNodeCountResult_of :ATTR(:get<readNodeCountResult>);
__PACKAGE__->_factory(
[ qw(
readNodeCountResult
) ],
{
readNodeCountResult => \%readNodeCountResult_of,
},
{
readNodeCountResult => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
}
);
sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' }
__PACKAGE__->__set_name('readNodeCountResponse');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
1;
__END__
=pod
=head1 NAME MyElements::readNodeCountResponse
=head1 SYNOPSIS
=head1 DESCRIPTION
Type class for the XML element readNodeCountResponse.
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
readNodeCountResult
=head1 Object structure
readNodeCountResult => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
'readNodeCountResponse'=> {
'readNodeCountResult' => $someValue,
},
=cut

View File

@@ -0,0 +1,60 @@
package MyElements::string;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
#
# <element name="string" type="s:string"/> definition
#
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::Builtin::string
);
sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' }
__PACKAGE__->__set_name('string');
__PACKAGE__->__set_nillable(true);
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
1;
__END__
=pod
=head1 NAME MyElements::string
=head1 SYNOPSIS
=head1 DESCRIPTION
Type class for the XML element string.
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=head1 Object structure
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
'string' => $someValue,
=cut

View File

@@ -0,0 +1,327 @@
package MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie;
use strict;
use warnings;
use MyTypemaps::FullerData_x0020_Fortune_x0020_Cookie;
use base 'SOAP::WSDL::Client::Base';
sub new {
my $class = shift;
my $arg_ref = shift || {};
my $self = $class->SUPER::new({
class_resolver => 'MyTypemaps::FullerData_x0020_Fortune_x0020_Cookie',
proxy => 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx',
%{ $arg_ref }
});
return bless $self, $class;
}
__PACKAGE__->__create_methods(
GetSpecificCookie => [ 'MyElements::GetSpecificCookie', ],
CountCookies => [ 'MyElements::CountCookies', ],
readNodeCount => [ 'MyElements::readNodeCount', ],
GetFortuneCookie => [ 'MyElements::GetFortuneCookie', ],
);
1;
__END__
=pod
=head1 NAME
MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie - SOAP interface to FullerData_x0020_Fortune_x0020_Cookie at
http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx
=head1 SYNOPSIS
my $interface = MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie->new();
my $CountCookies = $interface->CountCookies();
=head1 Service FullerData_x0020_Fortune_x0020_Cookie
=head2 Service information:
Port name: FullerData_x0020_Fortune_x0020_CookieSoap
Binding: tns:FullerData_x0020_Fortune_x0020_CookieSoap
Location: http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx
=head2 SOAP Operations
B<Note:>
Input, output and fault messages are stated as perl hash refs.
These are only for informational purposes - the actual implementation
normally uses object trees, not hash refs, though the input messages
may be passed to the respective methods as hash refs and will be
converted to object trees automatically.
=head3 readNodeCount
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=head3 GetFortuneCookie
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=head3 CountCookies
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=head3 GetSpecificCookie
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=head2 Service information:
Port name: FullerData_x0020_Fortune_x0020_CookieHttpGet
Binding: tns:FullerData_x0020_Fortune_x0020_CookieHttpGet
Location:
=head2 SOAP Operations
B<Note:>
Input, output and fault messages are stated as perl hash refs.
These are only for informational purposes - the actual implementation
normally uses object trees, not hash refs, though the input messages
may be passed to the respective methods as hash refs and will be
converted to object trees automatically.
=head3 readNodeCount
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=head3 GetFortuneCookie
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=head3 CountCookies
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=head3 GetSpecificCookie
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=head2 Service information:
Port name: FullerData_x0020_Fortune_x0020_CookieHttpPost
Binding: tns:FullerData_x0020_Fortune_x0020_CookieHttpPost
Location:
=head2 SOAP Operations
B<Note:>
Input, output and fault messages are stated as perl hash refs.
These are only for informational purposes - the actual implementation
normally uses object trees, not hash refs, though the input messages
may be passed to the respective methods as hash refs and will be
converted to object trees automatically.
=head3 readNodeCount
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=head3 GetFortuneCookie
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=head3 CountCookies
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=head3 GetSpecificCookie
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=cut

View File

@@ -0,0 +1,259 @@
package MyInterfaces::GlobalWeather;
use strict;
use warnings;
use MyTypemaps::GlobalWeather;
use base 'SOAP::WSDL::Client::Base';
sub new {
my $class = shift;
my $arg_ref = shift || {};
my $self = $class->SUPER::new({
class_resolver => 'MyTypemaps::GlobalWeather',
proxy => 'http://www.webservicex.net/globalweather.asmx',
%{ $arg_ref }
});
return bless $self, $class;
}
__PACKAGE__->__create_methods(
GetWeather => [ 'MyElements::GetWeather', ],
GetCitiesByCountry => [ 'MyElements::GetCitiesByCountry', ],
);
1;
__END__
=pod
=head1 NAME
MyInterfaces::GlobalWeather - SOAP interface to GlobalWeather at
http://www.webservicex.net/globalweather.asmx
=head1 SYNOPSIS
my $interface = MyInterfaces::GlobalWeather->new();
my $GetCitiesByCountry = $interface->GetCitiesByCountry();
=head1 Service GlobalWeather
=head2 Service information:
Port name: GlobalWeatherSoap
Binding: tns:GlobalWeatherSoap
Location: http://www.webservicex.net/globalweather.asmx
=head2 SOAP Operations
B<Note:>
Input, output and fault messages are stated as perl hash refs.
These are only for informational purposes - the actual implementation
normally uses object trees, not hash refs, though the input messages
may be passed to the respective methods as hash refs and will be
converted to object trees automatically.
=head3 GetWeather
B<Input Message:>
{
'GetWeather'=> {
'CityName' => $someValue,
'CountryName' => $someValue,
},
}
B<Output Message:>
{
'GetWeather'=> {
'CityName' => $someValue,
'CountryName' => $someValue,
},
}
B<Fault:>
=head3 GetCitiesByCountry
B<Input Message:>
{
'GetWeather'=> {
'CityName' => $someValue,
'CountryName' => $someValue,
},
}
B<Output Message:>
{
'GetWeather'=> {
'CityName' => $someValue,
'CountryName' => $someValue,
},
}
B<Fault:>
=head2 Service information:
Port name: GlobalWeatherHttpGet
Binding: tns:GlobalWeatherHttpGet
Location:
=head2 SOAP Operations
B<Note:>
Input, output and fault messages are stated as perl hash refs.
These are only for informational purposes - the actual implementation
normally uses object trees, not hash refs, though the input messages
may be passed to the respective methods as hash refs and will be
converted to object trees automatically.
=head3 GetWeather
B<Input Message:>
{
'GetWeather'=> {
'CityName' => $someValue,
'CountryName' => $someValue,
},
}
B<Output Message:>
{
'GetWeather'=> {
'CityName' => $someValue,
'CountryName' => $someValue,
},
}
B<Fault:>
=head3 GetCitiesByCountry
B<Input Message:>
{
'GetWeather'=> {
'CityName' => $someValue,
'CountryName' => $someValue,
},
}
B<Output Message:>
{
'GetWeather'=> {
'CityName' => $someValue,
'CountryName' => $someValue,
},
}
B<Fault:>
=head2 Service information:
Port name: GlobalWeatherHttpPost
Binding: tns:GlobalWeatherHttpPost
Location:
=head2 SOAP Operations
B<Note:>
Input, output and fault messages are stated as perl hash refs.
These are only for informational purposes - the actual implementation
normally uses object trees, not hash refs, though the input messages
may be passed to the respective methods as hash refs and will be
converted to object trees automatically.
=head3 GetWeather
B<Input Message:>
{
'GetWeather'=> {
'CityName' => $someValue,
'CountryName' => $someValue,
},
}
B<Output Message:>
{
'GetWeather'=> {
'CityName' => $someValue,
'CountryName' => $someValue,
},
}
B<Fault:>
=head3 GetCitiesByCountry
B<Input Message:>
{
'GetWeather'=> {
'CityName' => $someValue,
'CountryName' => $someValue,
},
}
B<Output Message:>
{
'GetWeather'=> {
'CityName' => $someValue,
'CountryName' => $someValue,
},
}
B<Fault:>
=cut

View File

@@ -0,0 +1,49 @@
package MyTypemaps::FullerData_x0020_Fortune_x0020_Cookie;
use strict;
use warnings;
my %typemap = (
'readNodeCount' => 'MyElements::readNodeCount',
'readNodeCountResponse' => 'MyElements::readNodeCountResponse',
# atomic complex type (sequence)
'readNodeCountResponse/readNodeCountResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
# end atomic complex type (sequence)
'GetFortuneCookie' => 'MyElements::GetFortuneCookie',
'GetFortuneCookieResponse' => 'MyElements::GetFortuneCookieResponse',
# atomic complex type (sequence)
'GetFortuneCookieResponse/GetFortuneCookieResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
# end atomic complex type (sequence)
'CountCookies' => 'MyElements::CountCookies',
'CountCookiesResponse' => 'MyElements::CountCookiesResponse',
# atomic complex type (sequence)
'CountCookiesResponse/CountCookiesResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
# end atomic complex type (sequence)
'GetSpecificCookie' => 'MyElements::GetSpecificCookie',
# atomic complex type (sequence)
'GetSpecificCookie/index' => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
# end atomic complex type (sequence)
'GetSpecificCookieResponse' => 'MyElements::GetSpecificCookieResponse',
# atomic complex type (sequence)
'GetSpecificCookieResponse/GetSpecificCookieResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
# end atomic complex type (sequence)
);
sub get_class {
my $name = join '/', @{ $_[1] };
exists $typemap{ $name } or die "Cannot resolve $name via " . __PACKAGE__;
return $typemap{ $name };
}
1;
__END__

View File

@@ -0,0 +1,45 @@
package MyTypemaps::GlobalWeather;
use strict;
use warnings;
my %typemap = (
'GetWeather' => 'MyElements::GetWeather',
# atomic complex type (sequence)
'GetWeather/CityName' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
'GetWeather/CountryName' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
# end atomic complex type (sequence)
'GetWeatherResponse' => 'MyElements::GetWeatherResponse',
# atomic complex type (sequence)
'GetWeatherResponse/GetWeatherResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
# end atomic complex type (sequence)
'GetCitiesByCountry' => 'MyElements::GetCitiesByCountry',
# atomic complex type (sequence)
'GetCitiesByCountry/CountryName' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
# end atomic complex type (sequence)
'GetCitiesByCountryResponse' => 'MyElements::GetCitiesByCountryResponse',
# atomic complex type (sequence)
'GetCitiesByCountryResponse/GetCitiesByCountryResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
# end atomic complex type (sequence)
Fault => 'SOAP::WSDL::SOAP::Typelib::Fault11',
'Fault/faultstring' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
'Fault/faultcode' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
'Fault/faultactor' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
'Fault/faultactor' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
'Fault/detail' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
);
sub get_class {
my $name = join '/', @{ $_[1] };
exists $typemap{ $name } or die "Cannot resolve $name via " . __PACKAGE__;
return $typemap{ $name };
}
1;
__END__

19
example/weather.pl Normal file
View File

@@ -0,0 +1,19 @@
# Accessing the fortune cookie service at
# www.webservicex.net/GlobalWeather/GlobalWeather.asmx
#
# I have no connection to www.webservicex.net
#
# Use this script at your own risk.
use lib 'lib/';
use MyInterfaces::GlobalWeather;
my $webservice = MyInterfaces::GlobalWeather->new();
my $result = $webservice->GetWeather({ CountryName => 'Germany', CityName => 'Munich' });
if ($result) {
print $result->get_GetWeatherResult()->get_value(), "\n";
}
else {
print $result;
}

View File

@@ -0,0 +1,308 @@
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" targetNamespace="http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx">
<s:element name="readNodeCount">
<s:complexType />
</s:element>
<s:element name="readNodeCountResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="readNodeCountResult" type="s:int" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="GetFortuneCookie">
<s:complexType />
</s:element>
<s:element name="GetFortuneCookieResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="GetFortuneCookieResult" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="CountCookies">
<s:complexType />
</s:element>
<s:element name="CountCookiesResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="CountCookiesResult" type="s:int" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="GetSpecificCookie">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="index" type="s:int" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="GetSpecificCookieResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="GetSpecificCookieResult" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="int" type="s:int" />
<s:element name="string" nillable="true" type="s:string" />
</s:schema>
</wsdl:types>
<wsdl:message name="readNodeCountSoapIn">
<wsdl:part name="parameters" element="tns:readNodeCount" />
</wsdl:message>
<wsdl:message name="readNodeCountSoapOut">
<wsdl:part name="parameters" element="tns:readNodeCountResponse" />
</wsdl:message>
<wsdl:message name="GetFortuneCookieSoapIn">
<wsdl:part name="parameters" element="tns:GetFortuneCookie" />
</wsdl:message>
<wsdl:message name="GetFortuneCookieSoapOut">
<wsdl:part name="parameters" element="tns:GetFortuneCookieResponse" />
</wsdl:message>
<wsdl:message name="CountCookiesSoapIn">
<wsdl:part name="parameters" element="tns:CountCookies" />
</wsdl:message>
<wsdl:message name="CountCookiesSoapOut">
<wsdl:part name="parameters" element="tns:CountCookiesResponse" />
</wsdl:message>
<wsdl:message name="GetSpecificCookieSoapIn">
<wsdl:part name="parameters" element="tns:GetSpecificCookie" />
</wsdl:message>
<wsdl:message name="GetSpecificCookieSoapOut">
<wsdl:part name="parameters" element="tns:GetSpecificCookieResponse" />
</wsdl:message>
<wsdl:message name="readNodeCountHttpGetIn" />
<wsdl:message name="readNodeCountHttpGetOut">
<wsdl:part name="Body" element="tns:int" />
</wsdl:message>
<wsdl:message name="GetFortuneCookieHttpGetIn" />
<wsdl:message name="GetFortuneCookieHttpGetOut">
<wsdl:part name="Body" element="tns:string" />
</wsdl:message>
<wsdl:message name="CountCookiesHttpGetIn" />
<wsdl:message name="CountCookiesHttpGetOut">
<wsdl:part name="Body" element="tns:int" />
</wsdl:message>
<wsdl:message name="GetSpecificCookieHttpGetIn">
<wsdl:part name="index" type="s:string" />
</wsdl:message>
<wsdl:message name="GetSpecificCookieHttpGetOut">
<wsdl:part name="Body" element="tns:string" />
</wsdl:message>
<wsdl:message name="readNodeCountHttpPostIn" />
<wsdl:message name="readNodeCountHttpPostOut">
<wsdl:part name="Body" element="tns:int" />
</wsdl:message>
<wsdl:message name="GetFortuneCookieHttpPostIn" />
<wsdl:message name="GetFortuneCookieHttpPostOut">
<wsdl:part name="Body" element="tns:string" />
</wsdl:message>
<wsdl:message name="CountCookiesHttpPostIn" />
<wsdl:message name="CountCookiesHttpPostOut">
<wsdl:part name="Body" element="tns:int" />
</wsdl:message>
<wsdl:message name="GetSpecificCookieHttpPostIn">
<wsdl:part name="index" type="s:string" />
</wsdl:message>
<wsdl:message name="GetSpecificCookieHttpPostOut">
<wsdl:part name="Body" element="tns:string" />
</wsdl:message>
<wsdl:portType name="FullerData_x0020_Fortune_x0020_CookieSoap">
<wsdl:operation name="readNodeCount">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Display the number of nodes specified in fortune XML document</documentation>
<wsdl:input message="tns:readNodeCountSoapIn" />
<wsdl:output message="tns:readNodeCountSoapOut" />
</wsdl:operation>
<wsdl:operation name="GetFortuneCookie">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Get a random fortune cookie from the XML document</documentation>
<wsdl:input message="tns:GetFortuneCookieSoapIn" />
<wsdl:output message="tns:GetFortuneCookieSoapOut" />
</wsdl:operation>
<wsdl:operation name="CountCookies">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Count the actual number of nodes in the XML document of fortunes</documentation>
<wsdl:input message="tns:CountCookiesSoapIn" />
<wsdl:output message="tns:CountCookiesSoapOut" />
</wsdl:operation>
<wsdl:operation name="GetSpecificCookie">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Get a specific cookie by the XML node number</documentation>
<wsdl:input message="tns:GetSpecificCookieSoapIn" />
<wsdl:output message="tns:GetSpecificCookieSoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:portType name="FullerData_x0020_Fortune_x0020_CookieHttpGet">
<wsdl:operation name="readNodeCount">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Display the number of nodes specified in fortune XML document</documentation>
<wsdl:input message="tns:readNodeCountHttpGetIn" />
<wsdl:output message="tns:readNodeCountHttpGetOut" />
</wsdl:operation>
<wsdl:operation name="GetFortuneCookie">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Get a random fortune cookie from the XML document</documentation>
<wsdl:input message="tns:GetFortuneCookieHttpGetIn" />
<wsdl:output message="tns:GetFortuneCookieHttpGetOut" />
</wsdl:operation>
<wsdl:operation name="CountCookies">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Count the actual number of nodes in the XML document of fortunes</documentation>
<wsdl:input message="tns:CountCookiesHttpGetIn" />
<wsdl:output message="tns:CountCookiesHttpGetOut" />
</wsdl:operation>
<wsdl:operation name="GetSpecificCookie">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Get a specific cookie by the XML node number</documentation>
<wsdl:input message="tns:GetSpecificCookieHttpGetIn" />
<wsdl:output message="tns:GetSpecificCookieHttpGetOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:portType name="FullerData_x0020_Fortune_x0020_CookieHttpPost">
<wsdl:operation name="readNodeCount">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Display the number of nodes specified in fortune XML document</documentation>
<wsdl:input message="tns:readNodeCountHttpPostIn" />
<wsdl:output message="tns:readNodeCountHttpPostOut" />
</wsdl:operation>
<wsdl:operation name="GetFortuneCookie">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Get a random fortune cookie from the XML document</documentation>
<wsdl:input message="tns:GetFortuneCookieHttpPostIn" />
<wsdl:output message="tns:GetFortuneCookieHttpPostOut" />
</wsdl:operation>
<wsdl:operation name="CountCookies">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Count the actual number of nodes in the XML document of fortunes</documentation>
<wsdl:input message="tns:CountCookiesHttpPostIn" />
<wsdl:output message="tns:CountCookiesHttpPostOut" />
</wsdl:operation>
<wsdl:operation name="GetSpecificCookie">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Get a specific cookie by the XML node number</documentation>
<wsdl:input message="tns:GetSpecificCookieHttpPostIn" />
<wsdl:output message="tns:GetSpecificCookieHttpPostOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="FullerData_x0020_Fortune_x0020_CookieSoap" type="tns:FullerData_x0020_Fortune_x0020_CookieSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
<wsdl:operation name="readNodeCount">
<soap:operation soapAction="http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx/readNodeCount" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetFortuneCookie">
<soap:operation soapAction="http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx/GetFortuneCookie" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="CountCookies">
<soap:operation soapAction="http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx/CountCookies" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetSpecificCookie">
<soap:operation soapAction="http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx/GetSpecificCookie" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="FullerData_x0020_Fortune_x0020_CookieHttpGet" type="tns:FullerData_x0020_Fortune_x0020_CookieHttpGet">
<http:binding verb="GET" />
<wsdl:operation name="readNodeCount">
<http:operation location="/readNodeCount" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetFortuneCookie">
<http:operation location="/GetFortuneCookie" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="CountCookies">
<http:operation location="/CountCookies" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetSpecificCookie">
<http:operation location="/GetSpecificCookie" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="FullerData_x0020_Fortune_x0020_CookieHttpPost" type="tns:FullerData_x0020_Fortune_x0020_CookieHttpPost">
<http:binding verb="POST" />
<wsdl:operation name="readNodeCount">
<http:operation location="/readNodeCount" />
<wsdl:input>
<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetFortuneCookie">
<http:operation location="/GetFortuneCookie" />
<wsdl:input>
<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="CountCookies">
<http:operation location="/CountCookies" />
<wsdl:input>
<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetSpecificCookie">
<http:operation location="/GetSpecificCookie" />
<wsdl:input>
<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="FullerData_x0020_Fortune_x0020_Cookie">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Simple XML-based fortune cookie</documentation>
<wsdl:port name="FullerData_x0020_Fortune_x0020_CookieSoap" binding="tns:FullerData_x0020_Fortune_x0020_CookieSoap">
<soap:address location="http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx" />
</wsdl:port>
<wsdl:port name="FullerData_x0020_Fortune_x0020_CookieHttpGet" binding="tns:FullerData_x0020_Fortune_x0020_CookieHttpGet">
<http:address location="http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx" />
</wsdl:port>
<wsdl:port name="FullerData_x0020_Fortune_x0020_CookieHttpPost" binding="tns:FullerData_x0020_Fortune_x0020_CookieHttpPost">
<http:address location="http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

View File

@@ -0,0 +1,153 @@
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://www.webservicex.net/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" targetNamespace="http://www.webservicex.net/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://www.webservicex.net/">
<s:element name="GenerateBarCode">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="BarCodeParam" type="tns:BarCodeData" />
<s:element minOccurs="0" maxOccurs="1" name="BarCodeText" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="BarCodeData">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="Height" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="Width" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="Angle" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="Ratio" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="Module" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="Left" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="Top" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="CheckSum" type="s:boolean" />
<s:element minOccurs="0" maxOccurs="1" name="FontName" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="BarColor" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="BGColor" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="FontSize" type="s:float" />
<s:element minOccurs="1" maxOccurs="1" name="barcodeOption" type="tns:BarcodeOption" />
<s:element minOccurs="1" maxOccurs="1" name="barcodeType" type="tns:BarcodeType" />
<s:element minOccurs="1" maxOccurs="1" name="checkSumMethod" type="tns:CheckSumMethod" />
<s:element minOccurs="1" maxOccurs="1" name="showTextPosition" type="tns:ShowTextPosition" />
<s:element minOccurs="1" maxOccurs="1" name="BarCodeImageFormat" type="tns:ImageFormats" />
</s:sequence>
</s:complexType>
<s:simpleType name="BarcodeOption">
<s:restriction base="s:string">
<s:enumeration value="None" />
<s:enumeration value="Code" />
<s:enumeration value="Typ" />
<s:enumeration value="Both" />
</s:restriction>
</s:simpleType>
<s:simpleType name="BarcodeType">
<s:restriction base="s:string">
<s:enumeration value="Code_2_5_interleaved" />
<s:enumeration value="Code_2_5_industrial" />
<s:enumeration value="Code_2_5_matrix" />
<s:enumeration value="Code39" />
<s:enumeration value="Code39Extended" />
<s:enumeration value="Code128A" />
<s:enumeration value="Code128B" />
<s:enumeration value="Code128C" />
<s:enumeration value="Code93" />
<s:enumeration value="Code93Extended" />
<s:enumeration value="CodeMSI" />
<s:enumeration value="CodePostNet" />
<s:enumeration value="CodeCodabar" />
<s:enumeration value="CodeEAN8" />
<s:enumeration value="CodeEAN13" />
<s:enumeration value="CodeUPC_A" />
<s:enumeration value="CodeUPC_E0" />
<s:enumeration value="CodeUPC_E1" />
<s:enumeration value="CodeUPC_Supp2" />
<s:enumeration value="CodeUPC_Supp5" />
<s:enumeration value="CodeEAN128A" />
<s:enumeration value="CodeEAN128B" />
<s:enumeration value="CodeEAN128C" />
</s:restriction>
</s:simpleType>
<s:simpleType name="CheckSumMethod">
<s:restriction base="s:string">
<s:enumeration value="None" />
<s:enumeration value="Modulo10" />
</s:restriction>
</s:simpleType>
<s:simpleType name="ShowTextPosition">
<s:restriction base="s:string">
<s:enumeration value="TopLeft" />
<s:enumeration value="TopRight" />
<s:enumeration value="TopCenter" />
<s:enumeration value="BottomLeft" />
<s:enumeration value="BottomRight" />
<s:enumeration value="BottomCenter" />
</s:restriction>
</s:simpleType>
<s:simpleType name="ImageFormats">
<s:restriction base="s:string">
<s:enumeration value="BMP" />
<s:enumeration value="EMF" />
<s:enumeration value="EXIF" />
<s:enumeration value="GIF" />
<s:enumeration value="ICON" />
<s:enumeration value="JPEG" />
<s:enumeration value="MemoryBMP" />
<s:enumeration value="PNG" />
<s:enumeration value="TIFF" />
<s:enumeration value="WMF" />
</s:restriction>
</s:simpleType>
<s:element name="GenerateBarCodeResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="GenerateBarCodeResult" type="s:base64Binary" />
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
<wsdl:message name="GenerateBarCodeSoapIn">
<wsdl:part name="parameters" element="tns:GenerateBarCode" />
</wsdl:message>
<wsdl:message name="GenerateBarCodeSoapOut">
<wsdl:part name="parameters" element="tns:GenerateBarCodeResponse" />
</wsdl:message>
<wsdl:portType name="BarCodeSoap">
<wsdl:operation name="GenerateBarCode">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/">WebserviceX.NET barcode library that provides the means to create barcodes for printing and display in any internet enabled applications. This web service supports Code 128, Industrial 2 of 5, Interleaved 2 of 5, Code 2 5 Matrix, Code 39, Code 39 Extended, Code 93, Code 93 Extended, Codabar, EAN13, EAN8, MSI, Postnet, Supp2, Supp5, UPC A, UPC E0 and UPC E1 barcode formats. This Barcodes returns byte image. It supports following image format JPEG, GIF, PNG, BMP, EMF, EXIF, ICON, MEMORY BMP, TIFF and WMF.</documentation>
<wsdl:input message="tns:GenerateBarCodeSoapIn" />
<wsdl:output message="tns:GenerateBarCodeSoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:portType name="BarCodeHttpGet" />
<wsdl:portType name="BarCodeHttpPost" />
<wsdl:binding name="BarCodeSoap" type="tns:BarCodeSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
<wsdl:operation name="GenerateBarCode">
<soap:operation soapAction="http://www.webservicex.net/GenerateBarCode" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="BarCodeHttpGet" type="tns:BarCodeHttpGet">
<http:binding verb="GET" />
</wsdl:binding>
<wsdl:binding name="BarCodeHttpPost" type="tns:BarCodeHttpPost">
<http:binding verb="POST" />
</wsdl:binding>
<wsdl:service name="BarCode">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Barcode generator</documentation>
<wsdl:port name="BarCodeSoap" binding="tns:BarCodeSoap">
<soap:address location="http://www.webservicex.net/genericbarcode.asmx" />
</wsdl:port>
<wsdl:port name="BarCodeHttpGet" binding="tns:BarCodeHttpGet">
<http:address location="http://www.webservicex.net/genericbarcode.asmx" />
</wsdl:port>
<wsdl:port name="BarCodeHttpPost" binding="tns:BarCodeHttpPost">
<http:address location="http://www.webservicex.net/genericbarcode.asmx" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

View File

@@ -0,0 +1,185 @@
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://www.webserviceX.NET" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" targetNamespace="http://www.webserviceX.NET" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://www.webserviceX.NET">
<s:element name="GetWeather">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="CityName" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="CountryName" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="GetWeatherResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="GetWeatherResult" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="GetCitiesByCountry">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="CountryName" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="GetCitiesByCountryResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="GetCitiesByCountryResult" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="string" nillable="true" type="s:string" />
</s:schema>
</wsdl:types>
<wsdl:message name="GetWeatherSoapIn">
<wsdl:part name="parameters" element="tns:GetWeather" />
</wsdl:message>
<wsdl:message name="GetWeatherSoapOut">
<wsdl:part name="parameters" element="tns:GetWeatherResponse" />
</wsdl:message>
<wsdl:message name="GetCitiesByCountrySoapIn">
<wsdl:part name="parameters" element="tns:GetCitiesByCountry" />
</wsdl:message>
<wsdl:message name="GetCitiesByCountrySoapOut">
<wsdl:part name="parameters" element="tns:GetCitiesByCountryResponse" />
</wsdl:message>
<wsdl:message name="GetWeatherHttpGetIn">
<wsdl:part name="CityName" type="s:string" />
<wsdl:part name="CountryName" type="s:string" />
</wsdl:message>
<wsdl:message name="GetWeatherHttpGetOut">
<wsdl:part name="Body" element="tns:string" />
</wsdl:message>
<wsdl:message name="GetCitiesByCountryHttpGetIn">
<wsdl:part name="CountryName" type="s:string" />
</wsdl:message>
<wsdl:message name="GetCitiesByCountryHttpGetOut">
<wsdl:part name="Body" element="tns:string" />
</wsdl:message>
<wsdl:message name="GetWeatherHttpPostIn">
<wsdl:part name="CityName" type="s:string" />
<wsdl:part name="CountryName" type="s:string" />
</wsdl:message>
<wsdl:message name="GetWeatherHttpPostOut">
<wsdl:part name="Body" element="tns:string" />
</wsdl:message>
<wsdl:message name="GetCitiesByCountryHttpPostIn">
<wsdl:part name="CountryName" type="s:string" />
</wsdl:message>
<wsdl:message name="GetCitiesByCountryHttpPostOut">
<wsdl:part name="Body" element="tns:string" />
</wsdl:message>
<wsdl:portType name="GlobalWeatherSoap">
<wsdl:operation name="GetWeather">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Get weather report for all major cities around the world.</documentation>
<wsdl:input message="tns:GetWeatherSoapIn" />
<wsdl:output message="tns:GetWeatherSoapOut" />
</wsdl:operation>
<wsdl:operation name="GetCitiesByCountry">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Get all major cities by country name(full / part).</documentation>
<wsdl:input message="tns:GetCitiesByCountrySoapIn" />
<wsdl:output message="tns:GetCitiesByCountrySoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:portType name="GlobalWeatherHttpGet">
<wsdl:operation name="GetWeather">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Get weather report for all major cities around the world.</documentation>
<wsdl:input message="tns:GetWeatherHttpGetIn" />
<wsdl:output message="tns:GetWeatherHttpGetOut" />
</wsdl:operation>
<wsdl:operation name="GetCitiesByCountry">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Get all major cities by country name(full / part).</documentation>
<wsdl:input message="tns:GetCitiesByCountryHttpGetIn" />
<wsdl:output message="tns:GetCitiesByCountryHttpGetOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:portType name="GlobalWeatherHttpPost">
<wsdl:operation name="GetWeather">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Get weather report for all major cities around the world.</documentation>
<wsdl:input message="tns:GetWeatherHttpPostIn" />
<wsdl:output message="tns:GetWeatherHttpPostOut" />
</wsdl:operation>
<wsdl:operation name="GetCitiesByCountry">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Get all major cities by country name(full / part).</documentation>
<wsdl:input message="tns:GetCitiesByCountryHttpPostIn" />
<wsdl:output message="tns:GetCitiesByCountryHttpPostOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="GlobalWeatherSoap" type="tns:GlobalWeatherSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
<wsdl:operation name="GetWeather">
<soap:operation soapAction="http://www.webserviceX.NET/GetWeather" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetCitiesByCountry">
<soap:operation soapAction="http://www.webserviceX.NET/GetCitiesByCountry" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="GlobalWeatherHttpGet" type="tns:GlobalWeatherHttpGet">
<http:binding verb="GET" />
<wsdl:operation name="GetWeather">
<http:operation location="/GetWeather" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetCitiesByCountry">
<http:operation location="/GetCitiesByCountry" />
<wsdl:input>
<http:urlEncoded />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="GlobalWeatherHttpPost" type="tns:GlobalWeatherHttpPost">
<http:binding verb="POST" />
<wsdl:operation name="GetWeather">
<http:operation location="/GetWeather" />
<wsdl:input>
<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetCitiesByCountry">
<http:operation location="/GetCitiesByCountry" />
<wsdl:input>
<mime:content type="application/x-www-form-urlencoded" />
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="GlobalWeather">
<wsdl:port name="GlobalWeatherSoap" binding="tns:GlobalWeatherSoap">
<soap:address location="http://www.webservicex.net/globalweather.asmx" />
</wsdl:port>
<wsdl:port name="GlobalWeatherHttpGet" binding="tns:GlobalWeatherHttpGet">
<http:address location="http://www.webservicex.net/globalweather.asmx" />
</wsdl:port>
<wsdl:port name="GlobalWeatherHttpPost" binding="tns:GlobalWeatherHttpPost">
<http:address location="http://www.webservicex.net/globalweather.asmx" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

File diff suppressed because it is too large Load Diff

View File

@@ -3,11 +3,19 @@ use strict;
use warnings;
use Carp;
use Class::Std::Storable;
use List::Util qw(first);
my %id_of :ATTR(:name<id> :default<()>);
my %name_of :ATTR(:name<name> :default<()>);
my %targetNamespace_of :ATTR(:name<targetNamespace> :default<()>);
my %xmlns_of :ATTR(:name<xmlns> :default<{}>);
my %parent_of :ATTR(:name<parent> :default<()>);
sub DEMOLISH {
my $self = shift;
# delete upward references
delete $parent_of{ ident $self };
}
sub STORABLE_freeze_pre :CUMULATIVE {};
sub STORABLE_freeze_post :CUMULATIVE {};
@@ -20,14 +28,18 @@ sub STORABLE_thaw_post :CUMULATIVE { return $_[0] };
sub AUTOMETHOD {
my ($self, $ident, @values) = @_;
my $subname = $_; # Requested subroutine name is passed via $_
# we're called as $self->push_something(@values);
if ($subname =~s{^push_}{}xms) {
# we're not paranoid - we could be checking get_subname, too
my $getter = "get_$subname";
my $setter = "set_$subname";
croak "no set accessor found for push_$subname"
if not ($self->can( $setter ));
my $setter = "set_$subname";
## Checking here is paranoid - will fail fatally if
## there is no setter...
## And we would have to check getters, too.
## Maybe do it the Conway way via the Symbol table...
## ... can is way slow...
# croak "no set accessor found for push_$subname"
# if not ($self->can( $setter ));
return sub {
no strict qw(refs);
my $old_value = $self->$getter();
@@ -42,12 +54,11 @@ sub AUTOMETHOD {
# we're called as $obj->find_something($ns, $key)
elsif ($subname =~s {^find_}{get_}xms) {
return sub {
my @found_at = grep {
return first {
$_->get_targetNamespace() eq $values[0] &&
$_->get_name() eq $values[1]
}
@{ $self->$subname() };
return $found_at[0];
}
}
elsif ($subname =~s {^first_}{get_}xms) {
@@ -61,45 +72,98 @@ sub AUTOMETHOD {
croak "$subname not found in class " . (ref $self || $self);
}
#sub to_string :STRINGIFY {
# $_[0]->_DUMP();
#}
sub init {
my $self = shift;
my @args = @_;
foreach my $value (@args)
{
die $value if (not defined ($value->{ Name }));
if ($value->{ Name } =~m{^xmlns\:}xms) {
my $self = shift;
my @args = @_;
foreach my $value (@args)
{
die $value if (not defined ($value->{ Name }));
if ($value->{ Name } =~m{^xmlns\:}xms) {
die $xmlns_of{ ident $self }
if ref $xmlns_of{ ident $self } ne 'HASH';
$xmlns_of{ ident $self }->{ $value->{ Value } } =
$value->{ LocalName };
next;
}
next;
}
elsif ($value->{ Name } =~m{^xmlns$}xms) {
# just ignore xmlns = for now
# TODO handle xmlns correctly - maybe via setting a prefix ?
next;
}
my $name = $value->{ LocalName };
my $method = "set_$name";
$self->$method( $value->{ Value } ) if ( $method );
}
my $name = $value->{ LocalName };
my $method = "set_$name";
$self->$method( $value->{ Value } ) if ( $method );
}
return $self;
}
sub add_namespace {
my ($self, $uri, $prefix ) = @_;
return unless $uri;
$self->{ namespace } ||= {};
$self->{ namespace }->{ $uri } = $prefix;
my ($self, $uri, $prefix ) = @_;
return unless $uri;
$self->{ namespace } ||= {};
$self->{ namespace }->{ $uri } = $prefix;
}
sub to_typemap {
warn "to_typemap";
return q{};
}
sub toClass {
my $self = shift;
warn 'toClass is deprecated and will be removed before reaching 2.01 - '
. 'use to_class instead (' . caller() . ')';
$self->to_class(@_);
}
sub to_class {
my $self = shift;
my $opt = shift;
my $template = shift;
$opt->{ base_path } ||= '.';
my $element_prefix = $opt->{ element_prefix } || $opt->{ prefix };
my $type_prefix = $opt->{ type_prefix } || $opt->{ prefix };
if (($type_prefix) && ($type_prefix !~m{ :: $ }xms ) ) {
warn 'type_prefix should end with "::"';
$type_prefix .= '::';
}
if (($element_prefix) && ($element_prefix !~m{ :: $ }xms) ) {
warn 'element_prefix should end with "::"';
$element_prefix .= '::';
}
# Be careful: a Element may be ComplexType, too
# (but not vice versa)
my $prefix = $self->isa('SOAP::WSDL::XSD::Element')
? $element_prefix
: $type_prefix;
die 'No prefix specified' if not $prefix;
my $filename = $prefix . $self->get_name() . '.pm';
$filename =~s{::}{/}xmsg;
my $output = $opt->{ output } || $filename;
require Template;
my $tt = Template->new(
RELATIVE => 1,
OUTPUT_PATH => $opt->{ base_path },
);
my $code = $tt->process( \$template, {
element_prefix => $element_prefix,
type_prefix => $type_prefix,
self => $self,
nsmap => { reverse %{ $opt->{ wsdl }->get_xmlns() } },
structure => $self->explain( { wsdl => $opt->{ wsdl } } ),
},
$output
)
or die $tt->error();
}
1;

View File

@@ -2,51 +2,50 @@ package SOAP::WSDL::Binding;
use strict;
use warnings;
use Class::Std::Storable;
use List::Util qw(first);
use base qw(SOAP::WSDL::Base);
my %operation_of :ATTR(:name<operation> :default<()>);
my %type_of :ATTR(:name<type> :default<()>);
my %transport_of :ATTR(:name<transport> :default<()>);
my %style_of :ATTR(:name<style> :default<()>);
sub explain {
my $self = shift;
my $opt = shift;
sub explain {
my $self = shift;
my $opt = shift;
my $name = $self->get_name();
my %ns_map = reverse %{ $opt->{ wsdl }->get_xmlns() };
my ($prefix, $localname) = split /:/ , $self->get_type();
die 'required atribute wsdl missing' if not $opt->{ wsdl };
my $portType = $opt->{ wsdl }->find_portType(
$ns_map{ $prefix }, $localname
) or die "portType $prefix:$localname not found !";
$opt->{ wsdl }->_expand( $self->get_type() )
) or die 'portType not found: ' . $self->get_type();
my $txt = <<"EOT";
=head2 SOAP Operations
my $txt = <<"EOT";
B<Note:>
=head2 Binding name: $name
=over
=item * Style $style_of{ ident $self }
=item * Transport $transport_of{ ident $self }
=back
=head3 Operations
Input, output and fault messages are stated as perl hash refs.
These are only for informational purposes - the actual implementation
normally uses object trees, not hash refs, though the input messages
may be passed to the respective methods as hash refs and will be
converted to object trees automatically.
EOT
foreach my $operation (@{ $self->get_operation() })
{
foreach my $operation (@{ $self->get_operation() }) {
my $operation_name = $operation->get_name();
my $operation_style = $operation->get_style() || q{};
my $port_operation = $portType->find_operation( $ns_map{ $prefix },
$operation->get_name() )
or die "operation not found:" . $operation->get_name();
my $port_operation = first { $_->get_name eq $operation_name }
@{ $portType->get_operation() }
or die "operation not found:" . $operation->get_name();
# TODO rename lexical $input to "message"
my $input_message = do {
my $input = $port_operation->first_input();
@@ -60,69 +59,55 @@ EOT
my $input = $port_operation->first_fault();
$input ? $input->explain($opt) : q{};
};
$txt .= <<"EOT";
$txt .= <<"EOT";
=over
=head3 $operation_name
=item * $operation_name
=over 8
=item * Style: $operation_style
=item * Input Message:
B<Input Message:>
$input_message
=item * Output Message:
B<Output Message:>
$output_message
=item * Fault:
B<Fault:>
$fault_message
=back
=back
EOT
}
}
return $txt;
return $txt;
}
sub to_typemap {
my ($self, $opt) = @_;
my $name = $self->get_name();
my %ns_map = reverse %{ $opt->{ wsdl }->get_xmlns() };
my ($prefix, $localname) = split /:/ , $self->get_type();
my $portType = $opt->{ wsdl }->find_portType(
$ns_map{ $prefix }, $localname
) or die "portType $prefix:$localname not found !";
$opt->{ wsdl }->_expand( $self->get_type )
) or die 'portType not found: ' . $self->get_type;
my $txt = q{};
foreach my $operation (@{ $self->get_operation() })
{
my $operation_name = $operation->get_name();
my $operation_style = $operation->get_style() || q{};
my $port_operation = $portType->find_operation( $ns_map{ $prefix },
$operation->get_name() )
or die "operation not found:" . $operation->get_name();
# TODO rename lexical $input to "message"
$txt .= do {
my $input = $port_operation->first_input();
$input ? $input->to_typemap($opt) : q{};
};
$txt .= do {
my $input = $port_operation->first_output();
$input ? $input->to_typemap($opt) : q{};
};
$txt .= do {
my $input = $port_operation->first_fault();
$input ? $input->to_typemap($opt) : q{};
};
my ($port_operation) = grep { $_->get_name eq $operation_name }
@{ $portType->get_operation() }
or die "operation not found:" . $operation->get_name();
no strict qw(refs);
$txt .= join q{},
map {
my $message = $port_operation->$_;
$message
? $message->to_typemap($opt)
: q{}
} qw(first_input first_output first_fault);
}
return $txt;
}

View File

@@ -1,279 +1,73 @@
package SOAP::WSDL::Client;
use strict;
use warnings;
use vars qw/$AUTOLOAD/;
use Carp;
use Scalar::Util qw(blessed);
use SOAP::WSDL::Envelope;
use SOAP::WSDL::SAX::WSDLHandler;
use SOAP::Lite;
use Class::Std::Storable;
use SOAP::WSDL::Expat::MessageParser;
use SOAP::WSDL::SOAP::Typelib::Fault11;
# Package globals for speed...
my $PARSER;
my $MESSAGE_HANDLER;
my %class_resolver_of :ATTR(:name<class_resolver> :default<()>);
my %no_dispatch_of :ATTR(:name<no_dispatch> :default<()>);
my %outputxml_of :ATTR(:name<outputxml> :default<()>);
my %proxy_of :ATTR(:name<proxy> :default<()>);
# TODO remove when preparing 2.01
sub outputtree { warn 'outputtree is deprecated and'
. 'will be removed before reaching v2.01 !' }
SUBFACTORY: {
no strict qw(refs);
for (qw(class_resolver no_dispatch outputxml proxy)) {
my $setter = "set_$_";
my $getter = "get_$_";
*{ $_ } = sub { my $self = shift;
if (@_) {
$self->$setter(@_);
return $self;
}
return $self->$getter()
};
}
}
BEGIN {
eval {
use XML::LibXML;
};
if ($@) {
use XML::SAX::ParserFactory;
}
}
use base qw/SOAP::Lite/;
sub outputtree {
my $self = shift;
return $self->{ _WSDL }->{ outputtree } if not @_;
return $self->{ _WSDL }->{ outputtree } = shift;
}
sub class_resolver {
my $self = shift;
return $self->{ _WSDL }->{ class_resolver } if not @_;
return $self->{ _WSDL }->{ class_resolver } = shift;
}
sub wsdlinit
{
my $self = shift;
my $wsdl_xml = SOAP::Schema->new( schema_url => $self->wsdl() )->access(
$self->wsdl()
);
my $filter;
my $parser = eval { XML::LibXML->new() };
if ($parser) {
$filter = SOAP::WSDL::SAX::WSDLHandler->new();
$parser->set_handler( $filter );
}
else {
$filter = SOAP::WSDL::SAX::WSDLHandler->new( base => 'XML::SAX::Base' );
$parser = XML::SAX::ParserFactory->parser( Handler => $filter );
}
$parser->parse_string( $wsdl_xml );
my $wsdl_definitions = $filter->get_data()
or die "unable to parse WSDL";
my $types = $wsdl_definitions->first_types()
or die "unable to extract schema from WSDL";
my $ns = $wsdl_definitions->get_xmlns()
or die "unable to extract XML Namespaces" . $wsdl_definitions->to_string;
( %{ $ns } ) or die "unable to extract XML Namespaces";
# setup lookup variables
$self->{ _WSDL }->{ wsdl_definitions } = $wsdl_definitions;
$self->{ _WSDL }->{ serialize_options } = {
autotype => 0,
readable => 1,
typelib => $types,
namespace => $ns,
};
$self->{ _WSDL }->{ explain_options } = {
readable => 1,
wsdl => $wsdl_definitions,
namespace => $ns,
typelib => $types,
};
return $self;
} ## end sub wsdlinit
sub _wsdl_get_service
{
my $self = shift;
my $service;
my $wsdl = $self->{ _WSDL }->{ wsdl_definitions };
my $ns = $wsdl->get_targetNamespace();
if ( $self->{ _WSDL }->{ servicename } )
{
$service =
$wsdl->find_service( $ns, $self->{ _WSDL }->{ servicename } );
}
else
{
$service = $wsdl->get_service()->[ 0 ];
warn "no servicename specified - using " . $service->get_name();
}
return $self->{ _WSDL }->{ service } = $service;
} ## end sub _wsdl_get_service
sub _wsdl_get_port
{
my $self = shift;
my $service = $self->{ _WSDL }->{ service }
|| $self->_wsdl_get_service();
my $wsdl = $self->{ _WSDL }->{ wsdl_definitions };
my $ns = $wsdl->get_targetNamespace();
my $port;
if ( $self->{ _WSDL }->{ portname } )
{
$port = $service->get_port( $ns, $self->{ _WSDL }->{ portname } );
}
else
{
$port = $service->get_port()->[ 0 ];
}
$self->{ _WSDL }->{ port } = $port;
# preload portType
$self->_wsdl_get_portType();
# Auto-set proxy - required before issuing call()
$self->proxy( $port->get_location() );
return $port;
} ## end sub _wsdl_get_port
sub _wsdl_get_binding
{
my $self = shift;
my $wsdl = $self->{ _WSDL }->{ wsdl_definitions };
my $ns = $wsdl->get_targetNamespace();
my $port = $self->{ _WSDL }->{ port }
|| $self->_wsdl_get_port();
my ( $prefix, $localname ) = split /:/, $port->get_binding();
# TODO lookup $ns instead of just using
# the top element's targetns...
my $binding = $wsdl->find_binding( $ns, $localname )
or die "no binding found for ", $port->get_binding();
return $self->{ _WSDL }->{ binding } = $binding;
} ## end sub _wsdl_get_binding
sub _wsdl_get_portType
{
my $self = shift;
my $wsdl = $self->{ _WSDL }->{ wsdl_definitions };
my $binding = $self->{ _WSDL }->{ binding }
|| $self->_wsdl_get_binding();
my $ns = $wsdl->get_targetNamespace();
my ( $prefix, $localname ) = split /:/, $binding->get_type();
my $portType = $wsdl->find_portType( $ns, $localname );
$self->{ _WSDL }->{ portType } = $portType;
return $portType;
} ## end sub _wsdl_get_portType
=pod
=head2 _wsdl_init_methods
=over
=item DESCRIPTION
Creates a lookup table containing the information required for all methods
specified for the service/port selected.
The lookup table is used by L<call|call>.
=back
=cut
sub _wsdl_init_methods {
my $self = shift;
my $wsdl = $self->{ _WSDL }->{ wsdl_definitions };
my $ns = $wsdl->get_targetNamespace();
# get bindings, portType, message, part(s)
# - use cached values where possible for speed,
# private methods if not for clear separation...
my $binding = $self->{ _WSDL }->{ binding }
|| $self->_wsdl_get_binding();
my $portType = $self->{ _WSDL }->{ portType }
|| $self->_wsdl_get_portType();
my $methodHashRef = {};
foreach my $binding_operation (@{ $binding->get_operation() })
{
my $method = {};
# get SOAP Action
# SOAP-Action is a required HTTP Header, so we need to look it up...
my $soap_binding_operation = $binding_operation->get_operation()->[0];
$method->{ soap_action } = $soap_binding_operation ?
$soap_binding_operation->get_soapAction() : $method;
# get parts
# 1. get operation from port
my $operation = $portType->find_operation( $ns,
$binding_operation->get_name() );
# 2. get input message name
my ( $prefix, $localname ) = split /:/,
$operation->get_input()->[0]->get_message();
# 3. get input message
my $message = $wsdl->find_message( $ns, $localname );
$method->{ parts } = $message->get_part();
# rpc / encoded methods may have a namespace specified.
# look it up and set it...
$method->{ namespace } = $binding_operation ?
$binding_operation->get_input()->[0]->get_namespace() : undef;
$methodHashRef->{ $binding_operation->get_name() } = $method;
}
$self->{ _WSDL }->{ methodInfo } = $methodHashRef;
return $methodHashRef;
$PARSER = SOAP::WSDL::Expat::MessageParser->new();
}
sub call {
my $self = shift;
my $method = shift;
my $data = ref $_[0] ? $_[0] : { @_ };
my $self = shift;
my $method = shift;
my $data = ref $_[0] ? $_[0] : { @_ };
my $content = q{};
my $envelope;
my $methodInfo;
if (blessed $data
my ($envelope, $soap_action);
if (blessed $data
&& $data->isa('SOAP::WSDL::XSD::Typelib::Builtin::anyType'))
{
$envelope = SOAP::WSDL::Envelope->serialize( $method, $data );
# TODO replace by something derived from binding - this is just a
# TODO replace by something derived from binding - this is just a
# workaround...
$methodInfo->{ soap_action }
= join '/', $data->get_xmlns(), $method;
}
else {
my $methodLookup = $self->{ _WSDL }->{ methodInfo }
|| $self->_wsdl_init_methods();
$methodInfo = $methodLookup->{ $method };
my $partListRef = $methodInfo->{ parts };
# set serializer options
# TODO allow custom options here
my $opt = $self->{ _WSDL }->{ serialize_options };
# set response target namespace
# TODO make rpc-encoded encoding recognise this namespace
# $opt->{ targetNamespace } = $soap_binding_operation ?
# $operation->input()->namespace() : undef;
# serialize content
# TODO create surrounding element for rpc-encoded messages
foreach my $part ( @{ $partListRef } )
{
$content .= $part->serialize( $method, $data, $opt );
}
$envelope = SOAP::WSDL::Envelope->serialize(
$method, $content , $opt );
};
$soap_action = join '/', $data->get_xmlns(), $method;
}
else {
$envelope = SOAP::WSDL::Envelope->serialize( $method, $data );
# $soap_action = $self->on_action( $method );
}
if ( $self->no_dispatch() )
{
return $envelope;
} ## end if ( $self->no_dispatch...
return $envelope if $self->no_dispatch();
# warn $envelope;
# get response via transport layer
# TODO remove dependency from SOAP::Lite and use a
# get response via transport layer
# TODO remove dependency from SOAP::Lite and use a
# SAX-based filter using XML::LibXML to get the
# result.
# Filter should have the following methods:
@@ -283,146 +77,119 @@ sub call {
# - fault: returns the result of the call if a SOAP fault is sent back
# by the server. Retuns undef (nothing) if the call has been
# processed without errors.
my $response = $self->transport->send_receive(
my $soap = SOAP::Lite->new()->proxy( $self->get_proxy() );
my $response = $soap->transport->send_receive(
context => $self, # this is provided for context
endpoint => $self->endpoint(),
action => $methodInfo->{ soap_action }, # SOAPAction from binding
endpoint => $soap->endpoint(),
action => $soap_action, # SOAPAction, should be from binding
envelope => $envelope, # use custom content
);
return $response if ($self->outputxml() );
# warn 'Received ' . length($response) . ' bytes of content';
return $response if ($self->outputxml() );
if ($self->outputtree()) {
$PARSER->class_resolver( $self->get_class_resolver() );
my ($parser, $handler); # replace by globals - singleton is faster
if (not $parser) {
require SOAP::WSDL::SOAP::Typelib::Fault11;
require SOAP::WSDL::SAX::MessageHandler;
require XML::LibXML;
$handler = SOAP::WSDL::SAX::MessageHandler->new(
{ class_resolver => $self->class_resolver() },
);
$parser = XML::LibXML->new();
$parser->set_handler( $handler);
}
# if we had no success (Transport layer error status code)
# or if transport layer failed
if (! $self->transport->is_success() ) {
# Try deserializing response - there may be some
if ($response) {
eval { $parser->parse_string( $response ) };
return $handler->get_data if not $@;
};
# generate & return fault if we cannot serialize response
# or have none...
return SOAP::WSDL::SOAP::Typelib::Fault11->new({
faultcode => 'soap:Server',
faultactor => 'urn:localhost',
faultstring => 'Error sending / receiving message: '
. $self->transport->message()
});
}
# if we had no success (Transport layer error status code)
# or if transport layer failed
if (! $soap->transport->is_success() ) {
# Try deserializing response - there may be some
if ($response) {
eval { $PARSER->parse( $response ); };
if ($@) {
warn "could not deserialize response: $@";
}
else {
return $PARSER->get_data();
}
};
eval { $parser->parse_string( $response ) };
# return fault if we cannot deserialize response
if ($@) {
return SOAP::WSDL::SOAP::Typelib::Fault11->new({
faultcode => 'soap:Server',
faultactor => 'urn:localhost',
faultstring => "Error deserializing message: $@. \n"
. "Message was: \n$response"
});
}
return $handler->get_data();
require SOAP::WSDL::SOAP::Typelib::Fault11;
# generate & return fault if we cannot serialize response
# or have none...
return SOAP::WSDL::SOAP::Typelib::Fault11->new({
faultcode => 'soap:Server',
faultactor => 'urn:localhost',
faultstring => 'Error sending / receiving message: '
. $soap->transport->message()
});
}
eval { $PARSER->parse( $response ) };
# return fault if we cannot deserialize response
if ($@) {
return SOAP::WSDL::SOAP::Typelib::Fault11->new({
faultcode => 'soap:Server',
faultactor => 'urn:localhost',
faultstring => "Error deserializing message: $@. \n"
. "Message was: \n$response"
});
}
# deserialize and store result
my $result = $self->{ '_call' } =
eval { $self->deserializer->deserialize( $response ) }
if $response;
if (
!$self->transport->is_success || # transport fault
$@ || # not deserializible
# fault message even if transport OK
# or no transport error (for example, fo TCP, POP3, IO implementations)
UNIVERSAL::isa( $result => 'SOAP::SOM' ) && $result->fault
)
{
return $self->{ '_call' } = (
$self->on_fault->(
$self, $@ ? $@ . ( $response || '' ) : $result
)
|| $result
);
# ? # trick editors
} ## end if ( !$self->transport...
return unless $response; # nothing to do for one-ways
return $result;
return $PARSER->get_data();
} ## end sub call
sub explain
{
my $self = shift;
my $opt = $self->{ _WSDL }->{ explain_options };
return $self->{ _WSDL }->{ wsdl_definitions }->explain( $opt );
} ## end sub explain
sub _load_method
{
my $method = shift;
no strict "refs";
*$method = sub {
my $self = shift;
return ( @_ ) ? $self->{ _WSDL }->{ $method } = shift
: $self->{ _WSDL }->{ $method }
};
} ## end sub _load_method
&_load_method( 'no_dispatch' );
&_load_method( 'wsdl' );
sub servicename
{
my $self = shift;
return $self->{ _WSDL }->{ servicename } if ( not @_ );
$self->{ _WSDL }->{ servicename } = shift;
my $ns = $self->{ _WSDL }->{ wsdl_definitions }->get_targetNamespace();
$self->{ _WSDL }->{ service } =
$self->{ _WSDL }->{ wsdl_definitions }
->find_service( $ns, $self->{ _WSDL }->{ servicename } )
or die "No such service: " . $self->{ _WSDL }->{ servicename };
} ## end sub servicename
sub portname
{
my $self = shift;
return $self->{ _WSDL }->{ portname } if ( not @_ );
$self->{ _WSDL }->{ portname } = shift;
my $ns = $self->{ _WSDL }->{ wsdl_definitions }->targetNamespace();
$self->{ _WSDL }->{ port } =
$self->{ _WSDL }->{ service }
->get_port( $ns, $self->{ _WSDL }->{ portname } )
or die "No such port: " . $self->{ _WSDL }->{ portname };
} ## end sub portname
1;
=pod
=head1 Auto-Dispatching
=head2 Features different from SOAP::Lite
SOAP::WSDL does not aim to be a complete replacement for SOAP::Lite - the
SOAP::Lite module has it's strengths and weaknesses and SOAP::WSDL is
designed as a cure for the weakness of little WSDL support - nothing more,
nothing less.
Nonetheless SOAP::WSDL mimics part of SOAP::Lite's API and behaviour,
so SOAP::Lite users can switch without looking up every method call in the
documentation.
A few things are quite differentl from SOAP::Lite, though:
=head3 SOAP request data
SOAP request data may either be given as message object, or as hash ref (in
which case it will automatically be encoded into a message object).
=head3 Return values
The result from call() is not a SOAP::SOM object, but a message object.
Message objects' classes may be generated from WSDL definitions automatically
- see SOAP::WSDL::Generator::Typelib on how to generate your own WSDL based
message class library.
=head3 Fault handling
SOAP::WSDL::Client returns a fault object on errors, even on transport layer
errors.
The fault object is a SOAP1.1 fault object of the following
C<SOAP::WSDL::SOAP::Typelib::Fault11>.
SOAP::WSDL::SOAP::Typelib::Fault11 objects are false in boolean context, so
you can just do something like
my $result = $soap->call($method, $data);
if ($result) {
# handle result
}
else {
die $result->faultstring();
}
=head3 outputxml
SOAP::Lite returns only the content of the SOAP body when outputxml is set
to true. SOAP::WSDL::Client returns the complete XML response.
=head3 Auto-Dispatching
SOAP::WSDL::Client does B<does not> support auto-dispatching.
This is on purpose: You may easily create interface classes by using
This is on purpose: You may easily create interface classes by using
SOAP::WSDL::Client and implementing something like
sub mySoapMethod {
@@ -430,17 +197,9 @@ SOAP::WSDL::Client and implementing something like
$soap_wsdl_client->call( mySoapMethod, @_);
}
You may even do this in a class factory - SOAP::WSDL provides the methods
You may even do this in a class factory - SOAP::WSDL provides the methods
for generating such interfaces.
SOAP::Lite's autodispatching mechanism is - though convenient - a constant
source of errors: Every typo in a method name gets caught by AUTOLOAD and
may lead to unpredictable results.
=cut
sub AUTOLOAD
{
my $method = substr($AUTOLOAD, rindex($AUTOLOAD, '::') + 2);
die "$method not found";
}

View File

@@ -1,31 +1,48 @@
#!/usr/bin/perl -w
package SOAP::WSDL::Client::Base;
##################################################################################
## <OWNER>Internetteam
## <AUTHOR>Martin Kutter <martin.kutter@siemens.com>
## <CREATIONDATE>25.10.2006
##
## <FUNCTION>Base client for WSDL-based SOAP access
## Automatisch gefüllt:
## <CVSPROJECT>$HeadURL:$
## <REVISION>$Revision:$
################################################################################
use strict;
use Log::Log4perl;
use warnings;
use base 'SOAP::WSDL::Client';
use Class::Accessor;
sub __create_new {
my ($package, %args_of) = @_;
no strict qw(refs);
*{ "$package\::new" } = sub {
my $class = shift;
my $self = $class->SUPER::new({
proxy => $args_of{ proxy },
class_resolver => $args_of{ class_resolver }
});
bless $self, $class;
return $self;
}
}
use base qw/Class::Accessor/;
sub __create_methods {
my ($package, %parts_of) = @_;
no strict qw(refs);
for my $method (keys %parts_of){
*{ "$package\::$method" } = sub {
my $self = shift;
my @param = map {
my $data = shift || {};
eval "require $_";
$_->new( $data );
} @{ $parts_of{ $method } };
$self->call( $method, @param );
}
}
$SOAP::WSDL::Client::Base::VERSION = sprintf("0.%d", q$LastChangedRevision: 1$ =~/(\d+)/ );
}
__PACKAGE__->mk_accessors(
qw//
);
1;
my $log = undef; # Global logger to speed up performance
__END__
=pod
@@ -35,93 +52,9 @@ SOAP::WSDL::Client::Base - Base client for WSDL-based SOAP access
=head1 SYNOPSIS
package MySoapClient;
use SOAP::WSDL::Client::Base;
# TODO Add more Synopsis information
=head1 DESCRIPTION
# TODO Add Description
=cut
=pod
=head2 new
=over
=item SYNOPSIS
my $obj = ->new();
=item DESCRIPTION
Constructor.
=back
=cut
sub new
{
my $proto = shift;
my $class = ref $proto || $proto;
my $self = {
soapBindingStyle => 'rpc',
};
bless $self, $class;
$self->init(@_);
return $self;
}
sub soapBindingStyle
{
my $self = shift;
my $style = shift;
if ($style)
{
die "Binding style must be one of rpc|document"
if (not( $style=~m/^(rpc|document)$/));
$self->{ soapBindingStyle } = $style;
}
return $self->{ soapBindingStyle };
}
sub init
{
}
sub call
{
my $self = shift;
my $method = shift;
my $data = shift;
my $content;
}
1;
__END__
=pod
=head1 AUTHOR
Martin Kutter <martin.kutter@siemens.com>
=head1 COPYING
Copyright (c) 2005 SIEMENS AG. All rights reserved.
=head1 Repository information
$ID: $
$LastChangedDate: $
$LastChangedRevision: $
$LastChangedBy: $
$HeadURL: $
__PACKAGE__->__create_methods( qw(one two three) );
1;
=cut

View File

@@ -1,6 +1,10 @@
package SOAP::WSDL::Definitions;
use strict;
use warnings;
use Carp;
use File::Basename;
use File::Path;
use List::Util qw(first);
use Class::Std::Storable;
use base qw(SOAP::WSDL::Base);
@@ -9,11 +13,10 @@ my %message_of :ATTR(:name<message> :default<()>);
my %portType_of :ATTR(:name<portType> :default<()>);
my %binding_of :ATTR(:name<binding> :default<()>);
my %service_of :ATTR(:name<service> :default<()>);
my %namespace_of :ATTR(:name<namespace> :default<()>);
my %attributes_of :ATTR();
my %namespace_of :ATTR(:name<namespace> :default<()>);
# must be attr for Class::Std::Storable
my %attributes_of :ATTR();
%attributes_of = (
binding => \%binding_of,
message => \%message_of,
@@ -23,40 +26,437 @@ my %attributes_of :ATTR();
# Function factory - we could be writing this method for all %attribute
# keys, too, but that's just C&P (eehm, Copy & Paste...)
foreach my $method(keys %attributes_of ) {
no strict qw/refs/;
# ... btw, we mean this method here...
*{ "find_$method" } = sub {
my ($self, @args) = @_;
my @found_at = grep {
$_->get_targetNamespace() eq $args[0] &&
$_->get_name() eq $args[1]
}
@{ $attributes_of{ $method }->{ ident $self } };
return $found_at[0];
};
}
BLOCK: {
no strict qw/refs/;
foreach my $method(keys %attributes_of ) {
*{ "find_$method" } = sub {
my ($self, @args) = @_;
return first {
$_->get_targetNamespace() eq $args[0]
&& $_->get_name() eq $args[1]
}
@{ $attributes_of{ $method }->{ ident $self } };
};
}
}
sub explain {
my $self = shift;
my $opt = shift;
my $txt = '';
foreach my $service (@{ $self->get_service() })
{
$txt .= $service->explain( $opt );
$txt .= "\n";
}
return $txt;
}
sub to_typemap {
my $self = shift;
my $opt = shift;
$opt->{ wsdl } ||= $self;
$opt->{ namespace } ||= $self->get_xmlns() || {};
my $txt = '';
for my $service (@{ $self->get_service() }) {
$txt .= $service->explain( $opt );
$txt .= "\n";
}
return $txt;
}
sub _expand {
my ($self, $prefix, $localname) = ($_[0], split /:/, $_[1]);
my %ns_map = reverse %{ $self->get_xmlns() };
return ($ns_map{ $prefix }, $localname);
}
sub to_typemap {
my $self = shift;
my $opt = shift;
$opt->{ prefix } ||= q{};
$opt->{ wsdl } ||= $self;
$opt->{ type_prefix } ||= $opt->{ prefix };
$opt->{ element_prefix } ||= $opt->{ prefix };
return join "\n",
map { $_->to_typemap( $opt ) } @{ $service_of{ ident $self } };
}
sub create {
my $self = shift;
my $opt = shift;
my $base_path = $opt->{ base_path }
or croak "missing or empty argument base_path";
$opt->{ prefix } ||= q{};
$opt->{ type_prefix } ||= $opt->{ prefix };
$opt->{ element_prefix } ||= $opt->{ prefix };
$opt->{ typemap_prefix } or die 'Required argument typemap_prefix missing';
mkpath $base_path;
for my $service (@{ $service_of{ ident $self } }) {
warn "creating typemap $opt->{ typemap_prefix }". $service->get_name() . "\n";
$self->_create_typemap({ %{ $opt }, service => $service });
$self->_create_interface({ %{ $opt }, service => $service });
}
my @schema = @{ $self->first_types()->get_schema() };
for my $type (map { @{ $_->get_type() } , @{ $_->get_element() } } @schema[1..$#schema] ) {
warn 'creating class for '. $type->get_name() . "\n";
$type->to_class( { %$opt, wsdl => $self } );
}
}
sub _create_interface {
my $self = shift;
my $opt = shift;
my $service_name = $opt->{ service }->get_name();
my $file_name = "$opt->{ base_path }/$opt->{ interface_prefix }/$service_name.pm";
$file_name =~s{::}{/}gms;
my $path = dirname $file_name;
my $name = basename $file_name;
my $binding = $self->find_binding( $self->_expand( $opt->{ service }->first_port()->get_binding() ) );
my $portType = $self->find_portType( $self->_expand( $binding->get_type() ) );
my $portType_operation_from_ref = $portType->get_operation();
my $operation_ref = $binding->get_operation();
$operation_ref = [ $operation_ref ] if ref $operation_ref ne 'ARRAY';
my %operations = map {
do {
my $operation_name = $_->get_name();
my $port_op = first { $_->get_name eq $operation_name } @{ $portType_operation_from_ref };
my $input = $port_op->first_input()->get_message();
my $message = $self->find_message( $self->_expand( $input ) );
my $parts = $message->get_part;
( $operation_name => [
map {
do {
my $name;
($name = $_->get_element())
? do {
my ($prefix, $localname) = split m{:}xms , $name;
"$opt->{ element_prefix }$localname";
}
: ($name = $_->get_type())
? do {
my ($prefix, $localname) = split m{:}xms , $name;
"$opt->{ type_prefix }$localname";
}
: ()
}
} @{ $parts }
] );
};
} @{ $operation_ref };
# use Data::Dumper;
# die Dumper \%operations;
my $template = <<'EOT';
package [% interface_prefix %][% service.get_name %];
use strict;
use warnings;
use [% typemap_prefix %][% service.get_name %];
use base 'SOAP::WSDL::Client::Base';
sub new {
my $class = shift;
my $arg_ref = shift || {};
my $self = $class->SUPER::new({
class_resolver => '[% typemap_prefix %][% service.get_name %]',
proxy => '[% service.first_port.get_location %]',
%{ $arg_ref }
});
return bless $self, $class;
}
__PACKAGE__->__create_methods(
[% FOREACH name = operations.keys -%]
[% name %] => [ [% FOREACH class = operations.$name %]'[% class %]', [% END %]],
[% END %]
);
1;
__END__
=pod
=head1 NAME
[% interface_prefix %][% service.get_name %] - SOAP interface to [% service.get_name %] at
[% service.first_port.get_location %]
=head1 SYNOPSIS
my $interface = [% interface_prefix %][% service.get_name %]->new();
my $[% operations.keys.1 %] = $interface->[% operations.keys.1 %]();
[% service.explain({ wsdl => wsdl }) %]
=cut
EOT
require Template;
my $tt = Template->new(
OUTPUT_PATH => $path,
);
$tt->process(\$template, { %{ $opt }, operations => \%operations, binding => $binding, wsdl => $self }, $name)
or die $tt->error();
return 1;
}
sub _create_typemap {
my $self = shift;
my $opt = shift;
my $service_name = $opt->{ service }->get_name();
my $file_name = "$opt->{ base_path }/$opt->{ typemap_prefix }/$service_name.pm";
$file_name =~s{::}{/}gms;
my $path = dirname $file_name;
my $name = basename $file_name;
my $typemap = $opt->{ service }->to_typemap( { %{ $opt }, wsdl => $self } );
my $template = <<'EOT';
package [% typemap_prefix %][% service.get_name %];
use strict;
use warnings;
my %typemap = (
[% typemap %]
[% custom_types %]
);
sub get_class {
my $name = join '/', @{ $_[1] };
exists $typemap{ $name } or die "Cannot resolve $name via " . __PACKAGE__;
return $typemap{ $name };
}
1;
__END__
EOT
require Template;
my $tt = Template->new(
OUTPUT_PATH => $path,
);
$tt->process(\$template, { %{ $opt }, typemap => $typemap }, $name)
or die $tt->error();
}
sub listify {
my $data = shift;
return if not defined $data;
return [ $data ] if not ref $data;
return [ $data ] if not ref $data eq 'ARRAY';
return $data;
}
1;
=pod
=head1 NAME
SOAP::WSDL::Definitions - model a WSDL E<gt>definitionsE<lt> element
=head1 DESCRIPTION
=head1 METHODS
=head2 first_service get_service set_service push_service
Accessors/Mutators for accessing / setting the E<gt>serviceE<lt> child
element(s).
=head2 find_service
Returns the service matching the namespace/localname pair passed as arguments.
my $service = $wsdl->find_service($namespace, $localname);
=head2 first_binding get_binding set_binding push_binding
Accessors/Mutators for accessing / setting the E<gt>bindingE<lt> child
element(s).
=head2 find_service
Returns the binding matching the namespace/localname pair passed as arguments.
my $binding = $wsdl->find_binding($namespace, $localname);
=head2 first_portType get_portType set_portType push_portType
Accessors/Mutators for accessing / setting the E<gt>portTypeE<lt> child
element(s).
=head2 find_portType
Returns the portType matching the namespace/localname pair passed as arguments.
my $portType = $wsdl->find_portType($namespace, $localname);
=head2 first_message get_message set_message push_message
Accessors/Mutators for accessing / setting the E<gt>messageE<lt> child
element(s).
=head2 find_service
Returns the message matching the namespace/localname pair passed as arguments.
my $message = $wsdl->find_message($namespace, $localname);
=head2 first_types get_types set_types push_types
Accessors/Mutators for accessing / setting the E<gt>typesE<lt> child
element(s).
=head2 explain
Returns a POD string describing how to call the methods of the service(s)
described in the WSDL.
=head2 to_typemap
Creates a typemap for use with a generated type class library.
Options:
NAME DESCRIPTION
-------------------------------------------------------------------------
prefix Prefix to use for all classes
type_prefix Prefix to use for all (Complex/Simple)Type classes
element_prefix Prefix to use for all Element classes (with atomic types)
As some webservices tend to use globally unique type definitions, but
locally unique elements with atomic types, type and element classes may
be separated by specifying type_prefix and element_prefix instead of
prefix.
The typemap is plain text which can be used as snipped for building a
SOAP::WSDL class_resolver perl class.
Try something like this for creating typemap classes:
my $parser = XML::LibXML->new();
my $handler = SOAP::WSDL::SAX::WSDLHandler->new()
$parser->set_handler( $handler );
$parser->parse_url('file:///path/to/wsdl');
my $wsdl = $handler->get_data();
my $typemap = $wsdl->to_typemap();
print <<"EOT"
package MyTypemap;
my \%typemap = (
$typemap
);
sub get_class { return \$typemap{\$_[1] } };
1;
"EOT"
=head2 create_interface
Creates a typemap class, classes for all types and elements, and interface
classes for every service.
See L<CODE GENERATOR|CODE GENERATOR> below.
Options:
Name Description
----------------------------------------------------------------------------
prefix Prefix to use for types and elements. Should end with '::'.
element_prefix Prefix to use for element packages. Should end with '::'.
Must be specified if prefix is not given.
type_prefix Prefix to use for type packages. Should end with '::'.
Must be specified if prefix is not given.
typemap_prefix Prefix to use for type packages. Should end with '::'.
Mandatory.
custom_types A perl source code snippet defining custom types for the
class resolver (typemap).
Must look like this:
q{
'path/to/my/element' => 'My::Element',
'path/to/my/element/prop' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
'path/to/my/element/prop2' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
};
=head2 _expand
Expands a qualified name into a list consisting of namespace URI and
localname by using the definition's xmlns table.
Used internally by SOAP::WSDL::* classes.
=head1 CODE GENERATOR
TODO: move somewhere else - maybe SOAP::WSDL::Client ?
SOAP::WSDL::Definitions features a code generation facility for generating
perl classes (packages) from a WSDL definition.
The following classes are generated:
=over
=item * Typemaps
A typemap class is created for every service.
Typemaps are basically lookup classes. They allow the
SOAP::WSDL::SAX::MessageHandler to find out which class a XML element
in a SOAP message shoud be processed as.
Typemaps are passed to SOAP::WSDL::Client via the class_resolver
method.
=item * Interfaces
TODO: Implement Interface generation
Interface classes are just convenience shortcuts for accessing web
service methods. They define a method for every web service method,
dispatching the request to SOAP::WSDL::Client.
=item * Type and Element classes
For every top-level E<lt>elementE<gt>, E<lt>complexTypeE<gt> and
E<lt>simpleTypeE<gt> definition in the WSDL's schema, a perl class is
created.
Classes for E<lt>complexTypeE<gt> and E<lt>simpleTypeE<gt> definitions
are prefixed by the C<type_prefix> argument passed to
L<create_interface|create_interface>, classes for E<lt>elementE<gt>
definitions are prefixed by the C<element_prefix> passed to
L<create_interface|create_interface>. If the specific prefixes are not
specified, the C<prefix> argument is used instead.
If your web service is part of a bigger framework which defines types
globally, you probably do well always using the same C<type_prefix>:
This reduces the number of classes generated (provided types
are re-used by more than one service).
You probably should use different element prefixes, though -
E<lt>elementE<gt> definitions tend to be unique in the defining WSDL
only, especially when using document/literal style/encoding.
If not, you probably want to specify just C<prefix> (and use a
different one for every web service).
=back
=head1 LICENSE
Copyright 2004-2007 Martin Kutter.
This file is part of SOAP-WSDL. You may distribute/modify it under
the same terms as perl itself
=head1 AUTHOR
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=cut

View File

@@ -0,0 +1,201 @@
#!/usr/bin/perl
package SOAP::WSDL::Expat::MessageParser;
use strict;
use warnings;
use SOAP::WSDL::XSD::Typelib::Builtin;
use XML::Parser::Expat;
=pod
=head2 new
=over
=item SYNOPSIS
my $obj = ->new();
=item DESCRIPTION
Constructor.
=back
=cut
sub new {
my $class = shift;
my $args = shift;
my $self = {
class_resolver => $args->{ class_resolver }
};
bless $self, $class;
return $self;
}
sub class_resolver {
my $self = shift;
$self->{ class_resolver } = shift;
}
sub parse {
my $self = shift;
my $xml = shift;
$self->{ data } = undef;
my $characters;
my $current = '__STOP__';
my $ignore = [ 'Envelope', 'Body' ];
my $list = [];
my $namespace = {};
my $path = [];
my $parser = XML::Parser::Expat->new();
no strict qw(refs);
$parser->setHandlers(
Start => sub {
my ($parser, $element, %attrs) = @_;
my ($prefix, $localname) = split m{:}xms , $element;
# for non-prefixed elements
if (not $localname) {
$localname = $element;
$prefix = q{};
}
# ignore top level elements
if (@{ $ignore } && $localname eq $ignore->[0]) {
shift @{ $ignore };
return;
}
# empty characters
$characters = q{};
push @{ $path }, $localname; # step down...
push @{ $list }, $current; # remember current
# resolve class of this element
my $class = $self->{ class_resolver }->get_class( $path )
or die "Cannot resolve class for "
. join('/', @{ $path }) . " via $self->{ class_resolver }";
# Check whether we have a primitive - we implement them as classes
# TODO replace with UNIVERSAL->isa()
# match is a bit faster if the string does not match, but WAY slower
# if $class matches...
# if (not $class=~m{^SOAP::WSDL::XSD::Typelib::Builtin}xms) {
if (index $class, 'SOAP::WSDL::XSD::Typelib::Builtin', 0 < 0) {
# check wheter there is a CODE reference for $class::new.
# If not, require it - all classes required here MUST
# define new()
# This is the same as $class->can('new'), but it's way faster
*{ "$class\::new" }{ CODE }
or eval "require $class" ## no critic qw(ProhibitStringyEval)
or die $@;
}
# create object
# set current object
$current = $class->new({ %attrs });
# remember top level element
defined $self->{ data }
or ($self->{ data } = $current);
},
Char => sub {
$characters .= $_[1];
},
End => sub {
my $element = $_[1];
my ($prefix, $localname) = split m{:}xms , $element;
# for non-prefixed elements
if (not $localname) {
$localname = $element;
$prefix = q{};
}
# This one easily handles ignores for us, too...
return if not ref $list->[-1];
if ( $current
->isa('SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType') ) {
$current->set_value( $characters );
}
# set appropriate attribute in last element
# multiple values must be implemented in base class
my $method = "add_$localname";
$list->[-1]->$method( $current );
# step up in path
pop @{ $path };
# step up in object hierarchy...
$current = pop @{ $list };
}
);
$parser->parse( $xml );
}
sub get_data {
my $self = shift;
return $self->{ data };
}
1;
=pod
=head1 NAME
SOAP::WSDL::Expat::MessageParser - Convert SOAP messages to custom object trees
=head1 SYNOPSIS
my $parser = SOAP::WSDL::Expat::MessageParser->new({
class_resolver => 'My::Resolver'
});
$parser->parse( $xml );
my $obj = $parser->get_data();
=head1 DESCRIPTION
Real fast expat based SOAP message parser.
See L<SOAP::WSDL::Parser> for details.
=head1 Bugs and Limitations
=over
=item * Ignores all namespaces
=item * Does not handle mixed content
=item * The SOAP header is ignored
=back
=head1 AUTHOR
Replace the whitespace by @ for E-Mail Address.
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 COPYING
This module may be used under the same terms as perl itself.
=head1 Repository information
$ID: $
$LastChangedDate: $
$LastChangedRevision: $
$LastChangedBy: $
$HeadURL: $

View File

@@ -0,0 +1,206 @@
#!/usr/bin/perl
package SOAP::WSDL::Expat::MessageStreamParser;
use strict;
use warnings;
use SOAP::WSDL::XSD::Typelib::Builtin;
use XML::Parser::Expat;
=pod
=head2 new
=over
=item SYNOPSIS
my $obj = ->new();
=item DESCRIPTION
Constructor.
=back
=cut
sub new {
my $class = shift;
my $self = {
class_resolver => shift->{ class_resolver }
};
bless $self, $class;
return $self;
}
sub class_resolver {
my $self = shift;
$self->{ class_resolver } = shift;
}
sub init {
my $self = shift;
my $xml = shift;
$self->{ data } = undef;
my $characters;
my $current = '__STOP__';
my $ignore = [ 'Envelope', 'Body' ];
my $list = [];
my $namespace = {};
my $path = [];
my $parser = XML::Parser::ExpatNB->new();
no strict qw(refs);
$parser->setHandlers(
Start => sub {
my ($parser, $element, %attrs) = @_;
my ($prefix, $localname) = split m{:}xms , $element;
# for non-prefixed elements
if (not $localname) {
$localname = $element;
$prefix = q{};
}
# ignore top level elements
if (@{ $ignore } && $localname eq $ignore->[0]) {
shift @{ $ignore };
return;
}
# empty characters
$characters = q{};
push @{ $path }, $localname; # step down...
push @{ $list }, $current; # remember current
# resolve class of this element
my $class = $self->{ class_resolver }->get_class( $path )
or die "Cannot resolve class for "
. join('/', @{ $path }) . " via $self->{ class_resolver }";
# Check whether we have a primitive - we implement them as classes
# TODO replace with UNIVERSAL->isa()
# match is a bit faster if the string does not match, but WAY slower
# if $class matches...
# if (not $class=~m{^SOAP::WSDL::XSD::Typelib::Builtin}xms) {
if (index $class, 'SOAP::WSDL::XSD::Typelib::Builtin', 0 < 0) {
# check wheter there is a CODE reference for $class::new.
# If not, require it - all classes required here MUST
# define new()
# This is the same as $class->can('new'), but it's way faster
*{ "$class\::new" }{ CODE }
or eval "require $class" ## no critic qw(ProhibitStringyEval)
or die $@;
}
# create object
# set current object
$current = $class->new({ %attrs });
# remember top level element
defined $self->{ data }
or ($self->{ data } = $current);
},
Char => sub {
$characters .= $_[1];
},
End => sub {
my $element = $_[1];
my ($prefix, $localname) = split m{:}xms , $element;
# for non-prefixed elements
if (not $localname) {
$localname = $element;
$prefix = q{};
}
# This one easily handles ignores for us, too...
return if not ref $list->[-1];
if ( $current
->isa('SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType') ) {
$current->set_value( $characters );
}
# set appropriate attribute in last element
# multiple values must be implemented in base class
my $method = "add_$localname";
$list->[-1]->$method( $current );
# step up in path
pop @{ $path };
# step up in object hierarchy...
$current = pop @{ $list };
}
);
return $parser;
}
sub get_data {
my $self = shift;
return $self->{ data };
}
1;
=pod
=head1 NAME
SOAP::WSDL::Expat::MessageStreamParser - Convert SOAP messages to custom object trees
=head1 SYNOPSIS
my $lwp = LWP::UserAgent->new();
my $parser = SOAP::WSDL::Expat::MessageParser->new({
class_resolver => 'My::Resolver'
});
my $chunk_parser = $parser->init();
# process response while it comes in, trying to read 32k chunks.
$lwp->request( $request, sub { $chunk_parser->parse_more($_[0]) } , 32468 );
$chunk_parser->parse_done();
my $obj = $parser->get_data();
=head1 DESCRIPTION
ExpatNB based parser for parsing huge documents.
See L<SOAP::WSDL::Parser> for details.
=head1 Bugs and Limitations
=over
=item * Ignores all namespaces
=item * Does not handle mixed content
=item * The SOAP header is ignored
=back
=head1 AUTHOR
Replace the whitespace by @ for E-Mail Address.
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 COPYING
This module may be used under the same terms as perl itself.
=head1 Repository information
$ID: $
$LastChangedDate: $
$LastChangedRevision: $
$LastChangedBy: $
$HeadURL: $

79
lib/SOAP/WSDL/Manual.pod Normal file
View File

@@ -0,0 +1,79 @@
=pod
=head1 NAME
SOAP::WSDL::Manual - accessing WSDL based web services
=head1 Intro: Accessing a WSDL-based web service
=head2 Quick walk-through for the unpatient
=over
=item * Create WSDL bindings
perl wsdl2perl.pl -b base_dir URL
=item * Look what has been generated
Check the results of the generator. There should be one
MyInterface/SERVICE_NAME.pm file per service.
=item * Write script
use MyInterface::SERVICE_NAME;
my $service = MyInterface::SERVICE_NAME->new();
my $result = $service->SERVICE_METHOD();
die $result if not $result;
print $result;
C<perldoc MyInterface::SERVICE_NAME> should give you some overview about
the service's interface structure.
The results of all calls to your service object's methods (except new)
are objects based on SOAP::WSDL's XML schema implementation.
These objects are false in boolean context, and serialize to XML when
printed.
To access the object's properties use get_NAME / set_NAME getter/setter
methods whith NAME corresponding to the XML tag name.
=item * Run script
=back
=head2 Instrumenting web services with interface classes
SOAP::WSDL (starting from 2.00) instruments WSDL based web services with
interface classes. This means that SOAP::WSDL features a code generator
which creates one class for every web service you want to access.
Moreover, the data types from the WSDL definitions are also wrapped into
classes and returned to the user as objects.
To find out which class a particular XML node should be, SOAP::WSDL uses
typemaps. For every Web service, there's also a typemap created.
=head1 SEE ALSO
L<SOAP::WSDL::Manual::Glossary> The meaning of all these words
L<SOAP::WSDL::Client> Basic client for SOAP::WSDL based interfaces
L<SOAP::WSDL> an interpreting WSDL based SOAP client
=head1 LICENSE
Copyright 2007 Martin Kutter.
This file is part of SOAP-WSDL. You may distribute/modify it under
the same terms as perl itself
=head1 AUTHOR
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=cut

View File

@@ -0,0 +1,51 @@
=head1 NAME
SOAP::WSDL::Manual::Glossary - Those acronyms and stuff
=head1 Glossary
=head2 web service
Web services are RPC (Remote Procedure Call) interfaces accessible via
the internet, typically via HTTP(S).
=head2 SOAP
SOAP (the Simple Object Access Protocol) is a specification for
defining RPC interfaces, including (but not neccessarily limited to)
web services.
While one of the constituting aspects of a web service is its
reachability via some internet protocol, you might as well define
SOAP services accessible via postcards.
Despite it's name, SOAP has nothing more to do with objects than
cars have with pets - SOAP messages may, but not neccessarily do
carry object, very much like your car may, but does not need to
carry your pet.
=head2 WSDL
WSDL (Web Service Definition Language) is a XML-based markup language
for defining web service interfaces.
=head2 WS-I
WS-I (Web Service Interoperability) is a industry consortium dedicated
to finding interoperability rules for web services.
SOAP::WSDL aims to be a WS-I compliant SOAP client.
=head1 LICENSE
Copyright 2007 Martin Kutter.
This file is part of SOAP-WSDL. You may distribute/modify it under
the same terms as perl itself
=head1 AUTHOR
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=cut

View File

@@ -29,17 +29,14 @@ sub explain
);
for my $part(@{ $message->[0]->get_part() }) {
$opt->{ indent } .= "\t";
$txt .= $part->explain($opt);
$opt->{ indent } =~s/\t//;
$txt .= $opt->{ indent } . "\n";
}
}
else
{
if ($self->use())
{
$txt .= $opt->{ indent } . "$name use: " . $self->use(). "\n";
$txt .= " $name use: " . $self->use(). "\n";
}
}
return $txt;

178
lib/SOAP/WSDL/Parser.pod Normal file
View File

@@ -0,0 +1,178 @@
=pod
=head1 NAME
SOAP::WSDL::Parser - How SOAP::WSDL parses XML messages
=head1 Which XML message does SOAP::WSDL parse ?
Naturally, there are two kinds of XMLdocuments (or messages) SOAP::WSDL
has to parse:
=over
=item * WSDL definitions
=item * SOAP messages
=back
=head1 Parser implementations
There are different parser implementations available for SOAP messages -
currently there's only one for WSDL definitions.
=head2 WSDL definitions parser
=over
=item * SOAP::WSDL::SAX::WSDLHandler
This is a SAX handler for parsing WSDL files into object trees SOAP::WSDL
works with.
It's built as a native handler for XML::LibXML, but will also work with
XML::SAX::ParserFactory.
To parse a WSDL file, use one of the following variants:
my $parser = XML::LibXML->new();
my $handler = SOAP::WSDL::SAX::WSDLHandler->new();
$parser->set_handler( $handler );
$parser->parse( $xml );
my $data = $handler->get_data();
my $handler = SOAP::WSDL::SAX::WSDLHandler->new({
base => 'XML::SAX::Base'
});
my $parser = XML::SAX::ParserFactor->parser(
Handler => $handler
);
$parser->parse( $xml );
my $data = $handler->get_data();
=back
=head2 SOAP messages parser
All SOAP message handler use class resolvers for finding out which class
a particular XML element should be of, and type libs containing these classes.
=head3 Creating a class resolver
The easiest way for creating a class resolver is to run SOAP::WSDL's generator.
See wsdl2perl.pl
The class resolver must implement a class method "get_class", which is passed
a list ref of the current element's XPath (relative to Body), split by /.
This method must return a class name appropriate for a XML element.
A class resolver package might look like this:
package ClassResolver;
my %class_list = (
'EnqueueMessage' => 'Typelib::TEnqueueMessage',
'EnqueueMessage/MMessage' => 'Typelib::TMessage',
'EnqueueMessage/MMessage/MRecipientURI' => 'SOAP::WSDL::XSD::Builtin::anyURI',
'EnqueueMessage/MMessage/MMessageContent' => 'SOAP::WSDL::XSD::Builtin::string',
);
sub new { return bless {}, 'ClassResolver' };
sub get_class {
my $name = join('/', @{ $_[1] });
return ($class_list{ $name }) ? $class_list{ $name }
: warn "no class found for $name";
};
1;
=head3 Creating type lib classes
Every element must have a correspondent one in the type library.
Builtin types should be resolved as SOAP::WSDL::XSD::Builtin::* classes
Creating a type lib is easy: Just run SOAP::WSDL's generator - it will
create both a typemap and the type lib classes for a WSDL file.
Sometimes it is nessecary to create type lib classes by hand - not all
WSDL definitions are complete.
For writing your own lib classes, see L<SOAP::WSDL::XSD::Typelib::Element>,
L<SOAP::WSDL::XSD::Typelib::ComplexType> and L<SOAP::WSDL::XSD::Typelib::SimpleType>.
=head3 Parser implementations
=over
=item * SOAP::WSDL::SAX::MessageHandler
This is a SAX handler for parsing WSDL files into object trees SOAP::WSDL
works with.
It's built as a native handler for XML::LibXML, but will also work with
XML::SAX::ParserFactory.
Can be used for parsing both streams (chunks) and documents.
See L<SOAP::WSDL::SAX::MessageHandler> for details.
=item * SOAP::WSDL::Expat::MessageParser
A L<XML::Parser::Expat|XML::Parser::Expat> based parser. This is the fastest
parser for most SOAP messages and the default for SOAP::WSDL::Client.
=item * SOAP::WSDL::Expat::MessageStreamParser
A XML::Parser::ExpatNB based parser. Useful for parsing huge HTTP responses,
as you don't need to keep everything in memory.
See L<SOAP::WSDL::Expat::MessageStreamParser|SOAP::WSDL::Expat::MessageStreamParser> for details.
=back
=head3 Performance
SOAP::WSDL::Expat::MessageParser is the fastest way of parsing SOAP messages
into object trees and only slightly slower than converting them into hash
data structures:
Parsing a SOAP message with a length of 5962 bytes:
SOAP::WSDL::Expat::MessageParser:
3 wallclock secs ( 3.28 usr + 0.05 sys = 3.33 CPU) @ 60.08/s (n=200)
SOAP::WSDL::SAX::MessageHandler (with raw XML::LibXML):
5 wallclock secs ( 4.95 usr + 0.00 sys = 4.95 CPU) @ 40.38/s (n=200)
XML::Simple (XML::Parser):
3 wallclock secs ( 2.36 usr + 0.03 sys = 2.39 CPU) @ 83.65/s (n=200)
XML::Simple (XML::SAX::Expat):
7 wallclock secs ( 6.50 usr + 0.03 sys = 6.53 CPU) @ 30.62/s (n=200)
As the benchmark shows, all SOAP::WSDL parser variants are faster than
XML::Simple with XML::SAX::Expat, and SOAP::WSDL::Expat::MessageParser almost
reaches the performance of XML::Simple with XML::Parser as backend.
Parsing SOAP responses in chunks does not increase speed - at least not up
to a response size of around 500k:
Benchmark: timing 5 iterations of SOAP::WSDL::SAX::MessageHandler,
SOAP::WSDL::Expat::MessageParser, SOAP::WSDL::Expat::MessageStreamParser...
SOAP::WSDL::Expat::MessageStreamParser:
13 wallclock secs ( 7.39 usr + 0.09 sys = 7.48 CPU) @ 0.67/s (n=5)
SOAP::WSDL::Expat::MessageParser:
10 wallclock secs ( 5.81 usr + 0.06 sys = 5.88 CPU) @ 0.85/s (n=5)
SOAP::WSDL::SAX::MessageHandler:
14 wallclock secs ( 8.78 usr + 0.03 sys = 8.81 CPU) @ 0.57/s (n=5)
Response size: 344330 bytes
=cut

View File

@@ -1,6 +1,7 @@
package SOAP::WSDL::Part;
use strict;
use warnings;
use Carp qw(croak);
use Class::Std::Storable;
use base qw(SOAP::WSDL::Base);
@@ -10,85 +11,75 @@ my %type_of :ATTR(:name<type> :default<()>);
sub serialize
{
my $self = shift;
my $name = shift;
my $data = shift;
my $opt = shift;
my $typelib = $opt->{ typelib } || die "No typelib";
my %ns_map = reverse %{ $opt->{ namespace } };
my $self = shift;
my $name = shift;
my $data = shift;
my $opt = shift;
my $typelib = $opt->{ typelib } || die "No typelib";
my %ns_map = reverse %{ $opt->{ namespace } };
my $item_name;
if ($item_name = $self->get_type() )
{
# resolve type
my ($prefix, $localname) = split /:/ , $item_name, 2;
my $type = $typelib->find_type(
$ns_map{ $prefix },
$localname
);
return $type->serialize( $self->get_name(), $data, $opt );
}
elsif ( $item_name = $self->get_element() )
{
if ($item_name = $self->get_type() ) {
# resolve type
my ($prefix, $localname) = split /:/ , $item_name, 2;
my $element = $typelib->find_element(
$ns_map{ $prefix },
$localname
);
return $element->serialize( undef, $data, $opt );
}
my $type = $typelib->find_type( $ns_map{ $prefix }, $localname )
or die "type $item_name , $ns_map{ $prefix } not found";
my $name = $self->get_name();
return $type->serialize( $name, $data->{ $name }, $opt );
}
elsif ( $item_name = $self->get_element() ) {
my ($prefix, $localname) = split /:/ , $item_name, 2;
my $element = $typelib->find_element(
$ns_map{ $prefix },
$localname
)
or die "element $item_name , $ns_map{ $prefix } not found";
$opt->{ qualify } = 1;
return $element->serialize( undef, $data->{ $element->get_name() }, $opt );
}
die "Neither type nor element - don't know what to do";
}
sub explain {
my ($self, $opt, $name ) = @_;
my $typelib = $opt->{ wsdl }->first_types()
|| die "No typelib";
my ($self, $opt, $name ) = @_;
my $typelib = $opt->{ wsdl }->first_types() || die "No typelib";
my $element = $self->get_type() || $self->get_element();
my %ns_map = reverse %{ $opt->{ namespace } };
my $element = $self->get_type() || $self->get_element();
# resolve type
my $type = $typelib->find_type( $opt->{ wsdl }->_expand( $element ) )
|| $typelib->find_element( $opt->{ wsdl }->_expand( $element ) );
# resolve type
my ($prefix, $localname) = split /:/ , $element;
my $type = $typelib->find_type(
$ns_map{ $prefix },
$localname
)
|| $typelib->find_element(
$ns_map{ $prefix },
$localname
);
if (not $type)
{
warn "no type/element $element ({ $ns_map{ $prefix } }$localname) found for part " . $self->get_name();
return q{};
}
return $type->explain( $opt, $self->get_name() );
if (not $type)
{
warn "no type/element $element found for part " . $self->get_name();
return q{};
}
return " {\n" . $type->explain( $opt, $self->get_name() ) . " }\n";
}
sub to_typemap {
my ($self, $opt, $name ) = @_;
my $txt = q{};
my $wsdl = $opt->{ wsdl };
my $typelib = $opt->{ wsdl }->first_types()
|| die "No typelib";
my %ns_map = reverse %{ $opt->{ wsdl }->get_xmlns() };
my $element = $self->get_type() || $self->get_element();
# resolve type
my ($prefix, $localname) = split /:/ , $element;
my $type;
if ($type = $typelib->find_type( $ns_map{ $prefix }, $localname ) ) {
$txt .= "'/' => " . $type->get_name() . "\n";
if (my $type_name = $self->get_type()) {
$type = $typelib->find_type( $wsdl->_expand( $type_name ) )
|| croak "no type/element $type_name found for part " . $self->get_name();
$txt .= "q{} => " . $type->get_name() . "\n";
}
elsif ( my $element_name = $self->get_element() ) {
$type = $typelib->find_element( $wsdl->_expand( $element_name ) )
|| croak "no type/element $element_name found for part " . $self->get_name();
}
else {
$type = $typelib->find_element( $ns_map{ $prefix }, $localname );
}
if (not $type) {
warn "no type/element $element ({ $ns_map{ $prefix } }$localname) found for part " . $self->get_name();
return q{};
warn 'neither type nor element - do not know what to do for part '
. $self->get_name();
return q{};
}
$opt->{ path } = [];
$txt .= $type->to_typemap( $opt, $self->get_name() );

View File

@@ -8,38 +8,35 @@ my %binding_of :ATTR(:name<binding> :default<()>);
my %location_of :ATTR(:name<location> :default<()>);
sub explain {
my $self = shift;
my $opt = shift;
my $txt =
"=head2 Port name: " . $self->get_name() . "\n\n"
. "=over\n\n"
. "=item * Binding: " . $self->get_binding() ."\n\n"
. "=item * Location: " . $self->get_location() ."\n\n"
. "=back\n\n";
# if ( $self->location() );
my %ns_map = reverse %{ $opt->{ namespace } };
my $self = shift;
my $opt = shift;
$opt->{ wsdl } || die 'required attribute wsdl missing';
my $binding = $opt->{ wsdl }->find_binding(
$opt->{ wsdl }->_expand( $self->get_binding() )
) or die 'binding ' . $self->get_binding() . ' not found !';
my $txt = "=head2 Service information:\n\n"
. " Port name: " . $self->get_name() . "\n"
. " Binding: " . $self->get_binding() ."\n"
. " Location: " . $self->get_location() ."\n"
. $binding->explain($opt);
my ($prefix, $localname) = split /:/ , $self->get_binding();
my $binding = $opt->{ wsdl }->find_binding(
$ns_map{ $prefix }, $localname
) or die "binding $prefix:$localname not found !";
$txt .= $binding->explain($opt);
return $txt;
return $txt;
}
sub to_typemap {
my $self = shift;
my $opt = shift;
my %ns_map = reverse %{ $opt->{ wsdl }->get_xmlns() };
my ($prefix, $localname) = split /:/ , $self->get_binding();
# skip non-SOAP ports (could be http, email or whatever...)
return q{} if not $location_of{ ident $self };
my $binding = $opt->{ wsdl }->find_binding(
$ns_map{ $prefix }, $localname
) or die "binding $prefix:$localname not found !";
$opt->{wsdl}->_expand( $binding_of{ ident $self } )
) or die 'binding ' . $binding_of{ ident $self } .' not found!';
return $binding->to_typemap($opt);
}

View File

@@ -7,7 +7,7 @@ use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Builtin;
my %characters_of :ATTR(:default<()>);
my %class_resolver_of :ATTR(:default<()> :init_attr<class_resolver>);
my %class_resolver_of :ATTR(:default<()> :name<class_resolver>);
my %current_of :ATTR(:default<()>);
my %ignore_of :ATTR(:default<()>);
my %list_of :ATTR(:default<()>);
@@ -70,12 +70,17 @@ my %data_of :ATTR(:default<()>);
}
$class_resolver_of{ ident $self } = $args->{ class_resolver }
or die "cannot parse message without type resolver";
if $args->{ class_resolver };
return bless $self, $class;
}
}
sub class_resolver {
my $self = shift;
$class_resolver_of{ ident $self } = shift;
}
sub start_document {
my $ident = ident $_[0];
$list_of{ $ident } = [];
@@ -83,17 +88,16 @@ sub start_document {
$namespace_of{ $ident } = {};
$ignore_of{ $ident } = [ qw(Envelope Body) ]; # SOAP elements
$path_of{ $ident } = [];
$data_of{ $ident } = undef;
$data_of{ $ident } = undef;
}
sub start_element {
# use $_[n] for performance
my ($ident, $element) = (ident $_[0], $_[1]);
my $local_name = $element->{ LocalName };
# ignore top level elements
if (@{ $ignore_of{ $ident } }
&& $local_name eq $ignore_of{ $ident }->[0]) {
&& $element->{ LocalName } eq $ignore_of{ $ident }->[0]) {
shift @{ $ignore_of{ $ident } };
return;
}
@@ -101,7 +105,7 @@ sub start_element {
# empty characters
$characters_of{ $ident } = q{};
push @{ $path_of{ $ident } }, $local_name; # step down...
push @{ $path_of{ $ident } }, $element->{ LocalName }; # step down...
push @{ $list_of{ $ident } }, $current_of{ $ident }; # remember current
# resolve class of this element
@@ -111,26 +115,32 @@ sub start_element {
. " via "
. $class_resolver_of{ $ident };
# Check whether we have a primitive - we implement them as classes
# TODO replace with UNIVERSAL->isa() or maybe index - could be faster
# than m//
# TODO
if (not $class=~m{^SOAP::WSDL::XSD::Typelib::Builtin}xms) {
eval "require $class"; ## no critic qw(ProhibitStringyEval)
die $@ if $@;
# TODO replace with UNIVERSAL->isa()
# match is a bit faster if the string does not match, but WAY slower
# if $class matches...
# if (not $class=~m{^SOAP::WSDL::XSD::Typelib::Builtin}xms) {
if (index $class, 'SOAP::WSDL::XSD::Typelib::Builtin', 0 < 0) {
# check wheter there is a CODE reference for $class::new.
# If not, require it - all classes required here MUST
# define new()
# This is the same as $class->can('new'), but it's way faster
no strict qw(refs);
*{ "$class\::new" }{ CODE }
or eval "require $class" ## no critic qw(ProhibitStringyEval)
or die $@;
}
# create object
my $obj = $class->new({
# set current object
$current_of{ $ident } = $class->new({
map { $_->{ Name } => $_->{ Value } }
values %{ $element->{ Attributes } }
});
# set current object
$current_of{ $ident } = $obj;
# remember top level element
$data_of{ $ident } = $obj if not defined $data_of{ $ident };
defined $data_of{ $ident }
or ($data_of{ $ident } = $current_of{ $ident });
}
sub characters {
@@ -142,7 +152,8 @@ sub end_element {
my ($ident, $element) = (ident $_[0], $_[1]);
# This one easily handles ignores for us, too...
return if $list_of{ $ident }->[-1] eq '__STOP__';
return if not ref $list_of{ $ident }->[-1];
if ( $current_of{ $ident }
->isa('SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType') ) {
$current_of{ $ident }->set_value( $characters_of{ $ident } );
@@ -156,7 +167,7 @@ sub end_element {
# step up in path
pop @{ $path_of{ $ident } };
# step up in object hierarchy...
$current_of{ $ident } = pop @{ $list_of{ $ident } };
}
@@ -223,121 +234,18 @@ SOAP::WSDL::SAX::MessageHandler - Convert SOAP messages to custom object trees
class_resolver => FakeResolver->new(),
base => 'XML::SAX::Base',
), "Object creation");
my $parser = XML::LibXML->new();
$parser->set_handler( $filter );
my $parser = XML::SAX::ParserFactor->parser(
Handler => $handler
);
$parser->parse_string( $soap_message );
my $object_tree = $filter->get_data();
=head1 DESCRIPTION
Parses a SOAP message into an object tree.
SAX handler for parsing SOAP messages.
For every element in the SOAP message, an object is created. The class
of the object is determined via a Resolver object which has to be passed
to new via the class_resolver parameter.
=head1 Writing a class resolver
The class resolver must returned a method "get_class", which is passed a list
ref of the current element's XPath (relative to Body), split by /.
This method must return a class name appropriate for a XML element.
A class resolver package might look like this:
package FakeResolver;
my %class_list = (
'EnqueueMessage' => 'Typelib::TEnqueueMessage',
'EnqueueMessage/MMessage' => 'Typelib::TMessage',
'EnqueueMessage/MMessage/MRecipientURI' => 'SOAP::WSDL::XSD::Builtin::anyURI',
'EnqueueMessage/MMessage/MMessageContent' => 'SOAP::WSDL::XSD::Builtin::string',
);
sub new { return bless {}, 'FakeResolver' };
sub get_class {
my $name = join('/', @{ $_[1] });
return ($class_list{ $name }) ? $class_list{ $name }
: warn "no class found for $name";
};
1;
=head1 Writing type library classes
Every element must have a correspondent one in the type library.
Type library classes must provide the following methods:
Builtin types should be resolved as SOAP::WSDL::XSD::Builtin::* classes
=over
=item * new
Constructor
=item * add_FOO
The add_FOO method is called for every child element of the XML node.
Characters are regarded as child element of the last XML node.
=back
A tyelib class implemented as Inside-Out object using Class::Std::Storable
as base class would look like this:
package Typelib::TEnqueueMessage;
use strict;
use Class::Std::Storable;
my %MMessage_of :ATTR(:name<MMessage> :default<()>);
sub add_MMessage {
my ($self, $value) = @_;
my $ident = ident $self;
# we're the first value
return $MMessage_of{ $ident } = $value
if not defined $MMessage_of{ $ident };
# we're the second value
return $MMessage_of{ $ident } = [
$MMessage_of{ $ident }, $value ]
if not ref $MMessage_of{ $ident } eq 'ARRAY';
# we're third or later
push @{ $MMessage_of{ $ident } }, $value;
return $MMessage_of{ $ident };
}
}
1;
Of course one could use a method factory for these add_FOO methods - see
t/lib/Typelib/Base.pm for an example.
=head1 Performance
SOAP::WSDL::SAX::MessageHandler with a raw XML::LibXML parser almost reaches
the performance of XML::Simple with XML::Parser (and expat) as low-level
parser.
And SOAP::WSDL::SAX::MessageHandler builds up a object tree, while
XML::Simple just emits hash data structures:
SOAP::WSDL::SAX::MessageHandler:
1 wallclock secs ( 1.39 usr + 0.00 sys = 1.39 CPU) @ 719.42/s (n=1000)
XML::Simple:
2 wallclock secs ( 1.25 usr + 0.01 sys = 1.26 CPU) @ 790.51/s (n=1000)
If you know a faster way for parsing XML with a reasonable simple API than
XML::LibXML, please let me know...
See L<SOAP::WSDL::Parser> for details.
=head1 Bugs and Limitations

View File

@@ -1,4 +1,4 @@
package SOAP::WSDL::SAX::WSDLHandler;
package SOAP::WSDL::SAX::WSDLHandler;
use strict;
use warnings;
use Carp;
@@ -19,10 +19,10 @@ my %current_of :ATTR(:name<current> :default<()>);
my $class = shift;
my $self = {}; # $class->SUPER::new(@_);
my $args = shift || {};
die "arguments to new must be single hash ref"
if @_ or ! ref $args eq 'HASH';
# nasty, but for those who want to use XML::SAX::Base or similar
# as parser factory
if ($args->{base}) {
@@ -34,34 +34,34 @@ my %current_of :ATTR(:name<current> :default<()>);
# ...we ignore em all...
no strict qw(refs);
foreach my $method ( qw(
characters
processing_instruction
ignorable_whitespace
set_document_locator
start_prefix_mapping
end_prefix_mapping
skipped_entity
start_cdata
end_cdata
comment
entity_reference
notation_decl
unparsed_entity_decl
element_decl
attlist_decl
doctype_decl
xml_decl
entity_decl
attribute_decl
internal_entity_decl
external_entity_decl
resolve_entity
start_dtd
end_dtd
start_entity
end_entity
warning
error
characters
processing_instruction
ignorable_whitespace
set_document_locator
start_prefix_mapping
end_prefix_mapping
skipped_entity
start_cdata
end_cdata
comment
entity_reference
notation_decl
unparsed_entity_decl
element_decl
attlist_decl
doctype_decl
xml_decl
entity_decl
attribute_decl
internal_entity_decl
external_entity_decl
resolve_entity
start_dtd
end_dtd
start_entity
end_entity
warning
error
) ) {
*{ "$method" } = sub {};
}
@@ -72,7 +72,7 @@ my %current_of :ATTR(:name<current> :default<()>);
};
sub start_document {
my ($self, $ident) = ($_[0], ident $_[0]);
my $ident = ident $_[0];
$tree_of{ $ident } = {};
$order_of{ $ident } = [];
$targetNamespace_of{ $ident } = undef;
@@ -80,69 +80,63 @@ sub start_document {
}
sub start_element {
my ($self, $element) = @_;
my ($self, $element) = @_;
my $ident = ident $self;
my $action = SOAP::WSDL::TypeLookup->lookup(
$element->{ NamespaceURI },
$element->{ LocalName }
);
my $action = SOAP::WSDL::TypeLookup->lookup(
$element->{ NamespaceURI },
$element->{ LocalName }
);
if ($action)
{
if ($action->{ type } eq 'CLASS')
{
eval "require $action->{ class }";
croak $@, $tree_of{ $ident } if ($@);
return if not $action;
if ($action->{ type } eq 'CLASS') {
eval "require $action->{ class }";
croak $@, $tree_of{ $ident } if ($@);
my $class = $action->{ class };
my $obj = $class->new()->init(
values %{ $element->{ Attributes } }
);
my $class = $action->{ class };
my $obj = $class->new({ parent => $current_of{ $ident } })->init(
values %{ $element->{ Attributes } }
);
# set element in parent
if ($current_of{ $ident })
{
# inherit namespace, but don't override
$obj->set_targetNamespace(
$current_of{ $ident }->get_targetNamespace() )
if not $obj->get_targetNamespace();
# set element in parent
if ($current_of{ $ident }) {
# inherit namespace, but don't override
$obj->set_targetNamespace(
$current_of{ $ident }->get_targetNamespace() )
if not $obj->get_targetNamespace();
# push on name list
my $method = "push_$element->{ LocalName }";
no strict qw(refs);
$current_of{ $ident }->$method( $obj );
# push on name list
my $method = "push_$element->{ LocalName }";
no strict qw(refs);
$current_of{ $ident }->$method( $obj );
# remember element for stepping back
push @{ $order_of{ $ident } }, $current_of{ $ident };
}
else
{
$tree_of{ $ident } = $obj;
}
# set new element (step down)
$current_of{ $ident } = $obj;
}
elsif ($action->{ type } eq 'PARENT')
{
$current_of{ $ident }->init( values %{ $element->{ Attributes } } );
}
elsif ($action->{ type } eq 'METHOD')
{
my $method = $action->{ method } || $element->{ LocalName };
no strict qw(refs);
# call method with
# - default value ($action->{ value } if defined,
# dereferencing lists
# - the values of the elements Attributes hash
$current_of{ $ident }->$method( defined $action->{ value }
? ref $action->{ value }
? @{ $action->{ value } }
: ($action->{ value })
: values %{ $element->{ Attributes } } );
}
}
# remember element for stepping back
push @{ $order_of{ $ident } }, $current_of{ $ident };
}
else {
$tree_of{ $ident } = $obj;
}
# set new element (step down)
$current_of{ $ident } = $obj;
}
elsif ($action->{ type } eq 'PARENT') {
$current_of{ $ident }->init( values %{ $element->{ Attributes } } );
}
elsif ($action->{ type } eq 'METHOD') {
my $method = $action->{ method } || $element->{ LocalName };
no strict qw(refs);
# call method with
# - default value ($action->{ value } if defined,
# dereferencing lists
# - the values of the elements Attributes hash
$current_of{ $ident }->$method( defined $action->{ value }
? ref $action->{ value }
? @{ $action->{ value } }
: ($action->{ value })
: values %{ $element->{ Attributes } } );
}
}
sub end_element {
@@ -159,6 +153,10 @@ sub end_element {
$current_of{ $ident } = pop @{ $order_of{ $ident } };
}
}
sub fatal_error {
die @_;
}
sub get_data {
my $self = shift;

View File

@@ -15,13 +15,13 @@ use base qw(
my %faultcode_of :ATTR(:get<faultcode>);
my %faultstring_of :ATTR(:get<faultstring>);
my %faultactor_of :ATTR(:get<faultactor>);
my %detail_of :ATTR(:get<faultdetail>);
my %detail_of :ATTR(:get<detail>);
# always return false in boolean context - a fault is never true...
sub as_bool :BOOLIFY { return; }
__PACKAGE__->_factory(
[ qw(faultcode faultstring faultactor faultdetail) ],
[ qw(faultcode faultstring faultactor detail) ],
{
faultcode => \%faultcode_of,
faultstring => \%faultstring_of,
@@ -29,7 +29,7 @@ __PACKAGE__->_factory(
detail => \%detail_of,
},
{
faultcode => 'SOAP::WSDL::XSD::Typelib::Builtin::qName',
faultcode => 'SOAP::WSDL::XSD::Typelib::Builtin::QName',
faultstring => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
faultactor => 'SOAP::WSDL::XSD::Typelib::Builtin::anyURI',
detail => 'SOAP::WSDL::XSD::Typelib::Builtin::anyType',
@@ -44,4 +44,57 @@ __PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
1;
1;
=pod
=head1 NAME
SOAP::WSDL::SOAP::Typelib::Fault11 - SOAP 1.1 Fault class
=head1 DESCRIPTION
Models a SOAP 1.1 Fault.
SOAP::WSDL::SOAP::Typelib::Fault11 objects are false in boolean context
and serialize to XML on stringification.
This means you can do something like:
my $soap = SOAP::WSDL::Client->new();
# ...
my $result = $soap->call($method, $data);
if (not $result) {
die "Error calling SOAP method: ", $result->get_faultstring();
}
=head1 METHODS
=head2 get_faultcode / set_faultcode
Getter/setter for object's the faultcode property.
=head2 get_faultstring / set_faultstring
Getter/setter for object's the faultstring property.
=head2 get_faultactor / set_faultactor
Getter/setter for object's the faultactor property.
=head2 get_detail / set_detail
Getter/setter for detail object's detail property.
=head1 LICENSE
Copyright 2007 Martin Kutter.
This file is part of SOAP-WSDL. You may distribute/modify it under
the same terms as perl itself
=head1 AUTHOR
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=cut

View File

@@ -9,7 +9,7 @@ my %port_of :ATTR(:name<port> :default<()>);
sub explain {
my $self = shift;
my $opt = shift;
my $txt ="=head1 Service name\n\n" . $self->get_name() . "\n\n";
my $txt ="=head1 Service " . $self->get_name() . "\n\n";
foreach my $port (@{ $self->get_port() } )
{
$txt .= $port->explain( $opt );
@@ -23,5 +23,10 @@ sub to_typemap {
return join "\n",
map { $_->to_typemap( $opt ) } @{ $port_of{ ident $self } };
}
# TODO implement to_class as class generator for a (complete) interface
sub to_class {
}
1;

View File

@@ -5,6 +5,7 @@ use Carp;
use Class::Std::Storable;
use Scalar::Util qw(blessed);
use base qw/SOAP::WSDL::Base/;
use Data::Dumper;
my %annotation_of :ATTR(:name<annotation> :default<()>);
my %element_of :ATTR(:name<element> :default<()>);
@@ -56,96 +57,100 @@ sub init {
$self->SUPER::init( @args );
}
sub serialize
{
sub serialize {
my ($self, $name, $value, $opt) = @_;
$opt->{ indent } ||= q{};
my $flavor = $self->get_flavor();
my $xml = '';
$opt->{ indent } ||= q{};
$opt->{ attributes } ||= [];
my $flavor = $self->get_flavor();
my $xml = ($opt->{ readable }) ? $opt->{ indent } : q{}; # add indentation
if ( $opt->{ qualify } ) {
$opt->{ attributes } = [ ' xmlns="' . $self->get_targetNamespace .'"' ];
delete $opt->{ qualify };
}
$xml .= $opt->{ indent } if ($opt->{ readable }); # add indentation
$xml .= "<$name";
if ( $opt->{ autotype })
{
my $ns = $self->get_targetNamespace();
my $prefix = $opt->{ namespace }->{ $ns }
|| die 'No prefix found for namespace '. $ns;
$xml .= join q{}, " type=\"$prefix:", $self->get_name(), '"'
if ($self->get_name() );
}
$xml .= '>';
$xml .= "\n" if ( $opt->{ readable } ); # add linebreak
if ( ($flavor eq "sequence") or ($flavor eq "all") )
{
$opt->{ indent } .= "\t";
for my $element (@{ $self->get_element() })
{
# might be list - listify
$value = [ $value ] if not ref $value eq 'ARRAY';
$xml .= join q{ } , "<$name" , @{ $opt->{ attributes } };
delete $opt->{ attributes }; # don't propagate...
if ( $opt->{ autotype }) {
my $ns = $self->get_targetNamespace();
my $prefix = $opt->{ namespace }->{ $ns }
|| die 'No prefix found for namespace '. $ns;
$xml .= join q{}, " type=\"$prefix:", $self->get_name(), '" '
if ($self->get_name() );
}
$xml .= '>';
$xml .= "\n" if ( $opt->{ readable } ); # add linebreak
if ( ($flavor eq "sequence") or ($flavor eq "all") )
{
$opt->{ indent } .= "\t";
for my $element (@{ $self->get_element() }) {
# might be list - listify
$value = [ $value ] if not ref $value eq 'ARRAY';
for my $single_value (@{ $value }) {
my $element_value;
if (blessed $single_value) {
my $method = 'get_' . $element->get_name();
$element_value = $single_value->$method();
my $element_value;
if (blessed $single_value) {
my $method = 'get_' . $element->get_name();
$element_value = $single_value->$method();
}
else {
$element_value = $single_value->{ $element->get_name() }
else {
$element_value = $single_value->{ $element->get_name() };
}
$element_value = [ $element_value ]
if not ref $element_value eq 'ARRAY';
$element_value = [ $element_value ]
if not ref $element_value eq 'ARRAY';
$xml .= join q{}
, map { $element->serialize( undef, $_, $opt ) }
@{ $element_value };
}
}
$opt->{ indent } =~s/\t$//;
}
else
{
die "sorry, we just handle all and sequence types yet...";
}
$xml .= $opt->{ indent } if ( $opt->{ readable } ); # add indentation
$xml .= '</' . $name . '>';
$xml .= "\n" if ($opt->{ readable } ); # add linebreak
return $xml;
$xml .= join q{}
, map { $element->serialize( undef, $_, $opt ) }
@{ $element_value };
}
}
$opt->{ indent } =~s/\t$//;
}
else {
die "sorry, we just handle all and sequence types yet...";
}
$xml .= $opt->{ indent } if ( $opt->{ readable } ); # add indentation
$xml .= '</' . $name . '>';
$xml .= "\n" if ($opt->{ readable } ); # add linebreak
return $xml;
}
sub explain
{
my ($self, $opt, $name ) = @_;
my $flavor = $self->get_flavor();
my $xml = '';
$xml .= $opt->{ indent } if ($opt->{ readable }); # add indentation
$xml .= q{'} . $name . q{' => };
sub explain {
my ($self, $opt, $name ) = @_;
my $flavor = $self->get_flavor();
return q{} if not $flavor; # empty complexType
$name ||= q{};
if ( ($flavor eq "sequence") or ($flavor eq "all") )
{
$xml .= "{\n";
$opt->{ indent } .= "\t";
return q{} if not $flavor; # empty complexType
$opt->{ indent } ||= q{ };
my $xml = q{};
$xml .= "$opt->{indent}\'$name'=> " if $name;
if ( ($flavor eq "sequence") or ($flavor eq "all") ) {
$xml .= "{\n";
$opt->{ indent } .= " ";
$xml .= join q{}, map { $_->explain( $opt ) }
@{ $self->get_element() };
$opt->{ indent } =~s/\t$//; # step back
$xml .= $opt->{ indent } . "},\n";
}
elsif ($flavor eq "complexContent")
{
$opt->{ indent } =~s/\s{2}$//; # step back
$xml .= "$opt->{ indent }},\n";
}
elsif ($flavor eq "complexContent")
{
}
elsif ($flavor eq "simpleContent")
{
}
else
{
warn "unknown complexType definition $flavor";
}
$xml .= "\n" if ($opt->{ readable } ); # add linebreak
return $xml;
}
elsif ($flavor eq "simpleContent")
{
warn "found unsupported complexType definition $flavor";
}
else
{
warn "found unsupported complexType definition $flavor";
}
return $xml;
}
sub to_typemap {
@@ -165,12 +170,12 @@ sub to_typemap {
return $txt;
}
sub toClass {
sub to_class {
my $self = shift;
my $opt = shift;
my $template = <<'EOT';
package [% class_prefix %]::[% self.get_name %];
package [% type_prefix %][% self.get_name %];
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::ComplexType;
@@ -187,19 +192,38 @@ __PACKAGE__->_factory(
[% element.get_name %]
[% END %]) ],
{
[% FOREACH element=self.get_element %] [% element.get_name %] => \%[% element.get_name %]_of,
[% FOREACH element=self.get_element %][% element.get_name %] => \%[% element.get_name %]_of,
[% END %]
},
{
[%- FOREACH element=self.get_element;
split_name = element.get_type.split(':');
prefix = split_name.0;
localname = split_name.1;
IF nsmap.$prefix == 'http://www.w3.org/2001/XMLSchema' -%]
[% element.get_name %] => 'SOAP::WSDL::XSD::Typelib::Builtin::[% localname %]',
[% ELSE %]
[% element.get_name %] => '[% class_prefix %]::[% localname %]',
[%- END;
[%-
FOREACH element=self.get_element;
IF (element.get_type);
split_name = element.get_type.split(':');
prefix = split_name.0;
localname = split_name.1;
IF nsmap.$prefix == 'http://www.w3.org/2001/XMLSchema' -%]
[% element.get_name %] => 'SOAP::WSDL::XSD::Typelib::Builtin::[% localname %]',
[% ELSE -%]
[% element.get_name %] => '[% type_prefix %][% localname %]',
[%- END;
ELSIF (simpleType = element.first_simpleType);
base = simpleType.get_base();
%]
# basic simple type handling: we treat atomic simple types
# in complexType elements as their base types
# - and we only treat <restriction base="..."> yet.
# our base here is [% base %]
[%
split_name = base.split(':');
prefix = split_name.0;
localname = split_name.1;
IF nsmap.$prefix == 'http://www.w3.org/2001/XMLSchema' -%]
[% element.get_name %] => 'SOAP::WSDL::XSD::Typelib::Builtin::[% localname %]',
[% ELSE -%]
[% element.get_name %] => '[% type_prefix %][% localname %]',
[%- END;
END;
END %]
}
);
@@ -207,21 +231,68 @@ __PACKAGE__->_factory(
sub get_xmlns { '[% self.get_targetNamespace %]' }
1;
__END__
=pod
=head1 NAME [% type_prefix %][% self.get_name %]
=head1 SYNOPSIS
=head1 DESCRIPTION
Type class for the XML type [% self.get_name %].
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
[%- FOREACH element = self.get_element %]
[% element.get_name -%]
[% END %]
=head1 Object structure
[% FOREACH element=self.get_element;
IF (element.get_type);
split_name = element.get_type.split(':');
prefix = split_name.0;
localname = split_name.1;
IF nsmap.$prefix == 'http://www.w3.org/2001/XMLSchema' -%]
[% element.get_name %] => 'SOAP::WSDL::XSD::Typelib::Builtin::[% localname %]',
[% ELSE -%]
[% element.get_name %] => '[% type_prefix %][% localname %]',
[%- END;
ELSIF (simpleType = element.first_simpleType);
base = simpleType.get_base();
split_name = base.split(':');
prefix = split_name.0;
localname = split_name.1;
IF nsmap.$prefix == 'http://www.w3.org/2001/XMLSchema' -%]
[% element.get_name %] => 'SOAP::WSDL::XSD::Typelib::Builtin::[% localname %]',
[% ELSE -%]
[% element.get_name %] => '[% type_prefix %][% localname %]',
[%- END;
END;
END %]
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
[% structure %]
=cut
EOT
$opt->{ base_path } ||= '.';
require Template;
my $tt = Template->new(
RELATIVE => 1,
);
my $code = $tt->process( \$template, {
class_prefix => $opt->{ prefix },
self => $self,
nsmap => { reverse %{ $opt->{ wsdl }->get_xmlns() } },
},
$opt->{ output },
) or die $tt->error();
$self->SUPER::to_class($opt, $template);
}
sub _check_value {
@@ -249,6 +320,6 @@ Handling of these child elements is not implemented yet
=item * explain may produce erroneous results
=over
=back
=cut

View File

@@ -3,6 +3,7 @@ use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::Base);
use Data::Dumper;
my %simpleType_of :ATTR(:name<simpleType> :default<()>);
my %complexType_of :ATTR(:name<complexType> :default<()>);
@@ -42,9 +43,8 @@ sub first_complexType {
}
# serialize type instead...
sub serialize
{
my ($self, $name, $value, $opt) = @_;
sub serialize {
my ($self, $name, $value, $opt) = @_;
my $type;
my $typelib = $opt->{ typelib };
my %ns_map = reverse %{ $opt->{ namespace } };
@@ -59,13 +59,18 @@ sub serialize
# substitutionGroup ?
$name ||= $self->get_name();
if ( $opt->{ qualify } ) {
$opt->{ attributes } = [ ' xmlns="' . $self->get_targetNamespace .'"' ];
}
# set default and fixed - fixed overrides everything,
# default only empty (undefined) values
if (not defined $value) {
$value = $default_of{ ident $self } if $default_of{ ident $self };
}
$value = $fixed_of{ ident $self } if $fixed_of{ ident $self };
if (not defined $value) {
$value = $default_of{ ident $self } if $default_of{ ident $self };
}
$value = $fixed_of{ ident $self } if $fixed_of{ ident $self };
# TODO check nillable and serialize empty data correctly
@@ -76,18 +81,18 @@ sub serialize
}
# handle direct simpleType and complexType here
if ($type = $self->first_simpleType() ) { # simpleType
return $type->serialize( $name, $value, $opt );
}
elsif ($type = $self->first_complexType() ) { # complexType
return $type->serialize( $name, $value, $opt );
}
if ($type = $self->first_simpleType() ) { # simpleType
return $type->serialize( $name, $value, $opt );
}
elsif ($type = $self->first_complexType() ) { # complexType
return $type->serialize( $name, $value, $opt );
}
elsif (my $ref_name = $ref_of{ $ident }) { # ref
my ($prefix, $localname) = split /:/ , $ref_name;
my $ns = $ns_map{ $prefix };
$type = $typelib->find_type( $ns, $localname );
die "no type for $prefix:$localname" if (not $type);
return $type->serialize( $self->get_name(), $value, $opt );
return $type->serialize( $name, $value, $opt );
}
# lookup type
@@ -98,13 +103,12 @@ sub serialize
);
# safety check
die "no type for $prefix:$localname $ns_map{$prefix}" if (not $type);
return $type->serialize( $self->get_name(), $value, $opt );
die "no type for $prefix:$localname $ns_map{$prefix}" if (not $type);
return $type->serialize( $name, $value, $opt );
}
sub explain
{
sub explain {
my ($self, $opt, $name) = @_;
my $type;
my $text = q{};
@@ -113,10 +117,12 @@ sub explain
if ($type = $self->first_simpleType() )
{
$text .= $type->explain( $opt, $self->get_name() );
return $text;
}
elsif ($type = $self->first_complexType() )
{
$text .= $type->explain( $opt, $self->get_name() )
$text .= $type->explain( $opt, $self->get_name() );
return $text;
}
# return if it's not a derived type - we don't handle
@@ -125,14 +131,17 @@ sub explain
# if we have a derived type, fetch type and explain
my ($prefix, $localname) = split /:/ , $self->get_type();
my %ns_map = reverse %{ $opt->{ namespace } };
my $ns = $ns_map{ $prefix };
my %ns_map = reverse %{ $opt->{ wsdl }->get_xmlns };
$type = $opt->{ wsdl }->first_types()->find_type(
$ns, $localname
$ns_map{ $prefix }, $localname
);
die "no type for $prefix:$localname ($ns)" if (not $type);
use Data::Dumper;
die "no type for $prefix:$localname ($ns_map{ $prefix })"
. Dumper $opt->{ wsdl }->first_types()->first_schema()->_DUMP
if (not $type);
return $text .= $type->explain( $opt, $self->get_name() );
return 'ERROR: '. $@;
@@ -144,9 +153,10 @@ sub to_typemap {
my $txt = q{};
my %nsmap = reverse %{ $opt->{ wsdl }->get_xmlns() };
my $type;
push @{ $opt->{path} }, $self->get_name();
if ( my $typename = $self->get_type() ) {
my ($prefix, $localname) = split /:/, $self->get_type();
my $ns = $nsmap{ $prefix };
@@ -159,12 +169,21 @@ sub to_typemap {
else
{
$type = $opt->{ wsdl }->first_types()->find_type( $ns, $localname );
$typeclass = $opt->{ prefix } . $type->get_name();
# referenced types need type_prefix (may be globally unique)
$typeclass = $opt->{ type_prefix } . $type->get_name();
$txt .= $type->to_typemap($opt);
}
$txt .= q{'} . join( q{/}, @{ $opt->{path} } ) . "' => '$typeclass',\n";
}
# atomic types need element prefix
elsif ($type = $self->first_simpleType() ) {
# atomic types need element prefix (may be locally unique)
# TODO fix simpletype Typemap
my $typeclass = $opt->{ element_prefix } . $self->get_name();
$txt .= q{'} . join( q{/}, @{ $opt->{path} } ) . "' => '$typeclass',\n";
my $flavor = $type->get_flavor();
if ( $flavor eq 'sequence' ) {
$txt .= "# atomic simple type (sequence)\n";
@@ -179,9 +198,10 @@ sub to_typemap {
}
elsif ($type = $self->first_complexType() ) {
my $typeclass = $opt->{ prefix } . $self->get_name();
my $typeclass = $opt->{ element_prefix } . $self->get_name();
$txt .= q{'} . join( q{/}, @{ $opt->{path} } ) . "' => '$typeclass',\n";
my $flavor = $type->get_flavor();
my $flavor = $type->get_flavor()
|| 'UNKNOWN';
if ( $flavor eq 'sequence' ) {
$txt .= "# atomic complex type (sequence)\n";
$txt .= $type->to_typemap($opt). "\n";;
@@ -192,18 +212,22 @@ sub to_typemap {
$txt .= $type->to_typemap($opt). "\n";
$txt .= "# end atomic complex type (all)\n";
}
else {
warn "flavor $flavor in element " . $self->get_name() . "\n";
}
}
pop @{ $opt->{ path } };
return $txt;
}
sub toClass {
sub to_class {
my $self = shift;
my $opt = shift;
my $template = <<'EOT';
package [% class_prefix %]::[% self.get_name %];
package [% element_prefix %][% self.get_name %];
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
@@ -214,9 +238,10 @@ use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::SimpleType
[% type.flavor_class %]
[% type.base_class($class_prefix) %]
[% type.base_class($type_prefix) %]
);
[% ELSIF (type = self.first_complexType) %]
# atomic complexType
# <element name="[% self.get_name %]"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
@@ -225,7 +250,7 @@ use base qw(
);
[% FOREACH element = type.get_element %]
my %[% element.get_name %]_of :ATTR(get:<[% element.get_name %]>);
my %[% element.get_name %]_of :ATTR(:get<[% element.get_name %]>);
[% END %]
__PACKAGE__->_factory(
@@ -244,23 +269,24 @@ __PACKAGE__->_factory(
IF nsmap.$prefix == 'http://www.w3.org/2001/XMLSchema' %]
[% element.get_name %] => 'SOAP::WSDL::XSD::Typelib::Builtin::[% localname %]',
[% ELSE %]
[% element.get_name %] => '[% class_prefix %]::[% localname %]',
[% element.get_name %] => '[% type_prefix %][% localname %]',
[% END %]
[% END %]
}
);
[%# END complexType %]
[% ELSIF (type = self.get_type) %]
#
# <element name="[% self.get_name %]" type="[% self.get_type %]"/> definition
[% (typename = self.get_type);
split_name = element.type.split(':');
#
[% split_name = self.get_type.split(':');
prefix = split_name.0;
localname = split_name.1;
-%]
[% IF (nsmap.$prefix == 'http://www.w3.org/2001/XMLSchema');
IF (nsmap.$prefix == 'http://www.w3.org/2001/XMLSchema');
base_class = 'SOAP::WSDL::XSD::Typelib::Builtin::' _ localname ;
ELSE;
base_class = class_prefix _ '::' _ localname;
base_class = type_prefix _ localname;
-%]
use [% base_class %];
@@ -284,20 +310,61 @@ __PACKAGE__->__set_maxOccurs([% self.get_maxOccurs %]);
__PACKAGE__->__set_ref('[% self.get_ref %]');
1;
EOT
require Template;
my $tt = Template->new(
RELATIVE => 1,
);
my $code = $tt->process( \$template, {
class_prefix => $opt->{ prefix },
self => $self,
nsmap => { reverse %{ $opt->{ wsdl }->get_xmlns() } },
},
$opt->{ output },
)
or die $tt->error();
__END__
=pod
=head1 NAME [% element_prefix %][% self.get_name %]
=head1 SYNOPSIS
=head1 DESCRIPTION
Type class for the XML element [% self.get_name %].
=head1 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
[%- IF (type = self.first_complexType);
FOREACH element = type.get_element %]
[% element.get_name -%]
[% END;
END %]
=head1 Object structure
[%- IF (type = self.first_complexType);
FOREACH element = type.get_element;
split_name = element.get_type.split(':');
prefix = split_name.0;
localname = split_name.1;
IF nsmap.$prefix == 'http://www.w3.org/2001/XMLSchema' %]
[% element.get_name %] => 'SOAP::WSDL::XSD::Typelib::Builtin::[% localname %]',
[% ELSE %]
[% element.get_name %] => '[% type_prefix %]::[% localname %]',
[% END;
END;
END %]
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
[% structure %]
=cut
EOT
$self->SUPER::to_class($opt, $template);
}
1;
@@ -333,7 +400,7 @@ Handling of the substitutionGroup attribute is not implemented yet
=item * explain may produce erroneous results
=over
=back
=head1 COPYING

View File

@@ -9,9 +9,11 @@ sub serialize
{
my ($self, $name, $value, $opt) = @_;
my $xml;
$opt->{ indent } ||= "";
$opt->{ indent } ||= "";
$opt->{ attributes } ||= [];
$xml .= $opt->{ indent } if ($opt->{ readable });
$xml .= '<' . $name;
$xml .= '<' . join ' ', $name, @{ $opt->{ attributes } };
if ( $opt->{ autotype })
{
my $ns = $self->get_targetNamespace();
@@ -38,13 +40,8 @@ sub serialize
sub explain
{
my ($self, $opt, $name ) = @_;
my $perl;
$opt->{ indent } ||= "";
$perl .= $opt->{ indent } if ($opt->{ readable });
$perl .= q{'} . $name . q{' => $someValue };
$perl .= "\n" if ($opt->{ readable });
return $perl;
return "$opt->{ indent }'$name' => \$someValue,\n"
}
sub toClass {

View File

@@ -5,43 +5,42 @@ use Class::Std::Storable;
use base qw(SOAP::WSDL::Base);
my %base_of :ATTR(:name<base> :default<()>);
my %flavor_of :ATTR(:name<flavor> :default<()>);
my %itemType_of :ATTR(:name<itemType> :default<()>);
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
# is set to simpleContent/complexContent
my %content_Model_of :ATTR(:name<contentModel> :default<()>);
# set to restriction|list|union|enumeration
my %flavor_of :ATTR(:name<flavor> :default<()>);
sub set_restriction {
my $self = shift;
my @attributes = @_;
$self->set_flavor( 'restriction' );
foreach my $attr (@attributes)
{
next if (not $attr->{ LocalName } eq 'restriction');
$self->base( $attr->{ Value } );
}
my $self = shift;
my @attributes = @_;
$self->set_flavor( 'restriction' );
for (@attributes) {
next if (not $_->{ LocalName } eq 'base');
$self->set_base( $_->{ Value } );
}
}
sub set_list {
my $self = shift;
my @attributes = @_;
$self->set_flavor( 'list' );
foreach my $attr (@attributes)
{
next if (not $attr->{ LocalName } eq 'list');
$self->set_base( $attr->{ Value } );
}
my $self = shift;
my @attributes = @_;
$self->set_flavor( 'list' );
for (@attributes) {
next if (not $_->{ LocalName } eq 'type');
$self->set_base( $_->{ Value } );
}
}
sub set_union {
my $self = shift;
my @attributes = @_;
$self->set_flavor( 'union' );
foreach my $attr (@attributes)
{
next if (not $attr->{ LocalName } eq 'memberTypes');
$self->set_base( [ split /\s/, $attr->{ Value } ] );
}
my $self = shift;
my @attributes = @_;
$self->set_flavor( 'union' );
for (@attributes) {
next if (not $_->{ LocalName } eq 'memberTypes');
$self->set_base( [ split /\s/, $_->{ Value } ] );
}
}
sub push_enumeration
@@ -50,75 +49,77 @@ sub push_enumeration
my @attr = @_;
my @attributes = @_;
$self->set_flavor( 'enumeration' );
foreach my $attr (@attributes)
{
next if (not $attr->{ LocalName } eq 'value');
push @{ $enumeration_of{ ident $self } }, $attr->{ 'Value' };
for (@attributes) {
next if (not $_->{ LocalName } eq 'value');
push @{ $enumeration_of{ ident $self } }, $_->{ 'Value' };
}
}
sub serialize
{
my $self = shift;
my $name = shift;
my $value = shift;
my $opt = shift;
my $ident = ident $self;
$self->_check_value( $value );
sub serialize {
my $self = shift;
my $name = shift;
my $value = shift;
my $opt = shift;
my $ident = ident $self;
$opt->{ attributes } ||= [];
$opt->{ indent } ||= q{};
$self->_check_value( $value );
return $self->_serialize_single($name, $value , $opt)
if ( $flavor_of{ $ident } eq 'restriction'
or $flavor_of{ $ident } eq 'union'
or $flavor_of{ $ident } eq 'enumeration');
return $self->_serialize_single($name, $value , $opt)
if ( $flavor_of{ $ident } eq 'restriction'
or $flavor_of{ $ident } eq 'union'
or $flavor_of{ $ident } eq 'enumeration');
if ($flavor_of{ $ident } eq 'list' )
{
$value ||= [];
$value = [ $value ] if ( ref( $value) ne 'ARRAY' );
return $self->_serialize_single($name, join( q{ }, @{ $value } ), $opt);
}
if ($flavor_of{ $ident } eq 'list' )
{
$value ||= [];
$value = [ $value ] if ( ref( $value) ne 'ARRAY' );
return $self->_serialize_single($name, join( q{ }, @{ $value } ), $opt);
}
}
sub _serialize_single
{
my ($self, $name, $value, $opt) = @_;
my $xml = '';
$xml .= $opt->{ indent } if ($opt->{ readable }); # add indentation
$xml .= '<' . $name;
if ( $opt->{ autotype })
{
my $ns = $self->get_targetNamespace();
sub _serialize_single {
my ($self, $name, $value, $opt) = @_;
my $xml = '';
$xml .= $opt->{ indent } if ($opt->{ readable }); # add indentation
$xml .= '<' . join ' ', $name, @{ $opt->{ attributes } };
if ( $opt->{ autotype }) {
my $ns = $self->get_targetNamespace();
my $prefix = $opt->{ namespace }->{ $ns }
|| die 'No prefix found for namespace '. $ns;
$xml .= ' type="' . $prefix . ':'
. $self->get_name() .'"';
}
$xml .= '>';
$xml .= $value;
$xml .= '</' . $name . '>' ;
$xml .= "\n" if ($opt->{ readable });
return $xml;
|| die 'No prefix found for namespace '. $ns;
$xml .= ' type="' . $prefix . ':' . $self->get_name() .'"';
}
# nillabel ?
return $xml .'/>' if not defined $value;
$xml .= join q{}, '>' , $value , '</' , $name , '>';
$xml .= "\n" if ($opt->{ readable });
return $xml;
}
sub explain
{
my ($self, $opt, $name) = @_;
my $perl;
$opt->{ indent } ||= "";
$perl .= $opt->{ indent } if ($opt->{ readable });
$perl .= q{'} . $name . q{' => $someValue };
$perl .= "\n" if ($opt->{ readable });
return $perl;
sub explain {
my ($self, $opt, $name) = @_;
my $perl;
$opt->{ indent } ||= "";
$perl .= $opt->{ indent } if ($opt->{ readable });
$perl .= q{'} . $name . q{' => $someValue };
$perl .= "\n" if ($opt->{ readable });
return $perl;
}
sub _check_value {
my $self = shift;
}
# TODO: implement to_class based on template...
sub toClass {
sub to_class {
my $self = shift;
my $opt = shift;
my $class_prefix = $opt->{ prefix };
my $class_prefix = $opt->{ type_prefix };
my $name = $opt->{name} || $self->get_name();
my $flavor = $self->get_flavor() eq 'list'
? 'SOAP::WSDL::XSD::Typelib::Builtin::list'
@@ -173,6 +174,6 @@ union simpleType definitions probalbly serialize wrong
=item * explain may produce erroneous results
=over
=back
=cut

View File

@@ -2,368 +2,51 @@ package SOAP::WSDL::XSD::Typelib::Builtin;
use strict;
use warnings;
use Class::Std::Storable;
# derivation classes first...
package SOAP::WSDL::XSD::Typelib::Builtin::list;
use strict;
use warnings;
use Class::Std::Storable;
sub serialize {
my ($self, $opt) = @_;
my $value = $self->get_value();
return $self->start_tag({ %$opt, nil => 1 }) if not defined $value;
$value = [ $value ] if not ref $value;
return join q{}, $self->start_tag($opt, $value)
, join( q{ }, @{ $value } )
, $self->end_tag($opt, $value);
}
# Builtin classes
# Every XML schema type inherits from anyType...
package SOAP::WSDL::XSD::Typelib::Builtin::anyType;
use strict;
use warnings;
use Class::Std::Storable;
sub start_tag {
my ($self, $opt) = @_;
$opt ||= {};
return '<' . $opt->{name} . ' >' if $opt->{ name };
return q{}
}
sub end_tag {
my ($self, $opt) = @_;
$opt ||= {};
return '</' . $opt->{name} . ' >' if $opt->{ name };
return q{}
};
sub serialize_qualified :STRINGIFY {
return $_[0]->serialize( { qualified => 1 } );
}
# All builtin and all simpleType types inherit from anySimpleType
package SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anyType);
my %value_of :ATTR(:name<value> :default<()>);
sub serialize {
my ($self, $opt) = @_;
my $ident = ident $self;
$opt ||= {};
return $self->start_tag({ %$opt, nil => 1})
if not defined $value_of{ $ident };
return join q{}, $self->start_tag($opt, $value_of{ $ident })
, $value_of{ $ident }
, $self->end_tag($opt);
}
sub as_bool :BOOLIFY {
return $value_of { ident $_[0] };
}
package SOAP::WSDL::XSD::Typelib::Builtin::dateTime;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
package SOAP::WSDL::XSD::Typelib::Builtin::duration;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
package SOAP::WSDL::XSD::Typelib::Builtin::date;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
package SOAP::WSDL::XSD::Typelib::Builtin::time;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
package SOAP::WSDL::XSD::Typelib::Builtin::gYearMonth;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
package SOAP::WSDL::XSD::Typelib::Builtin::gYear;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
package SOAP::WSDL::XSD::Typelib::Builtin::gMonthDay;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
package SOAP::WSDL::XSD::Typelib::Builtin::gMonth;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
package SOAP::WSDL::XSD::Typelib::Builtin::gDay;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
package SOAP::WSDL::XSD::Typelib::Builtin::boolean;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
sub serialize {
my ($self, $opt) = @_;
my $ident = ident $self;
$opt ||= {};
return $self->start_tag({ %$opt, nil => 1})
if not defined $value_of{ $ident };
return join q{}
, $self->start_tag($opt)
, $value_of{ $ident } ? 'true' : 'false'
, $self->end_tag($opt);
}
sub as_num :NUMERIFY {
return $_[0]->get_value();
}
sub set_value {
my ($self, $value) = @_;
$value_of{ ident $self } = defined $value
? ($value ne 'false' or ($value))
? 1 : 0
: 0;
}
package SOAP::WSDL::XSD::Typelib::Builtin::string;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
package SOAP::WSDL::XSD::Typelib::Builtin::normalizedString;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::string);
package SOAP::WSDL::XSD::Typelib::Builtin::token;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::normalizedString);
package SOAP::WSDL::XSD::Typelib::Builtin::language;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::token);
package SOAP::WSDL::XSD::Typelib::Builtin::Name;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::token);
package SOAP::WSDL::XSD::Typelib::Builtin::NCName;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::Name);
package SOAP::WSDL::XSD::Typelib::Builtin::ID;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::NCName);
package SOAP::WSDL::XSD::Typelib::Builtin::IDREF;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::ID);
package SOAP::WSDL::XSD::Typelib::Builtin::IDREFS;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(
SOAP::WSDL::XSD::Typelib::Builtin::list
SOAP::WSDL::XSD::Typelib::Builtin::IDREF);
package SOAP::WSDL::XSD::Typelib::Builtin::ENTITY;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::NCName);
package SOAP::WSDL::XSD::Typelib::Builtin::NMTOKEN;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::token);
package SOAP::WSDL::XSD::Typelib::Builtin::NMTOKENS;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(
SOAP::WSDL::XSD::Typelib::Builtin::list
SOAP::WSDL::XSD::Typelib::Builtin::token);
package SOAP::WSDL::XSD::Typelib::Builtin::decimal;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
sub as_num :NUMERIFY :BOOLIFY {
return $_[0]->get_value();
}
package SOAP::WSDL::XSD::Typelib::Builtin::base64Binary;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
package SOAP::WSDL::XSD::Typelib::Builtin::hex64Binary;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
package SOAP::WSDL::XSD::Typelib::Builtin::float;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
sub as_num :NUMERIFY {
return $_[0]->get_value();
}
package SOAP::WSDL::XSD::Typelib::Builtin::double;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
sub as_num :NUMERIFY {
return $_[0]->get_value();
}
package SOAP::WSDL::XSD::Typelib::Builtin::anyURI;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
package SOAP::WSDL::XSD::Typelib::Builtin::qName;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
package SOAP::WSDL::XSD::Typelib::Builtin::NOTATION;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
package SOAP::WSDL::XSD::Typelib::Builtin::integer;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::decimal);
package SOAP::WSDL::XSD::Typelib::Builtin::nonPositiveInteger;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::integer);
package SOAP::WSDL::XSD::Typelib::Builtin::negativeInteger;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::nonPositiveInteger);
package SOAP::WSDL::XSD::Typelib::Builtin::nonNegativeInteger;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::integer);
package SOAP::WSDL::XSD::Typelib::Builtin::unsignedLong;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::nonNegativeInteger);
package SOAP::WSDL::XSD::Typelib::Builtin::positiveInteger;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::nonNegativeInteger);
package SOAP::WSDL::XSD::Typelib::Builtin::unsignedInt;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::unsignedLong);
package SOAP::WSDL::XSD::Typelib::Builtin::unsignedShort;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::unsignedInt);
package SOAP::WSDL::XSD::Typelib::Builtin::unsignedByte;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::unsignedShort);
package SOAP::WSDL::XSD::Typelib::Builtin::long;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::integer);
package SOAP::WSDL::XSD::Typelib::Builtin::int;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::long);
package SOAP::WSDL::XSD::Typelib::Builtin::short;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::int);
package SOAP::WSDL::XSD::Typelib::Builtin::byte;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::short);
use SOAP::WSDL::XSD::Typelib::Builtin::anyType;
use SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType;
use SOAP::WSDL::XSD::Typelib::Builtin::anyURI;
use SOAP::WSDL::XSD::Typelib::Builtin::base64Binary;
use SOAP::WSDL::XSD::Typelib::Builtin::boolean;
use SOAP::WSDL::XSD::Typelib::Builtin::byte;
use SOAP::WSDL::XSD::Typelib::Builtin::date;
use SOAP::WSDL::XSD::Typelib::Builtin::dateTime;
use SOAP::WSDL::XSD::Typelib::Builtin::decimal;
use SOAP::WSDL::XSD::Typelib::Builtin::double;
use SOAP::WSDL::XSD::Typelib::Builtin::duration;
use SOAP::WSDL::XSD::Typelib::Builtin::ENTITY;
use SOAP::WSDL::XSD::Typelib::Builtin::float;
use SOAP::WSDL::XSD::Typelib::Builtin::gDay;
use SOAP::WSDL::XSD::Typelib::Builtin::gMonth;
use SOAP::WSDL::XSD::Typelib::Builtin::gMonthDay;
use SOAP::WSDL::XSD::Typelib::Builtin::gYear;
use SOAP::WSDL::XSD::Typelib::Builtin::gYearMonth;
use SOAP::WSDL::XSD::Typelib::Builtin::hexBinary;
use SOAP::WSDL::XSD::Typelib::Builtin::ID;
use SOAP::WSDL::XSD::Typelib::Builtin::IDREF;
use SOAP::WSDL::XSD::Typelib::Builtin::IDREFS;
use SOAP::WSDL::XSD::Typelib::Builtin::int;
use SOAP::WSDL::XSD::Typelib::Builtin::integer;
use SOAP::WSDL::XSD::Typelib::Builtin::language;
use SOAP::WSDL::XSD::Typelib::Builtin::list;
use SOAP::WSDL::XSD::Typelib::Builtin::long;
use SOAP::WSDL::XSD::Typelib::Builtin::Name;
use SOAP::WSDL::XSD::Typelib::Builtin::NCName;
use SOAP::WSDL::XSD::Typelib::Builtin::negativeInteger;
use SOAP::WSDL::XSD::Typelib::Builtin::nonNegativeInteger;
use SOAP::WSDL::XSD::Typelib::Builtin::nonPositiveInteger;
use SOAP::WSDL::XSD::Typelib::Builtin::normalizedString;
use SOAP::WSDL::XSD::Typelib::Builtin::NOTATION;
use SOAP::WSDL::XSD::Typelib::Builtin::positiveInteger;
use SOAP::WSDL::XSD::Typelib::Builtin::QName;
use SOAP::WSDL::XSD::Typelib::Builtin::short;
use SOAP::WSDL::XSD::Typelib::Builtin::string;
use SOAP::WSDL::XSD::Typelib::Builtin::time;
use SOAP::WSDL::XSD::Typelib::Builtin::token;
use SOAP::WSDL::XSD::Typelib::Builtin::unsignedByte;
use SOAP::WSDL::XSD::Typelib::Builtin::unsignedInt;
use SOAP::WSDL::XSD::Typelib::Builtin::unsignedLong;
use SOAP::WSDL::XSD::Typelib::Builtin::unsignedShort;
1;
@@ -382,7 +65,13 @@ This module implements all builtin Types from the XML schema specification.
Objects of a class may be filled with values and serialize correctly.
These basic type classes are most useful when used as element or simpleType
base classes.
base classes.
The datatypes classes themselves are split up into
SOAP::WSDL::XSD::Typelib::Builtin::* modules.
Using SOAP::WSDL::XSD::Typelib::Builtin uses all of the builtin datatype
classes.
=head1 EXAMPLES
@@ -483,6 +172,130 @@ decimal, float and double (and derived classes) return their value in
numeric context.
=back
=head1 Subclasses
=head2 SOAP::WSDL::XSD::Typelib::Builtin::anyType
Base class for all types
=head2 SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType
Base class for all simple types
=head2 SOAP::WSDL::XSD::Typelib::Builtin::anyURI
Type representing URIs
=head2 SOAP::WSDL::XSD::Typelib::Builtin::boolean
Represents boolean data.
Serializes to "true" or "false".
Everything true in perl and not "false" is deserialized as true.
Returns true/false in boolean context.
Returns 1 / 0 in numeric context.
=head2 SOAP::WSDL::XSD::Typelib::Builtin::byte
byte integer objects.
=head2 SOAP::WSDL::XSD::Typelib::Builtin::date
=head2 SOAP::WSDL::XSD::Typelib::Builtin::dateTime
=head2 SOAP::WSDL::XSD::Typelib::Builtin::decimal
decimal is the base of all non-float numbers
=head2 SOAP::WSDL::XSD::Typelib::Builtin::double
=head2 SOAP::WSDL::XSD::Typelib::Builtin::duration
=head2 SOAP::WSDL::XSD::Typelib::Builtin::ENTITY
=head2 SOAP::WSDL::XSD::Typelib::Builtin::float
=head2 SOAP::WSDL::XSD::Typelib::Builtin::gDay
=head2 SOAP::WSDL::XSD::Typelib::Builtin::gMonth
=head2 SOAP::WSDL::XSD::Typelib::Builtin::gMonthDay
=head2 SOAP::WSDL::XSD::Typelib::Builtin::gYear
=head2 SOAP::WSDL::XSD::Typelib::Builtin::gYearMonth
=head2 SOAP::WSDL::XSD::Typelib::Builtin::hexBinary
=head2 SOAP::WSDL::XSD::Typelib::Builtin::ID
=head2 SOAP::WSDL::XSD::Typelib::Builtin::IDREF
=head2 SOAP::WSDL::XSD::Typelib::Builtin::IDREFS
Derived by SOAP::WSDL::XSD::Typelib::Builtin::list.
=head2 SOAP::WSDL::XSD::Typelib::Builtin::int
=head2 SOAP::WSDL::XSD::Typelib::Builtin::integer
=head2 SOAP::WSDL::XSD::Typelib::Builtin::language
=head2 SOAP::WSDL::XSD::Typelib::Builtin::list
=head2 SOAP::WSDL::XSD::Typelib::Builtin::long
=head2 SOAP::WSDL::XSD::Typelib::Builtin::Name
=head2 SOAP::WSDL::XSD::Typelib::Builtin::NCName
=head2 SOAP::WSDL::XSD::Typelib::Builtin::negativeInteger
=head2 SOAP::WSDL::XSD::Typelib::Builtin::nonNegativeInteger
=head2 SOAP::WSDL::XSD::Typelib::Builtin::nonPositiveInteger
=head2 SOAP::WSDL::XSD::Typelib::Builtin::normalizedString
=head2 SOAP::WSDL::XSD::Typelib::Builtin::NOTATION
=head2 SOAP::WSDL::XSD::Typelib::Builtin::positiveInteger
=head2 SOAP::WSDL::XSD::Typelib::Builtin::QName
=head2 SOAP::WSDL::XSD::Typelib::Builtin::short
=head2 SOAP::WSDL::XSD::Typelib::Builtin::string
=head2 SOAP::WSDL::XSD::Typelib::Builtin::time
=head2 SOAP::WSDL::XSD::Typelib::Builtin::token
=head2 SOAP::WSDL::XSD::Typelib::Builtin::unsignedByte
=head2 SOAP::WSDL::XSD::Typelib::Builtin::unsignedInt
=head2 SOAP::WSDL::XSD::Typelib::Builtin::unsignedLong
=head2 SOAP::WSDL::XSD::Typelib::Builtin::unsignedShort
=head1 CAVEATS
=over
=item * set_value
In contrast to Class::Std-generated mutators (setters), set_value does
not return the last value.
This is for speed reasons: SOAP::WSDL never needs to know the last value
when calling set_calue, but calls it over and over again...
=back
=head1 BUGS AND LIMITATIONS
@@ -506,7 +319,9 @@ Replace whitespace by @ in e-mail address.
Martin Kutter E<gt>martin.kutter fen-net.deE<lt>
=head1 COPYING
=head1 Licenxe
Copyright 2004-2007 Martin Kutter.
This library is free software, you may distribute/modify it under the
same terms as perl itself

View File

@@ -0,0 +1,25 @@
package SOAP::WSDL::XSD::Typelib::Builtin::ENTITY;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::NCName);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
};
1;

View File

@@ -0,0 +1,7 @@
package SOAP::WSDL::XSD::Typelib::Builtin::ID;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::NCName);
1;

View File

@@ -0,0 +1,7 @@
package SOAP::WSDL::XSD::Typelib::Builtin::IDREF;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::ID);
1;

View File

@@ -0,0 +1,9 @@
package SOAP::WSDL::XSD::Typelib::Builtin::IDREFS;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(
SOAP::WSDL::XSD::Typelib::Builtin::list
SOAP::WSDL::XSD::Typelib::Builtin::IDREF);
1;

View File

@@ -0,0 +1,25 @@
package SOAP::WSDL::XSD::Typelib::Builtin::NCName;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::Name);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
1;

View File

@@ -0,0 +1,26 @@
package SOAP::WSDL::XSD::Typelib::Builtin::NMTOKEN;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::token);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
1;

View File

@@ -0,0 +1,26 @@
package SOAP::WSDL::XSD::Typelib::Builtin::NMTOKENS;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::list
SOAP::WSDL::XSD::Typelib::Builtin::NMTOKEN);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
1;

View File

@@ -0,0 +1,33 @@
package SOAP::WSDL::XSD::Typelib::Builtin::NOTATION;
use strict;
use warnings;
my %length_of :ATTR(:name<length> :default<()>);
my %minLength_of :ATTR(:name<minLength> :default<()>);
my %maxLength_of :ATTR(:name<maxLength> :default<()>);
my %pattern_of :ATTR(:name<pattern> :default<()>);
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
1;

View File

@@ -0,0 +1,25 @@
package SOAP::WSDL::XSD::Typelib::Builtin::Name;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::token);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
};
1;

View File

@@ -0,0 +1,34 @@
package SOAP::WSDL::XSD::Typelib::Builtin::QName;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
my %length_of :ATTR(:name<length> :default<()>);
my %minLength_of :ATTR(:name<minLength> :default<()>);
my %maxLength_of :ATTR(:name<maxLength> :default<()>);
my %pattern_of :ATTR(:name<pattern> :default<()>);
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
1;

View File

@@ -0,0 +1,35 @@
package SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType;
use strict;
use warnings;
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anyType);
}
my %value_of :ATTR(:get<value> :init_arg<value> :default<()>);
## use $_[n] for speed - we get called zillions of times...
# and we don't need to return the last value...
sub set_value { $value_of{ ident $_[0] } = $_[1] }
sub serialize {
my ($self, $opt) = @_;
my $ident = ident $self;
$opt ||= {};
return $self->start_tag({ %$opt, nil => 1})
if not defined $value_of{ $ident };
return join q{}, $self->start_tag($opt, $value_of{ $ident })
, $value_of{ $ident }
, $self->end_tag($opt);
}
# TODO disallow serializing !
sub as_bool :BOOLIFY {
return $value_of { ident $_[0] };
}
Class::Std::initialize(); # make :BOOLIFY overloading serializable
1;

View File

@@ -0,0 +1,29 @@
package SOAP::WSDL::XSD::Typelib::Builtin::anyType;
use strict;
use warnings;
use Class::Std::Storable;
my %xmlns_of :ATTR(:name<xmlns> :default<()>);
# use $_[1] for performance
sub start_tag {
my $opt = $_[1] ||= {};
return '<' . $opt->{name} . ' >' if $opt->{ name };
return q{}
}
# use $_[1] for performance
sub end_tag {
return $_[1] && defined $_[1]->{ name }
? "</$_[1]->{name} >"
: q{};
};
sub serialize_qualified :STRINGIFY {
return $_[0]->serialize( { qualified => 1 } );
}
Class::Std::initialize(); # make :STRINGIFY overloading serializable
1;

View File

@@ -0,0 +1,33 @@
package SOAP::WSDL::XSD::Typelib::Builtin::anyURI;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
my %length_of :ATTR(:name<length> :default<()>);
my %minLength_of :ATTR(:name<minLength> :default<()>);
my %maxLength_of :ATTR(:name<maxLength> :default<()>);
my %pattern_of :ATTR(:name<pattern> :default<()>);
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
1;

View File

@@ -0,0 +1,35 @@
package SOAP::WSDL::XSD::Typelib::Builtin::base64Binary;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
my %length_of :ATTR(:name<length> :default<()>);
my %minLength_of :ATTR(:name<minLength> :default<()>);
my %maxLength_of :ATTR(:name<maxLength> :default<()>);
my %pattern_of :ATTR(:name<pattern> :default<()>);
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
1;

View File

@@ -0,0 +1,59 @@
package SOAP::WSDL::XSD::Typelib::Builtin::boolean;
use strict;
use warnings;
my %pattern_of :ATTR(:name<pattern> :default<()>);
my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
my %value_of :ATTR(:get<value> :init_attr<value> :default<()>);
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$value_of{ ident $self } = $_[0]->{ value }
if exists $_[0]->{ value }
}
return $self;
};
}
sub serialize {
my ($self, $opt) = @_;
my $ident = ident $self;
$opt ||= {};
return $self->start_tag({ %$opt, nil => 1})
if not defined $value_of{ $ident };
return join q{}
, $self->start_tag($opt)
, $value_of{ $ident } ? 'true' : 'false'
, $self->end_tag($opt);
}
sub as_num :NUMERIFY {
return $_[0]->get_value();
}
sub set_value {
my ($self, $value) = @_;
$value_of{ ident $self } = defined $value
? ($value ne 'false' or ($value))
? 1 : 0
: 0;
}
Class::Std::initialize(); # make :BOOLIFY overloading serializable
1;

View File

@@ -0,0 +1,26 @@
package SOAP::WSDL::XSD::Typelib::Builtin::byte;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::short);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
1;

View File

@@ -0,0 +1,35 @@
package SOAP::WSDL::XSD::Typelib::Builtin::date;
use strict;
use warnings;
my %pattern_of :ATTR(:name<pattern> :default<()>);
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
my %maxInclusive_of :ATTR(:name<maxInclusive> :default<()>);
my %maxExclusive_of :ATTR(:name<maxExclusive> :default<()>);
my %minInclusive_of :ATTR(:name<minInclusive> :default<()>);
my %minExclusive_of :ATTR(:name<minExclusive> :default<()>);
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
1;

View File

@@ -0,0 +1,37 @@
package SOAP::WSDL::XSD::Typelib::Builtin::dateTime;
use strict;
use warnings;
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
my %pattern_of :ATTR(:name<pattern> :default<()>);
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
my %maxInclusive_of :ATTR(:name<maxInclusive> :default<()>);
my %maxExclusive_of :ATTR(:name<maxExclusive> :default<()>);
my %minInclusive_of :ATTR(:name<minInclusive> :default<()>);
my %minExclusive_of :ATTR(:name<minExclusive> :default<()>);
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
1;

View File

@@ -0,0 +1,42 @@
package SOAP::WSDL::XSD::Typelib::Builtin::decimal;
use strict;
use warnings;
my %totalDigits_of :ATTR(:name<totalDigits> :default<()>);
my %fractionDigits_of :ATTR(:name<fractionDigits> :default<()>);
my %pattern_of :ATTR(:name<pattern> :default<()>);
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
my %maxInclusive_of :ATTR(:name<maxInclusive> :default<()>);
my %maxExclusive_of :ATTR(:name<maxExclusive> :default<()>);
my %minInclusive_of :ATTR(:name<minInclusive> :default<()>);
my %minExclusive_of :ATTR(:name<minExclusive> :default<()>);
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
sub as_num :NUMERIFY :BOOLIFY {
return $_[0]->get_value();
}
Class::Std::initialize(); # make :NUMERIFY :BOOLIFY overloading serializable
1;

View File

@@ -0,0 +1,31 @@
package SOAP::WSDL::XSD::Typelib::Builtin::double;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
sub as_num :NUMERIFY {
return $_[0]->get_value();
}
Class::Std::initialize(); # make :NUMERIFY overloading serializable
1;

View File

@@ -0,0 +1,34 @@
package SOAP::WSDL::XSD::Typelib::Builtin::duration;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
};
my %pattern_of :ATTR(:name<pattern> :default<()>);
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
my %maxInclusive_of :ATTR(:name<maxInclusive> :default<()>);
my %maxExclusive_of :ATTR(:name<maxExclusive> :default<()>);
my %minInclusive_of :ATTR(:name<minInclusive> :default<()>);
my %minExclusive_of :ATTR(:name<minExclusive> :default<()>);
1;

View File

@@ -0,0 +1,41 @@
package SOAP::WSDL::XSD::Typelib::Builtin::float;
use strict;
use warnings;
my %pattern_of :ATTR(:name<pattern> :default<()>);
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
my %maxInclusive_of :ATTR(:name<maxInclusive> :default<()>);
my %maxExclusive_of :ATTR(:name<maxExclusive> :default<()>);
my %minInclusive_of :ATTR(:name<minInclusive> :default<()>);
my %minExclusive_of :ATTR(:name<minExclusive> :default<()>);
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
};
sub as_num :NUMERIFY {
return $_[0]->get_value();
}
Class::Std::initialize(); # make :NUMERIFY overloading serializable
1;

View File

@@ -0,0 +1,34 @@
package SOAP::WSDL::XSD::Typelib::Builtin::gDay;
use strict;
use warnings;
my %pattern_of :ATTR(:name<pattern> :default<()>);
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
my %maxInclusive_of :ATTR(:name<maxInclusive> :default<()>);
my %maxExclusive_of :ATTR(:name<maxExclusive> :default<()>);
my %minInclusive_of :ATTR(:name<minInclusive> :default<()>);
my %minExclusive_of :ATTR(:name<minExclusive> :default<()>);
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
};
1;

View File

@@ -0,0 +1,34 @@
package SOAP::WSDL::XSD::Typelib::Builtin::gMonth;
use strict;
use warnings;
my %pattern_of :ATTR(:name<pattern> :default<()>);
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
my %maxInclusive_of :ATTR(:name<maxInclusive> :default<()>);
my %maxExclusive_of :ATTR(:name<maxExclusive> :default<()>);
my %minInclusive_of :ATTR(:name<minInclusive> :default<()>);
my %minExclusive_of :ATTR(:name<minExclusive> :default<()>);
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
};
1;

View File

@@ -0,0 +1,34 @@
package SOAP::WSDL::XSD::Typelib::Builtin::gMonthDay;
use strict;
use warnings;
my %pattern_of :ATTR(:name<pattern> :default<()>);
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
my %maxInclusive_of :ATTR(:name<maxInclusive> :default<()>);
my %maxExclusive_of :ATTR(:name<maxExclusive> :default<()>);
my %minInclusive_of :ATTR(:name<minInclusive> :default<()>);
my %minExclusive_of :ATTR(:name<minExclusive> :default<()>);
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
};
1;

View File

@@ -0,0 +1,34 @@
package SOAP::WSDL::XSD::Typelib::Builtin::gYear;
use strict;
use warnings;
my %pattern_of :ATTR(:name<pattern> :default<()>);
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
my %maxInclusive_of :ATTR(:name<maxInclusive> :default<()>);
my %maxExclusive_of :ATTR(:name<maxExclusive> :default<()>);
my %minInclusive_of :ATTR(:name<minInclusive> :default<()>);
my %minExclusive_of :ATTR(:name<minExclusive> :default<()>);
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
};
1;

View File

@@ -0,0 +1,33 @@
package SOAP::WSDL::XSD::Typelib::Builtin::gYearMonth;
use strict;
use warnings;
my %pattern_of :ATTR(:name<pattern> :default<()>);
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
my %maxInclusive_of :ATTR(:name<maxInclusive> :default<()>);
my %maxExclusive_of :ATTR(:name<maxExclusive> :default<()>);
my %minInclusive_of :ATTR(:name<minInclusive> :default<()>);
my %minExclusive_of :ATTR(:name<minExclusive> :default<()>);
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
};
1;

View File

@@ -0,0 +1,32 @@
package SOAP::WSDL::XSD::Typelib::Builtin::hexBinary;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
};
my %length_of :ATTR(:name<length> :default<()>);
my %minLength_of :ATTR(:name<minLength> :default<()>);
my %maxLength_of :ATTR(:name<maxLength> :default<()>);
my %pattern_of :ATTR(:name<pattern> :default<()>);
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
1;

View File

@@ -0,0 +1,26 @@
package SOAP::WSDL::XSD::Typelib::Builtin::int;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::long);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
};
1;

View File

@@ -0,0 +1,33 @@
package SOAP::WSDL::XSD::Typelib::Builtin::integer;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::decimal);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
};
sub as_num :NUMERIFY {
return $_[0]->get_value();
}
Class::Std::initialize(); # make :NUMERIFY overloading serializable
1;

View File

@@ -0,0 +1,26 @@
package SOAP::WSDL::XSD::Typelib::Builtin::language;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::token);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
};
1;

View File

@@ -0,0 +1,41 @@
package SOAP::WSDL::XSD::Typelib::Builtin::list;
use strict;
use warnings;
use Class::Std::Storable;
sub serialize {
my ($self, $opt) = @_;
my $value = $self->get_value();
return $self->start_tag({ %$opt, nil => 1 }) if not defined $value;
$value = [ $value ] if not ref $value;
return join q{}, $self->start_tag($opt, $value)
, join( q{ }, @{ $value } )
, $self->end_tag($opt, $value);
}
1;
__END__
=pod
=head1 NAME
SOAP::WSDL::XSD::Typelib::Builtin::list - list derivation base class
=head1 DESCRIPTION
To derive from some class by list, just inherit from list.
Make sure SOAP::WSDL::XSD::Typelib::Builtin::list is before the type
to derive from in the @ISA list.
=head1 LICENSE
This file is part of SOAP-WSDL. You may distribute/modify it under
the same terms as perl itself
=head1 AUTHOR
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=cut

View File

@@ -0,0 +1,25 @@
package SOAP::WSDL::XSD::Typelib::Builtin::long;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::integer);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
};
1;

View File

@@ -0,0 +1,25 @@
package SOAP::WSDL::XSD::Typelib::Builtin::negativeInteger;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::nonPositiveInteger);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
1;

View File

@@ -0,0 +1,25 @@
package SOAP::WSDL::XSD::Typelib::Builtin::nonNegativeInteger;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::integer);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
1;

View File

@@ -0,0 +1,26 @@
package SOAP::WSDL::XSD::Typelib::Builtin::nonPositiveInteger;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::integer);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
1;

View File

@@ -0,0 +1,26 @@
package SOAP::WSDL::XSD::Typelib::Builtin::normalizedString;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::string);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
};
1;

View File

@@ -0,0 +1,25 @@
package SOAP::WSDL::XSD::Typelib::Builtin::positiveInteger;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::nonNegativeInteger);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
1;

View File

@@ -0,0 +1,25 @@
package SOAP::WSDL::XSD::Typelib::Builtin::short;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::int);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
1;

View File

@@ -0,0 +1,60 @@
package SOAP::WSDL::XSD::Typelib::Builtin::string;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
my %length_of :ATTR(:name<length> :default<()>);
my %minLength_of :ATTR(:name<minLength> :default<()>);
my %maxLength_of :ATTR(:name<maxLength> :default<()>);
my %pattern_of :ATTR(:name<pattern> :default<()>);
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
my %char2entity = (
q{&} => q{&amp;},
q{<} => q{&lt;},
q{>} => q{&gt;},
q{"} => q{&qout;},
q{'} => q{&apos;},
);
sub serialize {
my ($self, $opt) = @_;
my $ident = ident $self;
$opt ||= {};
my $value = $self->get_value();
return $self->start_tag({ %$opt, nil => 1})
if not defined $value;
# HTML::Entities does the same - and more, thus it's around 1/3 slower...
$value =~ s{([&<>"'])}{$char2entity{$1}}xgmso;
return join q{}, $self->start_tag($opt, $value)
#, encode_entities( $value, q{&<>"'} )
, $value
, $self->end_tag($opt);
}
1;

View File

@@ -0,0 +1,33 @@
package SOAP::WSDL::XSD::Typelib::Builtin::time;
use strict;
use warnings;
my %pattern_of :ATTR(:name<pattern> :default<()>);
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
my %maxInclusive_of :ATTR(:name<maxInclusive> :default<()>);
my %maxExclusive_of :ATTR(:name<maxExclusive> :default<()>);
my %minInclusive_of :ATTR(:name<minInclusive> :default<()>);
my %minExclusive_of :ATTR(:name<minExclusive> :default<()>);
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
1;

View File

@@ -0,0 +1,24 @@
package SOAP::WSDL::XSD::Typelib::Builtin::token;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::normalizedString);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
1;

View File

@@ -0,0 +1,25 @@
package SOAP::WSDL::XSD::Typelib::Builtin::unsignedByte;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::unsignedShort);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
1;

View File

@@ -0,0 +1,25 @@
package SOAP::WSDL::XSD::Typelib::Builtin::unsignedInt;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::unsignedLong);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
1;

View File

@@ -0,0 +1,47 @@
package SOAP::WSDL::XSD::Typelib::Builtin::unsignedLong;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::nonNegativeInteger);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
1;
__END__
=pod
=head1 NAME
SOAP::WSDL::XSD::Typelib::Builtin::unsignedLong - unsigned long integer objects
=head1 DESCRIPTION
Subclass of nonNegativeInteger.
=head1 LICENSE
This file is part of SOAP-WSDL. You may distribute/modify it under
the same terms as perl itself
=head1 AUTHOR
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=cut

View File

@@ -0,0 +1,25 @@
package SOAP::WSDL::XSD::Typelib::Builtin::unsignedShort;
use strict;
use warnings;
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
BEGIN {
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::unsignedInt);
no warnings qw(redefine);
no strict qw(refs);
# Yes, I know it's ugly - but this is the fastest constructor to write
# for Class::Std-Style inside out objects..
*{ __PACKAGE__ . '::new' } = sub {
my $self = bless \do { my $foo } , shift;
if (@_) {
$self->set_value( $_[0]->{ value } )
if exists $_[0]->{ value }
}
return $self;
};
}
1;

Some files were not shown because too many files have changed in this diff Show More