Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ba1959888 | ||
|
|
a554e87f49 | ||
|
|
312f3d6bbd | ||
|
|
40e0e67e84 | ||
|
|
25548e6296 |
39
Build.PL
39
Build.PL
@@ -1,34 +1,43 @@
|
||||
use Module::Build;
|
||||
Module::Build->new(
|
||||
create_makefile_pl => 'passthrough',
|
||||
dist_abstract => 'SOAP with WSDL support',
|
||||
dist_name => 'SOAP-WSDL',
|
||||
dist_version => '2.00_05',
|
||||
dist_version => '2.00_10',
|
||||
module_name => 'SOAP::WSDL',
|
||||
license => 'artistic',
|
||||
requires => {
|
||||
'Class::Std' => q/v0.0.8/,
|
||||
'Class::Std::Storable' => 0,
|
||||
'SOAP::Lite' => 0,
|
||||
'XML::XPath' => 0,
|
||||
'XML::LibXML' => 0,
|
||||
'XML::SAX::Base' => 0,
|
||||
'XML::SAX::ParserFactory' => 0,
|
||||
'Date::Parse' => 0,
|
||||
'Date::Format' => 0,
|
||||
'LWP::UserAgent' => 0,
|
||||
'List::Util' => 0,
|
||||
'File::Basename' => 0,
|
||||
'File::Path' => 0,
|
||||
'XML::LibXML' => 0,
|
||||
'XML::SAX::Base' => 0,
|
||||
'XML::SAX::ParserFactory' => 0,
|
||||
'XML::Parser::Expat' => 0,
|
||||
},
|
||||
buildrequires => {
|
||||
'Date::Parse' => 0,
|
||||
'Date::Format' => 0,
|
||||
'Benchmark' => 0,
|
||||
'Cwd' => 0,
|
||||
'Test::More' => 0,
|
||||
'SOAP::Lite' => 0,
|
||||
'Class::Std' => 0.0.8,
|
||||
'Class::Std::Storable' => 0,
|
||||
'XML::XPath' => 0,
|
||||
'XML::Simple' => 0,
|
||||
'XML::LibXML' => 0,
|
||||
'XML::SAX::Base' => 0,
|
||||
'XML::SAX::ParserFactory' => 0,
|
||||
'Pod::Simple::Text' => 0,
|
||||
'XML::SAX::ParserFactory' => 0,
|
||||
|
||||
'List::Util' => 0,
|
||||
'LWP::UserAgent' => 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,
|
||||
},
|
||||
recursive_test_files => 1,
|
||||
)->create_build_script;
|
||||
|
||||
668
CHANGES
668
CHANGES
@@ -1,57 +1,639 @@
|
||||
$Log: CHANGES,v $
|
||||
------------------------------------------------------------------------
|
||||
r142 | kutterma | 2007-08-13 15:55:45 +0200 (Mo, 13 Aug 2007) | 1 line
|
||||
|
||||
Revision 1.19 2004/07/27 13:00:03 lsc
|
||||
- added missing test file
|
||||
typo
|
||||
------------------------------------------------------------------------
|
||||
r141 | kutterma | 2007-08-12 21:45:51 +0200 (So, 12 Aug 2007) | 2 lines
|
||||
|
||||
Revision 1.18 2004/07/16 07:43:05 lsc
|
||||
fixed test scripts for windows
|
||||
- corrected POD error
|
||||
- little speedup in add_FOO methods
|
||||
------------------------------------------------------------------------
|
||||
r140 | kutterma | 2007-08-12 21:27:58 +0200 (So, 12 Aug 2007) | 1 line
|
||||
|
||||
Revision 1.17 2004/07/05 08:19:49 lsc
|
||||
- added wsdl_checkoccurs
|
||||
- corrected POD error
|
||||
------------------------------------------------------------------------
|
||||
r139 | kutterma | 2007-08-12 21:15:59 +0200 (So, 12 Aug 2007) | 1 line
|
||||
|
||||
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
|
||||
- adder repository information
|
||||
------------------------------------------------------------------------
|
||||
r138 | kutterma | 2007-08-12 21:13:08 +0200 (So, 12 Aug 2007) | 1 line
|
||||
|
||||
Revision 1.15 2004/07/02 12:28:31 lsc
|
||||
- documentation update
|
||||
- typo
|
||||
------------------------------------------------------------------------
|
||||
r137 | kutterma | 2007-08-12 21:12:20 +0200 (So, 12 Aug 2007) | 3 lines
|
||||
|
||||
- updated docs
|
||||
- added svn information
|
||||
- cosmetics
|
||||
------------------------------------------------------------------------
|
||||
r136 | kutterma | 2007-08-12 15:11:50 +0200 (So, 12 Aug 2007) | 2 lines
|
||||
|
||||
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.
|
||||
- fixed element ref="" top level- elements in code generator
|
||||
- prepared 2.00_09 pre-release
|
||||
------------------------------------------------------------------------
|
||||
r135 | kutterma | 2007-08-12 14:44:06 +0200 (So, 12 Aug 2007) | 1 line
|
||||
|
||||
Revision 1.13 2004/06/30 12:08:40 lsc
|
||||
- added IServiceInstance (ecmed) to acceptance tests
|
||||
- refined documentation
|
||||
- prepared 2.00_09 pre-release
|
||||
------------------------------------------------------------------------
|
||||
r134 | kutterma | 2007-08-12 14:30:33 +0200 (So, 12 Aug 2007) | 2 lines
|
||||
|
||||
Revision 1.12 2004/06/26 14:13:29 lsc
|
||||
- refined file caching
|
||||
- added descriptive output to test scripts
|
||||
- updated README
|
||||
- bumped up version
|
||||
------------------------------------------------------------------------
|
||||
r133 | kutterma | 2007-08-12 14:27:17 +0200 (So, 12 Aug 2007) | 1 line
|
||||
|
||||
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)
|
||||
- fixed Build.PL to leave Makefile.PL untouched.
|
||||
------------------------------------------------------------------------
|
||||
r132 | kutterma | 2007-08-12 14:21:24 +0200 (So, 12 Aug 2007) | 1 line
|
||||
|
||||
Revision 1.10 2004/06/26 06:30:33 lsc
|
||||
- added filesystem caching using Cache::FileCache
|
||||
- now really added Makefile.PL
|
||||
------------------------------------------------------------------------
|
||||
r131 | kutterma | 2007-08-12 14:18:59 +0200 (So, 12 Aug 2007) | 3 lines
|
||||
|
||||
Revision 1.9 2004/06/24 12:27:23 lsc
|
||||
Cleanup
|
||||
- fixed documentation for generated code with element ref="" declarations
|
||||
- fixed element ref="" test for generated code
|
||||
- added (generated) Makefile.PL to make CPAN testers happy
|
||||
------------------------------------------------------------------------
|
||||
r130 | kutterma | 2007-08-10 15:57:12 +0200 (Fr, 10 Aug 2007) | 1 line
|
||||
|
||||
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
|
||||
- first try at truely callback-based parser (inspired by XML::Compile)
|
||||
------------------------------------------------------------------------
|
||||
r129 | kutterma | 2007-08-07 17:53:40 +0200 (Di, 07 Aug 2007) | 1 line
|
||||
|
||||
Revision 1.7 2004/06/07 13:01:16 lsc
|
||||
added changelog to pod
|
||||
- moved duplicate sub generation out of loop
|
||||
------------------------------------------------------------------------
|
||||
r128 | kutterma | 2007-08-07 14:16:28 +0200 (Di, 07 Aug 2007) | 1 line
|
||||
|
||||
- bool now returns numerical value in bool context, not "true" or "false" (always true...)
|
||||
------------------------------------------------------------------------
|
||||
r127 | kutterma | 2007-08-07 11:45:23 +0200 (Di, 07 Aug 2007) | 1 line
|
||||
|
||||
- fixed test to be timezone sensitive
|
||||
------------------------------------------------------------------------
|
||||
r126 | kutterma | 2007-08-07 11:09:51 +0200 (Di, 07 Aug 2007) | 1 line
|
||||
|
||||
- made test timezone-sensitive
|
||||
------------------------------------------------------------------------
|
||||
r125 | kutterma | 2007-08-07 11:09:16 +0200 (Di, 07 Aug 2007) | 1 line
|
||||
|
||||
- made test timezone-sensitive
|
||||
------------------------------------------------------------------------
|
||||
r124 | kutterma | 2007-08-06 18:05:02 +0200 (Mo, 06 Aug 2007) | 2 lines
|
||||
|
||||
- fixed element ref handling in code generator in ComplexType.
|
||||
- top-level element ref still not supported/tested
|
||||
------------------------------------------------------------------------
|
||||
r123 | kutterma | 2007-08-06 17:48:57 +0200 (Mo, 06 Aug 2007) | 1 line
|
||||
|
||||
- test now dies and outputs code to eval on eval errors
|
||||
------------------------------------------------------------------------
|
||||
r122 | kutterma | 2007-08-06 17:29:46 +0200 (Mo, 06 Aug 2007) | 1 line
|
||||
|
||||
- fixed element ref="" handling in complexType
|
||||
------------------------------------------------------------------------
|
||||
r121 | kutterma | 2007-08-06 17:29:14 +0200 (Mo, 06 Aug 2007) | 1 line
|
||||
|
||||
- added test data for element ref inside complexType
|
||||
------------------------------------------------------------------------
|
||||
r120 | kutterma | 2007-08-06 17:28:54 +0200 (Mo, 06 Aug 2007) | 1 line
|
||||
|
||||
- added test for element ref inside complexType
|
||||
------------------------------------------------------------------------
|
||||
r119 | kutterma | 2007-08-06 17:13:03 +0200 (Mo, 06 Aug 2007) | 1 line
|
||||
|
||||
- fixed element ref handling
|
||||
------------------------------------------------------------------------
|
||||
r118 | kutterma | 2007-08-06 17:12:47 +0200 (Mo, 06 Aug 2007) | 1 line
|
||||
|
||||
- added element ref test data
|
||||
------------------------------------------------------------------------
|
||||
r117 | kutterma | 2007-08-06 17:12:36 +0200 (Mo, 06 Aug 2007) | 1 line
|
||||
|
||||
- added element ref test
|
||||
------------------------------------------------------------------------
|
||||
r116 | kutterma | 2007-08-06 15:47:30 +0200 (Mo, 06 Aug 2007) | 1 line
|
||||
|
||||
- refined docs
|
||||
------------------------------------------------------------------------
|
||||
r115 | kutterma | 2007-08-06 15:39:39 +0200 (Mo, 06 Aug 2007) | 1 line
|
||||
|
||||
- updated docs. Hope the CPAN indexer ignores "=for developers"...
|
||||
------------------------------------------------------------------------
|
||||
r114 | kutterma | 2007-08-06 14:12:28 +0200 (Mo, 06 Aug 2007) | 1 line
|
||||
|
||||
- removed annoying pod
|
||||
------------------------------------------------------------------------
|
||||
r113 | kutterma | 2007-08-05 18:42:09 +0200 (So, 05 Aug 2007) | 5 lines
|
||||
|
||||
- removed SOAP::Lite dependency
|
||||
- updated docs
|
||||
- changed SOAP::WSDL::XSD::Typelib::ComplexType to require the actuall class for element data, not just the base class (good for finding errors earlier)
|
||||
- implemented returning SOAP::SOM objects in SOAP::WSDL
|
||||
- added SOAP::WSDL example(weather_wsdl.pl)
|
||||
------------------------------------------------------------------------
|
||||
r112 | kutterma | 2007-08-03 16:12:57 +0200 (Fr, 03 Aug 2007) | 1 line
|
||||
|
||||
updated docs
|
||||
------------------------------------------------------------------------
|
||||
r111 | kutterma | 2007-08-03 16:12:04 +0200 (Fr, 03 Aug 2007) | 1 line
|
||||
|
||||
- added "skip"
|
||||
------------------------------------------------------------------------
|
||||
r110 | kutterma | 2007-07-31 22:27:25 +0200 (Di, 31 Jul 2007) | 2 lines
|
||||
|
||||
- further work on removing SOAP::Lite dependency
|
||||
- Note: SOAP::WSDL may be broken !
|
||||
------------------------------------------------------------------------
|
||||
r109 | kutterma | 2007-07-31 21:10:40 +0200 (Di, 31 Jul 2007) | 3 lines
|
||||
|
||||
- finished move from XSD::Primitive to Builtin
|
||||
- fixed a few tests
|
||||
- removed typo namespace from TypeLookupt
|
||||
------------------------------------------------------------------------
|
||||
r108 | kutterma | 2007-07-31 21:02:43 +0200 (Di, 31 Jul 2007) | 1 line
|
||||
|
||||
- removed unneeded example stuff
|
||||
------------------------------------------------------------------------
|
||||
r107 | kutterma | 2007-07-31 20:32:43 +0200 (Di, 31 Jul 2007) | 1 line
|
||||
|
||||
- rename to Builtin
|
||||
------------------------------------------------------------------------
|
||||
r106 | kutterma | 2007-07-31 20:32:11 +0200 (Di, 31 Jul 2007) | 1 line
|
||||
|
||||
- prepared rename to Builtin
|
||||
------------------------------------------------------------------------
|
||||
r105 | kutterma | 2007-07-31 13:17:52 +0200 (Di, 31 Jul 2007) | 2 lines
|
||||
|
||||
- added configurable ContentType / charset
|
||||
- maybe split up charset and content type into two methods ?
|
||||
------------------------------------------------------------------------
|
||||
r104 | kutterma | 2007-07-31 00:16:15 +0200 (Di, 31 Jul 2007) | 3 lines
|
||||
|
||||
- removed optional nanoseconds from dateTime conversions
|
||||
- added conversion to date objects
|
||||
- removed fetching WSDL via SOAP::Schema in SOAP::WSDL. SOAP::Lite is still used as base class.
|
||||
------------------------------------------------------------------------
|
||||
r103 | kutterma | 2007-07-30 13:25:06 +0200 (Mo, 30 Jul 2007) | 1 line
|
||||
|
||||
- updated TODO
|
||||
------------------------------------------------------------------------
|
||||
r102 | kutterma | 2007-07-30 13:23:09 +0200 (Mo, 30 Jul 2007) | 2 lines
|
||||
|
||||
- updated Build.PL dependencies
|
||||
- update TODO
|
||||
------------------------------------------------------------------------
|
||||
r101 | kutterma | 2007-07-30 13:22:05 +0200 (Mo, 30 Jul 2007) | 2 lines
|
||||
|
||||
- added dateTime test
|
||||
- fixed pod test
|
||||
------------------------------------------------------------------------
|
||||
r100 | kutterma | 2007-07-27 16:03:15 +0200 (Fr, 27 Jul 2007) | 2 lines
|
||||
|
||||
- allow passing list refs of hash refs to set_value.
|
||||
I hope I got all combinations by now - start getting ugly...
|
||||
------------------------------------------------------------------------
|
||||
r99 | kutterma | 2007-07-26 23:18:35 +0200 (Do, 26 Jul 2007) | 1 line
|
||||
|
||||
- added SOAP::Lite usage (to be removed later)
|
||||
------------------------------------------------------------------------
|
||||
r98 | kutterma | 2007-07-26 23:16:30 +0200 (Do, 26 Jul 2007) | 3 lines
|
||||
|
||||
- removed SOAP::Lite dependency
|
||||
- added set_trace and tracing facility support via callback in call()
|
||||
- added fault_class property to allow different Fault classes (somewhen later on)
|
||||
------------------------------------------------------------------------
|
||||
r97 | kutterma | 2007-07-25 16:59:49 +0200 (Mi, 25 Jul 2007) | 3 lines
|
||||
|
||||
- dateTime now converts date strings into XML date strings
|
||||
- updated docs
|
||||
|
||||
------------------------------------------------------------------------
|
||||
r96 | kutterma | 2007-07-23 11:17:36 +0200 (Mo, 23 Jul 2007) | 3 lines
|
||||
|
||||
- SOAP::WSDL::Definitions::create now
|
||||
- converts '.' in service names to '::' (.NET class separator to perl class separator)
|
||||
- outputs Typemaps and Interface classes in UTF8 to allow proper inclusion of UTF8 documentation from WSDL
|
||||
------------------------------------------------------------------------
|
||||
r95 | kutterma | 2007-07-23 10:26:59 +0200 (Mo, 23 Jul 2007) | 1 line
|
||||
|
||||
- typo
|
||||
------------------------------------------------------------------------
|
||||
r94 | kutterma | 2007-07-23 10:11:46 +0200 (Mo, 23 Jul 2007) | 1 line
|
||||
|
||||
- typo
|
||||
------------------------------------------------------------------------
|
||||
r93 | kutterma | 2007-07-22 23:24:12 +0200 (So, 22 Jul 2007) | 1 line
|
||||
|
||||
updated TODO
|
||||
------------------------------------------------------------------------
|
||||
r92 | kutterma | 2007-07-22 23:19:15 +0200 (So, 22 Jul 2007) | 3 lines
|
||||
|
||||
- WSDLHandler now handles <wsdl:documentation> tags
|
||||
- SOAP::WSDL::Definitions now includes some usable doc in generated interface classes
|
||||
- fixed explain in SimpleType, ComplexType and Element (someway)
|
||||
------------------------------------------------------------------------
|
||||
r91 | kutterma | 2007-07-22 21:18:21 +0200 (So, 22 Jul 2007) | 1 line
|
||||
|
||||
- updated docs
|
||||
------------------------------------------------------------------------
|
||||
r90 | kutterma | 2007-07-22 15:42:23 +0200 (So, 22 Jul 2007) | 1 line
|
||||
|
||||
- updated docs
|
||||
------------------------------------------------------------------------
|
||||
r89 | kutterma | 2007-07-22 15:38:25 +0200 (So, 22 Jul 2007) | 2 lines
|
||||
|
||||
- updated docs
|
||||
- removed useless docs from "internally used only" - modules
|
||||
------------------------------------------------------------------------
|
||||
r88 | kutterma | 2007-07-22 09:17:57 +0200 (So, 22 Jul 2007) | 1 line
|
||||
|
||||
typo
|
||||
------------------------------------------------------------------------
|
||||
r87 | kutterma | 2007-07-21 23:57:46 +0200 (Sa, 21 Jul 2007) | 1 line
|
||||
|
||||
- updated docs
|
||||
------------------------------------------------------------------------
|
||||
r86 | kutterma | 2007-07-21 23:24:24 +0200 (Sa, 21 Jul 2007) | 5 lines
|
||||
|
||||
- removed irritating pod from SOAP::WSDL::XSD::Typelib::Builtin::* classes and put int into SOAP::WSDL::XSD::Typelib::Builtin
|
||||
- added fast constructor creation BEGIN block to all SOAP::WSDL::XSD::Typelib::Builtin::* classes
|
||||
- added examples
|
||||
- updated docs
|
||||
- prepared 2.00_07 pre-release
|
||||
------------------------------------------------------------------------
|
||||
r85 | kutterma | 2007-07-21 18:12:49 +0200 (Sa, 21 Jul 2007) | 4 lines
|
||||
|
||||
- added wsdl2perl code generation script - works against FortuneCookie web service at fullerdata.com
|
||||
- fixed SOAP::WSDL::Client::Base to work as base class for generated classes
|
||||
- added interface generation facility to SOAP::WSDL::Definitions
|
||||
- updated docs (a few)
|
||||
------------------------------------------------------------------------
|
||||
r84 | kutterma | 2007-07-20 15:37:40 +0200 (Fr, 20 Jul 2007) | 9 lines
|
||||
|
||||
- added Expat-based parser
|
||||
- made Expat-based parser the default
|
||||
- added fast "new" method to most important "Builtin" types
|
||||
- added Parser POD
|
||||
- fixed propagating element names in complex types to element elements - element ref="element" should work on
|
||||
class level now (don't know whether typelib supports it yet)
|
||||
- updated tests
|
||||
- updated HACKING
|
||||
- prepared 2.00_06 release
|
||||
------------------------------------------------------------------------
|
||||
r83 | kutterma | 2007-07-19 13:09:33 +0200 (Do, 19 Jul 2007) | 1 line
|
||||
|
||||
- fixed element class generation (removed additional ::)
|
||||
------------------------------------------------------------------------
|
||||
r82 | kutterma | 2007-07-17 22:17:02 +0200 (Di, 17 Jul 2007) | 1 line
|
||||
|
||||
- updated README and HACKING
|
||||
------------------------------------------------------------------------
|
||||
r81 | kutterma | 2007-07-17 22:00:14 +0200 (Di, 17 Jul 2007) | 5 lines
|
||||
|
||||
- added parent ref in SOAP::WSDL::Base - now we have a real tree, and maybe can completely support namespaces some day
|
||||
- replaced grep by List::Util::first where appropriate
|
||||
- code cleanup
|
||||
- fixed test for Code Generation
|
||||
- updated a few tests
|
||||
------------------------------------------------------------------------
|
||||
r80 | kutterma | 2007-07-17 17:00:48 +0200 (Di, 17 Jul 2007) | 1 line
|
||||
|
||||
- improved pod in generated classes
|
||||
------------------------------------------------------------------------
|
||||
r79 | kutterma | 2007-07-17 14:41:44 +0200 (Di, 17 Jul 2007) | 1 line
|
||||
|
||||
- made explain look nicer
|
||||
------------------------------------------------------------------------
|
||||
r78 | kutterma | 2007-07-15 12:25:03 +0200 (So, 15 Jul 2007) | 7 lines
|
||||
|
||||
- SOAP::WSDL::Definitions can now generate
|
||||
- Typemaps
|
||||
- Type and Element classes
|
||||
- fixed SOAP::WSDL::XSD::Typelib::ComplexType to support elements with type="ComplexType" definitions
|
||||
- moved toClass method in SOAP::WSDL::XSD::ComplexType, Element and SimpleType to to_class and added compatibility wrapper with warning for toClass calls
|
||||
- added generator test
|
||||
- updated docs
|
||||
------------------------------------------------------------------------
|
||||
r77 | kutterma | 2007-07-14 10:46:54 +0200 (Sa, 14 Jul 2007) | 1 line
|
||||
|
||||
- started working on high-level code generator
|
||||
------------------------------------------------------------------------
|
||||
r76 | kutterma | 2007-07-13 09:21:33 +0200 (Fr, 13 Jul 2007) | 1 line
|
||||
|
||||
- fixed handling of complex data (hashes with lists embedded lists of objects)
|
||||
------------------------------------------------------------------------
|
||||
r75 | kutterma | 2007-07-10 12:08:39 +0200 (Di, 10 Jul 2007) | 1 line
|
||||
|
||||
- removed unneeded SOAP::Lite calls
|
||||
------------------------------------------------------------------------
|
||||
r74 | kutterma | 2007-07-10 12:08:10 +0200 (Di, 10 Jul 2007) | 1 line
|
||||
|
||||
- updated to new SOAP::Lite API
|
||||
------------------------------------------------------------------------
|
||||
r73 | kutterma | 2007-07-10 12:00:25 +0200 (Di, 10 Jul 2007) | 6 lines
|
||||
|
||||
- re-integrated old SOAP::WSDL tests
|
||||
- updated docs
|
||||
- SOAP::WSDL::XSD::Typelib::Builtin::string now escapes XML builtin entities on serialization
|
||||
- SOAP::WSDL::XSD::Element now supports generating classes for elements and types into different namespaces
|
||||
- SOAP::WSDL::Definitions now supports different namespaces for elements and types when generating typmaps
|
||||
- 2.00_05 release preparation
|
||||
------------------------------------------------------------------------
|
||||
r72 | kutterma | 2007-07-06 11:20:56 +0200 (Fr, 06 Jul 2007) | 1 line
|
||||
|
||||
- fixed detail (typo)
|
||||
------------------------------------------------------------------------
|
||||
r71 | kutterma | 2007-07-05 16:13:28 +0200 (Do, 05 Jul 2007) | 1 line
|
||||
|
||||
- TODO comments added
|
||||
------------------------------------------------------------------------
|
||||
r70 | kutterma | 2007-07-04 16:14:50 +0200 (Mi, 04 Jul 2007) | 2 lines
|
||||
|
||||
- updated docs
|
||||
- prepared 2.00_04 release
|
||||
------------------------------------------------------------------------
|
||||
r69 | kutterma | 2007-07-04 16:07:54 +0200 (Mi, 04 Jul 2007) | 1 line
|
||||
|
||||
- ComplexType now ignores xmlns - TODO: check xmlns, don't ignore...
|
||||
------------------------------------------------------------------------
|
||||
r68 | kutterma | 2007-07-04 11:25:31 +0200 (Mi, 04 Jul 2007) | 1 line
|
||||
|
||||
- made builtin types with overloads serializable
|
||||
------------------------------------------------------------------------
|
||||
r67 | kutterma | 2007-07-04 09:51:06 +0200 (Mi, 04 Jul 2007) | 4 lines
|
||||
|
||||
- updated docs
|
||||
- removed unneeded uses from test
|
||||
- added Build requirements from tests
|
||||
- prepared 2.00_03 release
|
||||
------------------------------------------------------------------------
|
||||
r66 | kutterma | 2007-07-04 00:06:29 +0200 (Mi, 04 Jul 2007) | 3 lines
|
||||
|
||||
- split up builtin type lib into single files for Class::Std::Storable
|
||||
- fixed more tests
|
||||
- fixed complexType serialization for non-objecs
|
||||
------------------------------------------------------------------------
|
||||
r65 | kutterma | 2007-07-03 16:52:54 +0200 (Di, 03 Jul 2007) | 2 lines
|
||||
|
||||
- fixed a few tests
|
||||
- added performance improvements
|
||||
------------------------------------------------------------------------
|
||||
r64 | kutterma | 2007-07-03 15:09:27 +0200 (Di, 03 Jul 2007) | 1 line
|
||||
|
||||
- small performance improvements
|
||||
------------------------------------------------------------------------
|
||||
r63 | kutterma | 2007-07-03 14:37:28 +0200 (Di, 03 Jul 2007) | 3 lines
|
||||
|
||||
- fixed serializing complextypes correctly
|
||||
- fixed handling has attribute refs in new
|
||||
- fixed performance problems in MessageHandler
|
||||
------------------------------------------------------------------------
|
||||
r62 | kutterma | 2007-07-03 14:37:14 +0200 (Di, 03 Jul 2007) | 1 line
|
||||
|
||||
- re-added
|
||||
------------------------------------------------------------------------
|
||||
r61 | kutterma | 2007-07-03 14:36:59 +0200 (Di, 03 Jul 2007) | 1 line
|
||||
|
||||
|
||||
------------------------------------------------------------------------
|
||||
r60 | kutterma | 2007-07-01 09:52:41 +0200 (So, 01 Jul 2007) | 2 lines
|
||||
|
||||
- fixed lots of tests
|
||||
- attic tests may be re-integrated now...
|
||||
------------------------------------------------------------------------
|
||||
r59 | kutterma | 2007-06-28 13:07:35 +0200 (Do, 28 Jun 2007) | 1 line
|
||||
|
||||
- added ignore for dist tar.gz
|
||||
------------------------------------------------------------------------
|
||||
r58 | kutterma | 2007-06-28 13:06:25 +0200 (Do, 28 Jun 2007) | 1 line
|
||||
|
||||
- updated buildrequires
|
||||
------------------------------------------------------------------------
|
||||
r57 | kutterma | 2007-06-28 13:05:03 +0200 (Do, 28 Jun 2007) | 1 line
|
||||
|
||||
- typo
|
||||
------------------------------------------------------------------------
|
||||
r56 | kutterma | 2007-06-28 11:15:24 +0200 (Do, 28 Jun 2007) | 1 line
|
||||
|
||||
- pre-release 2.00_01
|
||||
------------------------------------------------------------------------
|
||||
r55 | kutterma | 2007-06-28 10:23:20 +0200 (Do, 28 Jun 2007) | 1 line
|
||||
|
||||
- moved old tests to attic
|
||||
------------------------------------------------------------------------
|
||||
r54 | kutterma | 2007-06-28 10:15:41 +0200 (Do, 28 Jun 2007) | 1 line
|
||||
|
||||
- fixed a few typos
|
||||
------------------------------------------------------------------------
|
||||
r53 | kutterma | 2007-06-28 10:10:41 +0200 (Do, 28 Jun 2007) | 3 lines
|
||||
|
||||
- fixed MessageHandler to support deserializing into objects which return false in boolean context
|
||||
- updated docs
|
||||
- fixed Fault11 (named detail correctly)
|
||||
------------------------------------------------------------------------
|
||||
r52 | kutterma | 2007-06-27 17:36:01 +0200 (Mi, 27 Jun 2007) | 3 lines
|
||||
|
||||
- added Fault for SOAP 1.1 implementation
|
||||
- fixed ComplexType - though it doesn't work quite for faults yet...
|
||||
|
||||
------------------------------------------------------------------------
|
||||
r51 | kutterma | 2007-06-27 13:27:59 +0200 (Mi, 27 Jun 2007) | 13 lines
|
||||
|
||||
- added test for sending objects via call()
|
||||
- modified Client to accept objects of type SOAP::WSDL::XSD::Typelib::Builtin::anyType as message content
|
||||
without checking the WSDL objects
|
||||
Note:
|
||||
- SOAPAction is just guessed - needs to be replaced by something better
|
||||
- The method should be looked up from the typelib, too, and serialized according to the rules specified in the WSDL
|
||||
and dumped into the typelib.
|
||||
|
||||
- updated to_typelib to include top element
|
||||
- fixed element and complextype templates for toClass
|
||||
|
||||
|
||||
|
||||
------------------------------------------------------------------------
|
||||
r50 | kutterma | 2007-06-27 00:01:32 +0200 (Mi, 27 Jun 2007) | 1 line
|
||||
|
||||
- added xsi xmlns to envelope
|
||||
------------------------------------------------------------------------
|
||||
r49 | kutterma | 2007-06-26 23:52:18 +0200 (Di, 26 Jun 2007) | 1 line
|
||||
|
||||
- cosmetics and a few doc updates
|
||||
------------------------------------------------------------------------
|
||||
r48 | kutterma | 2007-06-26 22:47:52 +0200 (Di, 26 Jun 2007) | 2 lines
|
||||
|
||||
- refactored element serializing to make it somewhat more consistent
|
||||
- added nillable implementation for Elements
|
||||
------------------------------------------------------------------------
|
||||
r47 | kutterma | 2007-06-26 18:06:59 +0200 (Di, 26 Jun 2007) | 1 line
|
||||
|
||||
- removed shebang
|
||||
------------------------------------------------------------------------
|
||||
r46 | kutterma | 2007-06-26 18:06:33 +0200 (Di, 26 Jun 2007) | 1 line
|
||||
|
||||
- added warnings
|
||||
------------------------------------------------------------------------
|
||||
r45 | kutterma | 2007-06-26 17:39:09 +0200 (Di, 26 Jun 2007) | 3 lines
|
||||
|
||||
- got toClass working for generating WSDL based type libraries.
|
||||
- changed typelib base class behavior to qualify first element called.
|
||||
TODO (a bigger one): Fully support namespaces...
|
||||
------------------------------------------------------------------------
|
||||
r44 | kutterma | 2007-06-26 12:10:33 +0200 (Di, 26 Jun 2007) | 14 lines
|
||||
|
||||
- changed Typelib::Element to work as attribute of a type (serialize serializes start_tag and end_tag provided by Typelib::Element around it's vontent, if present)
|
||||
- worked on toClass functionality with embedded templates.
|
||||
There's much to do - current impl should support:
|
||||
* <element name="name" type="type"
|
||||
* <element name="name"><simpleType>
|
||||
* <element name="name"><complexType>
|
||||
|
||||
* <simpleType ...><list>
|
||||
* <simpleType ...><restriction>
|
||||
|
||||
* <complexType ...><all>
|
||||
* <complexType ...><sequence>
|
||||
|
||||
All other variants are not completely supported yet.
|
||||
------------------------------------------------------------------------
|
||||
r43 | kutterma | 2007-06-25 18:58:56 +0200 (Mo, 25 Jun 2007) | 1 line
|
||||
|
||||
- broke element again...
|
||||
------------------------------------------------------------------------
|
||||
r42 | kutterma | 2007-06-25 17:30:34 +0200 (Mo, 25 Jun 2007) | 3 lines
|
||||
|
||||
- fixed to_typemap to report atomic simple and complex types correctly
|
||||
- update tests
|
||||
- renamed WSDLFilter to WSDLHandler
|
||||
------------------------------------------------------------------------
|
||||
r41 | kutterma | 2007-06-25 17:29:41 +0200 (Mo, 25 Jun 2007) | 1 line
|
||||
|
||||
|
||||
------------------------------------------------------------------------
|
||||
r40 | kutterma | 2007-06-25 14:15:40 +0200 (Mo, 25 Jun 2007) | 2 lines
|
||||
|
||||
- Client.pm now uses XML::LibXML as default and falls back on XML::SAX::ParserFactory if not present
|
||||
- fixed tests
|
||||
------------------------------------------------------------------------
|
||||
r39 | kutterma | 2007-06-25 14:07:28 +0200 (Mo, 25 Jun 2007) | 2 lines
|
||||
|
||||
- typo in Element
|
||||
- fixed tests
|
||||
------------------------------------------------------------------------
|
||||
r38 | kutterma | 2007-06-25 10:31:20 +0200 (Mo, 25 Jun 2007) | 2 lines
|
||||
|
||||
- made WSDLFilter.pm a inside out class and let it run without XML::SAX::Base (This probably breaks a lot of tests - we need to implement XML::LibXML semantics in all tests / classes which use it)
|
||||
- first swag at to_typemap Typemap generation. to_typemap implemented throughout the WSDL:: modules. Some implementations (Elenenet.pm, ComplexType.pm) need further work for correctly handling atomic simpleType / complexType definitions.
|
||||
------------------------------------------------------------------------
|
||||
r37 | kutterma | 2007-06-24 09:15:22 +0200 (So, 24 Jun 2007) | 3 lines
|
||||
|
||||
- added test for on-the-fly created ComplexType
|
||||
- fixed ComplexType factory to really work
|
||||
- startet working on Element facets
|
||||
------------------------------------------------------------------------
|
||||
r36 | kutterma | 2007-06-24 09:14:46 +0200 (So, 24 Jun 2007) | 2 lines
|
||||
|
||||
- added test for on-the-fly created ComplexType
|
||||
- startet working on Element facets
|
||||
------------------------------------------------------------------------
|
||||
r35 | kutterma | 2007-06-24 08:13:32 +0200 (So, 24 Jun 2007) | 1 line
|
||||
|
||||
- implemented ComplexType as class factory to get rid of the annoying START every subclass had to implement.
|
||||
------------------------------------------------------------------------
|
||||
r34 | kutterma | 2007-06-23 23:22:35 +0200 (Sa, 23 Jun 2007) | 2 lines
|
||||
|
||||
- added XSD Typelib SimpleType, Element and ComplexType base classes (stereotypes).
|
||||
ComplexType's not yet complete (no restriction / extension etc. handling).
|
||||
------------------------------------------------------------------------
|
||||
r33 | kutterma | 2007-06-23 11:04:56 +0200 (Sa, 23 Jun 2007) | 2 lines
|
||||
|
||||
- added SOAP::WSDL::XSD::Typelib::Builtin implementation of builtin XML Schema datatypes with built-in stringification, boolification and numerification.
|
||||
- SAX::MessageHandler now deserializes simple types in SOAP messages into SOAP::WSDL::XSD::Typelib::Builtin (provided these are named in the ClassResolver...)
|
||||
------------------------------------------------------------------------
|
||||
r32 | kutterma | 2007-06-23 02:14:16 +0200 (Sa, 23 Jun 2007) | 4 lines
|
||||
|
||||
- added pod
|
||||
- added ref handling for elements
|
||||
- added abstract handling for elements (easy...)
|
||||
- added storing of content model (simpleContent/complexContent) to simpleType and complexType, though the attribute is still ignored in serializing
|
||||
------------------------------------------------------------------------
|
||||
r31 | kutterma | 2007-06-23 00:37:18 +0200 (Sa, 23 Jun 2007) | 1 line
|
||||
|
||||
- renamed MessageFilter to MessageHandler
|
||||
------------------------------------------------------------------------
|
||||
r30 | kutterma | 2007-06-23 00:35:54 +0200 (Sa, 23 Jun 2007) | 1 line
|
||||
|
||||
- renamed MessageFilter to MessageHandler
|
||||
------------------------------------------------------------------------
|
||||
r29 | kutterma | 2007-06-23 00:35:16 +0200 (Sa, 23 Jun 2007) | 2 lines
|
||||
|
||||
- switched to Class::Std::Storable
|
||||
- renamed MessageFilter to MessageHandler
|
||||
------------------------------------------------------------------------
|
||||
r28 | kutterma | 2007-06-22 18:56:28 +0200 (Fr, 22 Jun 2007) | 3 lines
|
||||
|
||||
- optimised SOAP::WSDL::SAX::MessageFilter for performance
|
||||
- moved Typelob into own directory and load it dynamically from test script
|
||||
- added some pod
|
||||
------------------------------------------------------------------------
|
||||
r27 | kutterma | 2007-06-22 15:34:28 +0200 (Fr, 22 Jun 2007) | 5 lines
|
||||
|
||||
- modified SOAP::WSDL::XSD lib to allow serializing of object hierarchies
|
||||
- added SOAP::WSDL::SAX::MessageFilter for creating object hierarchies from SOAP messages
|
||||
- moved Builtin XML Schema types to SOAP::WSDL:XSD::Schema::Builtin
|
||||
- added test + benchmark for serializing /deserializing SOAP messages into object trees
|
||||
- fixed Client to use SOAP::WSDL::Types as typelib, not first SOAP::WSDL::XSD::Schema
|
||||
------------------------------------------------------------------------
|
||||
r26 | kutterma | 2007-06-21 23:35:30 +0200 (Do, 21 Jun 2007) | 2 lines
|
||||
|
||||
- first swag at a typed SOAP Message parser.
|
||||
Typelib is still to be implemented...
|
||||
------------------------------------------------------------------------
|
||||
r25 | kutterma | 2007-06-21 18:14:49 +0200 (Do, 21 Jun 2007) | 1 line
|
||||
|
||||
- added missing files from last commit
|
||||
------------------------------------------------------------------------
|
||||
r24 | kutterma | 2007-06-19 00:29:36 +0200 (Di, 19 Jun 2007) | 3 lines
|
||||
|
||||
- worked a bit on explain
|
||||
- introduced handling of multiple schema definitions in one WSDL file
|
||||
- fixed propagating targetNamespace to child elements in WSDLFilter
|
||||
------------------------------------------------------------------------
|
||||
r23 | kutterma | 2007-06-16 14:48:30 +0200 (Sa, 16 Jun 2007) | 1 line
|
||||
|
||||
- updated new SOAP::WSDL framework to use inside out classes based on Class::Std (not yet complete)
|
||||
------------------------------------------------------------------------
|
||||
r22 | kutterma | 2007-06-12 23:19:41 +0200 (Di, 12 Jun 2007) | 4 lines
|
||||
|
||||
- updated a few tests
|
||||
- fixed a few WSDLs
|
||||
- fixed handling of elements with minOccurs 0
|
||||
- fixed setting of minOccurs/maxOccurs for all/sequence complexTypes
|
||||
------------------------------------------------------------------------
|
||||
r21 | kutterma | 2007-06-08 21:38:41 +0200 (Fr, 08 Jun 2007) | 2 lines
|
||||
|
||||
- updated a few tests
|
||||
- fixed namespaces in tests
|
||||
------------------------------------------------------------------------
|
||||
r19 | kutterma | 2007-05-31 16:58:18 +0200 (Do, 31 Mai 2007) | 10 lines
|
||||
|
||||
- first swag at a WSDL-generated Object-tree based SOAP client.
|
||||
|
||||
Works as following:
|
||||
a) a sax filter transforms the sax stream from a wsdl into a perl object tree
|
||||
b) the perl object tree has methods for performing the following tasks:
|
||||
a) explain: Tell what services and methods are there, and how to use them
|
||||
b) serialize: Serialize data structures to the XML defined in the WSDL & schema
|
||||
c) The client uses the generated XML to call the SOAP Server. Unfortunately, SOAP::Lite
|
||||
does not allow custom XML to be rendered as a method's "value", so we have to replace
|
||||
call() completely and generate the envelope on our own (which is not complete yet).
|
||||
------------------------------------------------------------------------
|
||||
r9 | kutterma | 2007-05-28 17:08:41 +0200 (Mo, 28 Mai 2007) | 1 line
|
||||
|
||||
- first try at bindings support - see t/12/bindings on how we could find out bindings and portname from a target URL
|
||||
------------------------------------------------------------------------
|
||||
r4 | kutterma | 2007-05-28 15:15:03 +0200 (Mo, 28 Mai 2007) | 1 line
|
||||
|
||||
- move from private repository to sourceforge
|
||||
------------------------------------------------------------------------
|
||||
|
||||
39
HACKING
39
HACKING
@@ -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
|
||||
43
MANIFEST
43
MANIFEST
@@ -1,5 +1,30 @@
|
||||
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/weather_wsdl.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 +33,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
|
||||
@@ -21,9 +51,9 @@ lib/SOAP/WSDL/SOAP/Typelib/Fault11.pm
|
||||
lib/SOAP/WSDL/SoapOperation.pm
|
||||
lib/SOAP/WSDL/TypeLookup.pm
|
||||
lib/SOAP/WSDL/Types.pm
|
||||
lib/SOAP/WSDL/XSD/Builtin.pm
|
||||
lib/SOAP/WSDL/XSD/ComplexType.pm
|
||||
lib/SOAP/WSDL/XSD/Element.pm
|
||||
lib/SOAP/WSDL/XSD/Primitive.pm
|
||||
lib/SOAP/WSDL/XSD/Schema.pm
|
||||
lib/SOAP/WSDL/XSD/Schema/Builtin.pm
|
||||
lib/SOAP/WSDL/XSD/SimpleType.pm
|
||||
@@ -78,7 +108,7 @@ lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm
|
||||
lib/SOAP/WSDL/XSD/Typelib/Element.pm
|
||||
lib/SOAP/WSDL/XSD/Typelib/SimpleType.pm
|
||||
LICENSE
|
||||
MANIFEST
|
||||
MANIFEST This list of files
|
||||
META.yml
|
||||
README
|
||||
t/001_use.t
|
||||
@@ -96,6 +126,8 @@ t/013_complexType.t
|
||||
t/014_sax_typelib.t
|
||||
t/015_to_typemap.t
|
||||
t/016_client_object.t
|
||||
t/017_generator.t
|
||||
t/018_generator.t
|
||||
t/020_storable.t
|
||||
t/098_pod.t
|
||||
t/acceptance/results/03_complexType-all.xml
|
||||
@@ -123,6 +155,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/Expat/01_expat.t
|
||||
t/lib/MyComplexType.pm
|
||||
t/lib/MyElement.pm
|
||||
t/lib/MySimpleType.pm
|
||||
@@ -147,5 +180,9 @@ 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/97_pod.t
|
||||
t/SOAP/WSDL/XSD/Typelib/Builtin/001_string.t
|
||||
t/SOAP/WSDL/XSD/Typelib/Builtin/002_dateTime.t
|
||||
t/SOAP/WSDL/XSD/Typelib/Builtin/002_time.t
|
||||
t/SOAP/WSDL/XSD/Typelib/Builtin/003_date.t
|
||||
TODO
|
||||
Makefile.PL
|
||||
|
||||
24
META.yml
24
META.yml
@@ -1,17 +1,22 @@
|
||||
---
|
||||
name: SOAP-WSDL
|
||||
version: 2.00_05
|
||||
version: 2.00_10
|
||||
author:
|
||||
abstract: SOAP with WSDL support
|
||||
license: artistic
|
||||
requires:
|
||||
Class::Std: v0.0.8
|
||||
Class::Std::Storable: 0
|
||||
SOAP::Lite: 0
|
||||
Date::Format: 0
|
||||
Date::Parse: 0
|
||||
File::Basename: 0
|
||||
File::Path: 0
|
||||
LWP::UserAgent: 0
|
||||
List::Util: 0
|
||||
XML::LibXML: 0
|
||||
XML::Parser::Expat: 0
|
||||
XML::SAX::Base: 0
|
||||
XML::SAX::ParserFactory: 0
|
||||
XML::XPath: 0
|
||||
generated_by: Module::Build version 0.2808
|
||||
meta-spec:
|
||||
url: http://module-build.sourceforge.net/META-spec-v1.2.html
|
||||
@@ -19,7 +24,7 @@ meta-spec:
|
||||
provides:
|
||||
SOAP::WSDL:
|
||||
file: lib/SOAP/WSDL.pm
|
||||
version: 2.00_05
|
||||
version: 2.00_10
|
||||
SOAP::WSDL::Base:
|
||||
file: lib/SOAP/WSDL/Base.pm
|
||||
SOAP::WSDL::Binding:
|
||||
@@ -28,11 +33,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:
|
||||
@@ -47,8 +55,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:
|
||||
@@ -59,12 +65,12 @@ provides:
|
||||
file: lib/SOAP/WSDL/TypeLookup.pm
|
||||
SOAP::WSDL::Types:
|
||||
file: lib/SOAP/WSDL/Types.pm
|
||||
SOAP::WSDL::XSD::Builtin:
|
||||
file: lib/SOAP/WSDL/XSD/Builtin.pm
|
||||
SOAP::WSDL::XSD::ComplexType:
|
||||
file: lib/SOAP/WSDL/XSD/ComplexType.pm
|
||||
SOAP::WSDL::XSD::Element:
|
||||
file: lib/SOAP/WSDL/XSD/Element.pm
|
||||
SOAP::WSDL::XSD::Primitive:
|
||||
file: lib/SOAP/WSDL/XSD/Primitive.pm
|
||||
SOAP::WSDL::XSD::Schema:
|
||||
file: lib/SOAP/WSDL/XSD/Schema.pm
|
||||
SOAP::WSDL::XSD::Schema::Builtin:
|
||||
|
||||
31
Makefile.PL
Normal file
31
Makefile.PL
Normal file
@@ -0,0 +1,31 @@
|
||||
# Note: this file was auto-generated by Module::Build::Compat version 0.03
|
||||
|
||||
unless (eval "use Module::Build::Compat 0.02; 1" ) {
|
||||
print "This module requires Module::Build to install itself.\n";
|
||||
|
||||
require ExtUtils::MakeMaker;
|
||||
my $yn = ExtUtils::MakeMaker::prompt
|
||||
(' Install Module::Build now from CPAN?', 'y');
|
||||
|
||||
unless ($yn =~ /^y/i) {
|
||||
die " *** Cannot install without Module::Build. Exiting ...\n";
|
||||
}
|
||||
|
||||
require Cwd;
|
||||
require File::Spec;
|
||||
require CPAN;
|
||||
|
||||
# Save this 'cause CPAN will chdir all over the place.
|
||||
my $cwd = Cwd::cwd();
|
||||
|
||||
CPAN::Shell->install('Module::Build::Compat');
|
||||
CPAN::Shell->expand("Module", "Module::Build::Compat")->uptodate
|
||||
or die "Couldn't install Module::Build, giving up.\n";
|
||||
|
||||
chdir $cwd or die "Cannot chdir() back to $cwd: $!";
|
||||
}
|
||||
eval "use Module::Build::Compat 0.02; 1" or die $@;
|
||||
|
||||
Module::Build::Compat->run_build_pl(args => \@ARGV);
|
||||
require Module::Build;
|
||||
Module::Build::Compat->write_makefile(build_class => 'Module::Build');
|
||||
28
README
28
README
@@ -1,4 +1,26 @@
|
||||
INTRO
|
||||
-----
|
||||
|
||||
SOAP-WSDL provides a SOAP client with WSDL support.
|
||||
|
||||
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.
|
||||
|
||||
INSTALLING
|
||||
----------
|
||||
|
||||
Use the following mantra:
|
||||
|
||||
perl Build.PL
|
||||
perl Build
|
||||
perl Build test
|
||||
perl Build install
|
||||
|
||||
If you don't have Module::Build installed, you may also use
|
||||
|
||||
perl Makefile.PL
|
||||
make
|
||||
make test
|
||||
make install
|
||||
|
||||
Note that Module::Build is the recommended installer - make will not run
|
||||
all tests provided with SOAP-WSDL.
|
||||
36
TODO
Normal file
36
TODO
Normal file
@@ -0,0 +1,36 @@
|
||||
- support embedded atomic types by including a second (and third and fourth)
|
||||
package type_prefix::complex_type::element_name element package.
|
||||
Allow unlimited depth (though this is rather wicked).
|
||||
- fixup generated pod so it looks nice in SOAP::WSDL::Definitions.
|
||||
- remove benchmarks from tests. Create benchmark/ directory and store benchmarks in.
|
||||
- add tests for SOAP::WSDL::Definitions::create
|
||||
- test for correct creation
|
||||
- test against web service (fullerdata.com?)
|
||||
- Improve docs
|
||||
- Partially DONE
|
||||
- Remove SOAP::Lite dependency - for now, just support HTTP(s) via LWP::UserAgent.
|
||||
- Partially DONE. SOAP::WSDL still uses SOAP::Schema
|
||||
- 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.
|
||||
- add default Fault11 typemap to generated typemaps
|
||||
- DONE
|
||||
- SOAP::WSDL::Definitions::create creates bad interface docs. Fix it.
|
||||
- DONE
|
||||
- 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.
|
||||
|
||||
|
||||
141
bin/wsdl2perl.pl
Normal file
141
bin/wsdl2perl.pl
Normal file
@@ -0,0 +1,141 @@
|
||||
#!/usr/bin/perl -w
|
||||
use strict;
|
||||
use warnings;
|
||||
use Fcntl;
|
||||
use IO::File;
|
||||
use Pod::Usage;
|
||||
use Getopt::Long;
|
||||
use LWP::UserAgent;
|
||||
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/',
|
||||
proxy => undef
|
||||
);
|
||||
|
||||
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
|
||||
proxy|x=s
|
||||
)
|
||||
);
|
||||
|
||||
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();
|
||||
|
||||
local $ENV{HTTP_PROXY} = $opt{proxy} if $opt{proxy};
|
||||
my $lwp = LWP::UserAgent->new();
|
||||
my $response = $lwp->get($url);
|
||||
die $response->message(), "\n" if $response->code != 200;
|
||||
|
||||
my $xml = $response->content();
|
||||
|
||||
$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
|
||||
47
example/fortune.pl
Normal file
47
example/fortune.pl
Normal file
@@ -0,0 +1,47 @@
|
||||
# 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;
|
||||
my $cookieService = MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie->new();
|
||||
|
||||
my $cookie;
|
||||
$cookie = $cookieService->GetFortuneCookie()
|
||||
or die "$cookie";
|
||||
|
||||
print $cookie; # ->get_GetFortuneCookieResult()->get_value, "\n";
|
||||
|
||||
$cookie = $cookieService->GetSpecificCookie({ index => 23 })
|
||||
or die "$cookie";
|
||||
|
||||
print $cookie->get_GetSpecificCookieResult(), "\n";
|
||||
|
||||
print $cookie;
|
||||
|
||||
|
||||
=for demo:
|
||||
|
||||
# the same in SOAP lite (second call)
|
||||
#
|
||||
|
||||
use SOAP::Lite;
|
||||
|
||||
my $lite = SOAP::Lite->new()->on_action(sub { join '/', @_ } )
|
||||
->proxy('http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx');
|
||||
|
||||
$lite->call(
|
||||
SOAP::Data->name('GetSpecificCookie')
|
||||
->attr({ 'xmlns', 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' }),
|
||||
SOAP::Data->name('index')->value(23)
|
||||
);
|
||||
|
||||
die $soap->message() if ($soap->fault());
|
||||
print $soap->result();
|
||||
71
example/lib/MyElements/CountCookies.pm
Normal file
71
example/lib/MyElements/CountCookies.pm
Normal 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
|
||||
|
||||
85
example/lib/MyElements/CountCookiesResponse.pm
Normal file
85
example/lib/MyElements/CountCookiesResponse.pm
Normal 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
|
||||
|
||||
85
example/lib/MyElements/GetCitiesByCountry.pm
Normal file
85
example/lib/MyElements/GetCitiesByCountry.pm
Normal 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
|
||||
|
||||
85
example/lib/MyElements/GetCitiesByCountryResponse.pm
Normal file
85
example/lib/MyElements/GetCitiesByCountryResponse.pm
Normal 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
|
||||
|
||||
71
example/lib/MyElements/GetFortuneCookie.pm
Normal file
71
example/lib/MyElements/GetFortuneCookie.pm
Normal 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
|
||||
|
||||
85
example/lib/MyElements/GetFortuneCookieResponse.pm
Normal file
85
example/lib/MyElements/GetFortuneCookieResponse.pm
Normal 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
|
||||
|
||||
85
example/lib/MyElements/GetSpecificCookie.pm
Normal file
85
example/lib/MyElements/GetSpecificCookie.pm
Normal 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
|
||||
|
||||
85
example/lib/MyElements/GetSpecificCookieResponse.pm
Normal file
85
example/lib/MyElements/GetSpecificCookieResponse.pm
Normal 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
|
||||
|
||||
97
example/lib/MyElements/GetWeather.pm
Normal file
97
example/lib/MyElements/GetWeather.pm
Normal 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
|
||||
|
||||
84
example/lib/MyElements/GetWeatherResponse.pm
Normal file
84
example/lib/MyElements/GetWeatherResponse.pm
Normal file
@@ -0,0 +1,84 @@
|
||||
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
|
||||
|
||||
60
example/lib/MyElements/int.pm
Normal file
60
example/lib/MyElements/int.pm
Normal 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
|
||||
|
||||
71
example/lib/MyElements/readNodeCount.pm
Normal file
71
example/lib/MyElements/readNodeCount.pm
Normal 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
|
||||
|
||||
85
example/lib/MyElements/readNodeCountResponse.pm
Normal file
85
example/lib/MyElements/readNodeCountResponse.pm
Normal 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
|
||||
|
||||
60
example/lib/MyElements/string.pm
Normal file
60
example/lib/MyElements/string.pm
Normal 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.webserviceX.NET' }
|
||||
|
||||
__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
|
||||
|
||||
@@ -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
|
||||
|
||||
68
example/lib/MyInterfaces/GlobalWeather.pm
Normal file
68
example/lib/MyInterfaces/GlobalWeather.pm
Normal file
@@ -0,0 +1,68 @@
|
||||
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 METHODS
|
||||
|
||||
=head2 GetWeather
|
||||
|
||||
Get weather report for all major cities around the world.
|
||||
|
||||
SYNOPSIS:
|
||||
|
||||
$service->GetWeather({
|
||||
'CityName' => $someValue,
|
||||
'CountryName' => $someValue,
|
||||
});
|
||||
|
||||
|
||||
=head2 GetCitiesByCountry
|
||||
|
||||
Get all major cities by country name(full / part).
|
||||
|
||||
SYNOPSIS:
|
||||
|
||||
$service->GetCitiesByCountry({
|
||||
'CountryName' => $someValue,
|
||||
});
|
||||
|
||||
|
||||
|
||||
=cut
|
||||
|
||||
@@ -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__
|
||||
|
||||
50
example/lib/MyTypemaps/GlobalWeather.pm
Normal file
50
example/lib/MyTypemaps/GlobalWeather.pm
Normal file
@@ -0,0 +1,50 @@
|
||||
package MyTypemaps::GlobalWeather;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my %typemap = (
|
||||
# SOAP 1.1 fault typemap
|
||||
'Fault' => 'SOAP::WSDL::SOAP::Typelib::Fault11',
|
||||
'Fault/faultcode' => 'SOAP::WSDL::XSD::Typelib::Builtin::anyURI',
|
||||
'Fault/faultactor' => 'SOAP::WSDL::XSD::Typelib::Builtin::TOKEN',
|
||||
'Fault/faultstring' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
||||
'Fault/detail' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
||||
|
||||
# generated 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)
|
||||
|
||||
|
||||
|
||||
|
||||
);
|
||||
|
||||
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
19
example/weather.pl
Normal file
@@ -0,0 +1,19 @@
|
||||
# Accessing the globalweather service at
|
||||
# www.webservicex.net/GlobalWeather/GlobalWeather.asmx
|
||||
#
|
||||
# Note that the GlobalWeather web service returns a (quoted) XML structure -
|
||||
# don't be surprised by the response's format.
|
||||
#
|
||||
# I have no connection to www.webservicex.net
|
||||
# Use this script at your own risk.
|
||||
#
|
||||
# This script demonstrates the use of a interface generated by wsdl2perl.pl
|
||||
|
||||
use lib 'lib/';
|
||||
use MyInterfaces::GlobalWeather;
|
||||
my $weather = MyInterfaces::GlobalWeather->new();
|
||||
my $result = $weather->GetWeather({ CountryName => 'Germany', CityName => 'Munich' });
|
||||
|
||||
die $result->get_faultstring()->get_value() if not ($result); # boolean comparison overloaded
|
||||
|
||||
print $result->get_GetWeatherResult()->get_value() , "\n";
|
||||
25
example/weather_wsdl.pl
Normal file
25
example/weather_wsdl.pl
Normal file
@@ -0,0 +1,25 @@
|
||||
# Accessing the globalweather service at
|
||||
# www.webservicex.net/GlobalWeather/GlobalWeather.asmx
|
||||
#
|
||||
# Note that the GlobalWeather web service returns a (quoted) XML structure -
|
||||
# don't be surprised by the response's format.
|
||||
#
|
||||
# I have no connection to www.webservicex.net
|
||||
# Use this script at your own risk.
|
||||
#
|
||||
# This script demonstrates the use of SOAP::WSDL in SOAP::Lite style.
|
||||
|
||||
use lib 'lib/';
|
||||
use lib '../lib';
|
||||
use SOAP::WSDL;
|
||||
use File::Basename qw(dirname);
|
||||
use File::Spec;
|
||||
my $path = File::Spec->rel2abs( dirname __FILE__);
|
||||
|
||||
my $soap = SOAP::WSDL->new();
|
||||
my $som = $soap->wsdl("file:///$path/wsdl/globalweather.xml")
|
||||
->call('GetWeather', GetWeather => { CountryName => 'Germany', CityName => 'Munich' });
|
||||
|
||||
die $som->message() if $som->fault();
|
||||
|
||||
print $som->result();
|
||||
308
example/wsdl/FortuneCookie.xml
Normal file
308
example/wsdl/FortuneCookie.xml
Normal 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>
|
||||
153
example/wsdl/genericbarcode.xml
Normal file
153
example/wsdl/genericbarcode.xml
Normal 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>
|
||||
185
example/wsdl/globalweather.xml
Normal file
185
example/wsdl/globalweather.xml
Normal 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>
|
||||
727
lib/SOAP/WSDL.pm
727
lib/SOAP/WSDL.pm
@@ -1,181 +1,185 @@
|
||||
package SOAP::WSDL;
|
||||
use strict;
|
||||
use warnings;
|
||||
use vars qw/$AUTOLOAD/;
|
||||
use vars qw($AUTOLOAD);
|
||||
use Carp;
|
||||
use Scalar::Util qw(blessed);
|
||||
use SOAP::WSDL::Client;
|
||||
use SOAP::WSDL::Envelope;
|
||||
use SOAP::WSDL::SAX::WSDLHandler;
|
||||
use base qw(SOAP::Lite);
|
||||
use Data::Dumper;
|
||||
use Class::Std;
|
||||
use XML::LibXML;
|
||||
use LWP::UserAgent;
|
||||
|
||||
our $VERSION='2.00_05';
|
||||
|
||||
BEGIN {
|
||||
eval {
|
||||
use XML::LibXML;
|
||||
};
|
||||
if ($@) {
|
||||
use XML::SAX::ParserFactory;
|
||||
}
|
||||
}
|
||||
our $VERSION='2.00_10';
|
||||
|
||||
sub AUTOLOAD {
|
||||
my $method = substr($AUTOLOAD, rindex($AUTOLOAD, '::') + 2);
|
||||
die "$method not found";
|
||||
my %no_dispatch_of :ATTR(:name<no_dispatch>);
|
||||
my %wsdl_of :ATTR(:name<wsdl>);
|
||||
my %proxy_of :ATTR(:name<proxy>);
|
||||
my %readable_of :ATTR(:name<readable>);
|
||||
my %autotype_of :ATTR(:name<autotype>);
|
||||
my %outputxml_of :ATTR(:name<outputxml>);
|
||||
my %outputtree_of :ATTR(:name<outputtree>);
|
||||
my %outputhash_of :ATTR(:name<outputhash>);
|
||||
my %servicename_of :ATTR(:name<servicename>);
|
||||
my %portname_of :ATTR(:name<portname>);
|
||||
my %class_resolver_of :ATTR(:name<class_resolver>);
|
||||
|
||||
my %method_info_of :ATTR(:default<()>);
|
||||
my %port_of :ATTR(:default<()>);
|
||||
my %porttype_of :ATTR(:default<()>);
|
||||
my %binding_of :ATTR(:default<()>);
|
||||
my %service_of :ATTR(:default<()>);
|
||||
my %definitions_of :ATTR(:get<definitions> :default<()>);
|
||||
my %serialize_options_of :ATTR(:default<()>);
|
||||
my %explain_options_of :ATTR(:default<()>);
|
||||
|
||||
my %client_of :ATTR(:name<client> :default<()>);
|
||||
|
||||
my %LOOKUP = (
|
||||
no_dispatch => \%no_dispatch_of,
|
||||
class_resolver => \%class_resolver_of,
|
||||
wsdl => \%wsdl_of,
|
||||
proxy => \%proxy_of,
|
||||
readable => \%readable_of,
|
||||
autotype => \%autotype_of,
|
||||
outputxml => \%outputxml_of,
|
||||
outputtree => \%outputtree_of,
|
||||
outputhash => \%outputhash_of,
|
||||
portname => \%portname_of,
|
||||
servicename => \%servicename_of,
|
||||
);
|
||||
|
||||
for my $method (keys %LOOKUP ) {
|
||||
no strict qw(refs);
|
||||
*{ $method } = sub {
|
||||
my $self = shift;
|
||||
my $ident = ident $self;
|
||||
if (@_) {
|
||||
$LOOKUP{ $method }->{ $ident } = shift;
|
||||
return $self;
|
||||
}
|
||||
return $LOOKUP{ $method }->{ $ident };
|
||||
};
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
{
|
||||
# we need to roll our own for supporting
|
||||
# SOAP::WSDL->new( key => value ) syntax,
|
||||
# like SOAP::Lite does
|
||||
no warnings qw(redefine);
|
||||
sub new {
|
||||
my $class = shift;
|
||||
my %args_from = @_;
|
||||
my $self = \do { my $foo = undef };
|
||||
bless $self, $class;
|
||||
|
||||
for (keys %args_from) {
|
||||
my $method = $self->can("set_$_")
|
||||
or croak "unknown parameter $_ passed to new";
|
||||
$method->($self, $args_from{$_});
|
||||
}
|
||||
my $ident = ident $self;
|
||||
$self->wsdlinit() if ($wsdl_of{ $ident });
|
||||
|
||||
$client_of{ $ident } = SOAP::WSDL::Client->new();
|
||||
|
||||
return $self;
|
||||
}
|
||||
}
|
||||
|
||||
sub wsdlinit {
|
||||
my $self = shift;
|
||||
my $self = shift;
|
||||
my $ident = ident $self;
|
||||
my %opt = @_;
|
||||
|
||||
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 $lwp = LWP::UserAgent->new();
|
||||
my $response = $lwp->get( $wsdl_of{ $ident } );
|
||||
croak $response->message() if ($response->code != 200);
|
||||
|
||||
# TODO: Port parser to expat and remove XML::LibXML dependency
|
||||
my $parser = XML::LibXML->new();
|
||||
my $filter = SOAP::WSDL::SAX::WSDLHandler->new();
|
||||
$parser->set_handler( $filter );
|
||||
$parser->parse_string( $response->content() );
|
||||
|
||||
# sanity checks
|
||||
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 } = {
|
||||
$definitions_of{ $ident } = $wsdl_definitions;
|
||||
$serialize_options_of{ $ident } = {
|
||||
autotype => 0,
|
||||
readable => $self->readable(),
|
||||
typelib => $types,
|
||||
namespace => $ns,
|
||||
};
|
||||
$self->{ _WSDL }->{ explain_options } = {
|
||||
$explain_options_of{ $ident } = {
|
||||
readable => $self->readable(),
|
||||
wsdl => $wsdl_definitions,
|
||||
namespace => $ns,
|
||||
typelib => $types,
|
||||
};
|
||||
|
||||
$self->servicename($opt{servicename}) if $opt{servicename};
|
||||
$self->portname($opt{portname}) if $opt{portname};
|
||||
$servicename_of{ $ident } = $opt{servicename} if $opt{servicename};
|
||||
$portname_of{ $ident } = $opt{portname} if $opt{portname};
|
||||
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;
|
||||
sub _wsdl_get_service :PRIVATE {
|
||||
my $ident = ident shift;
|
||||
my $wsdl = $definitions_of{ $ident };
|
||||
return $service_of{ $ident } = $servicename_of{ $ident }
|
||||
? $wsdl->find_service( $wsdl->get_targetNamespace() , $servicename_of{ $ident } )
|
||||
: $service_of{ $ident } = $wsdl->get_service()->[ 0 ];
|
||||
} ## 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 };
|
||||
sub _wsdl_get_port :PRIVATE {
|
||||
my $ident = ident shift;
|
||||
my $wsdl = $definitions_of{ $ident };
|
||||
my $ns = $wsdl->get_targetNamespace();
|
||||
my $port = $self->{ _WSDL }->{ port }
|
||||
|| $self->_wsdl_get_port();
|
||||
return $port_of{ $ident } = $portname_of{ $ident }
|
||||
? $service_of{ $ident }->get_port( $ns, $portname_of{ $ident } )
|
||||
: $port_of{ $ident } = $service_of{ $ident }->get_port()->[ 0 ];
|
||||
}
|
||||
|
||||
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 )
|
||||
sub _wsdl_get_binding :PRIVATE {
|
||||
my $self = shift;
|
||||
my $ident = ident $self;
|
||||
my $wsdl = $definitions_of{ $ident };
|
||||
my $port = $port_of{ $ident } || $self->_wsdl_get_port();
|
||||
$binding_of{ $ident } = $wsdl->find_binding( $wsdl->_expand( $port->get_binding() ) )
|
||||
or die "no binding found for ", $port->get_binding();
|
||||
return $self->{ _WSDL }->{ binding } = $binding;
|
||||
} ## end sub _wsdl_get_binding
|
||||
return $binding_of{ $ident };
|
||||
}
|
||||
|
||||
sub _wsdl_get_portType {
|
||||
sub _wsdl_get_portType :PRIVATE {
|
||||
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
|
||||
my $ident = ident $self;
|
||||
my $wsdl = $definitions_of{ $ident };
|
||||
my $binding = $binding_of{ $ident } || $self->_wsdl_get_binding();
|
||||
$porttype_of{ $ident } = $wsdl->find_portType( $wsdl->_expand( $binding->get_type() ) )
|
||||
or die "cannot find portType for " . $binding->get_type();
|
||||
return $porttype_of{ $ident };
|
||||
}
|
||||
|
||||
|
||||
sub _wsdl_init_methods {
|
||||
my $self = shift;
|
||||
my $wsdl = $self->{ _WSDL }->{ wsdl_definitions };
|
||||
sub _wsdl_init_methods :PRIVATE {
|
||||
my $self = shift;
|
||||
my $ident = ident $self;
|
||||
my $wsdl = $definitions_of{ $ident };
|
||||
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()
|
||||
# get bindings, portType, message, part(s) - use private methods for clear separation...
|
||||
$self->_wsdl_get_service if not ($service_of{ $ident });
|
||||
my $binding = $binding_of{ $ident } || $self->_wsdl_get_binding()
|
||||
|| die "Can't find binding";
|
||||
my $portType = $self->{ _WSDL }->{ portType }
|
||||
|| $self->_wsdl_get_portType()
|
||||
|| die "Can't find portType";
|
||||
my $portType = $porttype_of{ $ident } || $self->_wsdl_get_portType();
|
||||
|
||||
my $methodHashRef = {};
|
||||
$method_info_of{ $ident } = {};
|
||||
|
||||
foreach my $binding_operation (@{ $binding->get_operation() })
|
||||
{
|
||||
@@ -211,201 +215,59 @@ sub _wsdl_init_methods {
|
||||
}
|
||||
: undef;
|
||||
|
||||
$methodHashRef->{ $binding_operation->get_name() } = $method;
|
||||
$method_info_of{ $ident }->{ $binding_operation->get_name() } = $method;
|
||||
}
|
||||
|
||||
$self->{ _WSDL }->{ methodInfo } = $methodHashRef;
|
||||
|
||||
return $methodHashRef;
|
||||
|
||||
return $method_info_of{ $ident };
|
||||
}
|
||||
|
||||
|
||||
sub call {
|
||||
my $self = shift;
|
||||
my $self = shift;
|
||||
my $ident = ident $self;
|
||||
my $method = shift;
|
||||
my $data = ref $_[0] ? $_[0] : { @_ };
|
||||
|
||||
my $content = q{};
|
||||
my $envelope;
|
||||
my $methodInfo;
|
||||
|
||||
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
|
||||
# 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 );
|
||||
};
|
||||
|
||||
|
||||
if ( $self->no_dispatch() ) {
|
||||
return $envelope;
|
||||
} ## end if ( $self->no_dispatch...
|
||||
|
||||
# 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:
|
||||
# - result: returns the result of the call (like SOAP::Lite, but as
|
||||
# perl data structure)
|
||||
# - header: returns the content of the SOAP header
|
||||
# - 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(
|
||||
context => $self, # this is provided for context
|
||||
endpoint => $self->endpoint(),
|
||||
action => $methodInfo->{ soap_action }, # SOAPAction from binding
|
||||
envelope => $envelope, # use custom content
|
||||
);
|
||||
|
||||
return $response if ($self->outputxml() );
|
||||
|
||||
if ($self->outputtree()) {
|
||||
|
||||
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()
|
||||
});
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
# 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
|
||||
);
|
||||
} ## end if ( !$self->transport...
|
||||
|
||||
return unless $response; # nothing to do for one-ways
|
||||
return $result;
|
||||
} ## end sub call
|
||||
|
||||
$self->wsdlinit() if not ($definitions_of{ $ident });
|
||||
$self->_wsdl_init_methods() if not ($method_info_of{ $ident });
|
||||
|
||||
my $client = $client_of{ $ident };
|
||||
$client->set_proxy( $proxy_of{ $ident } || $port_of{ $ident }->get_location() );
|
||||
$client->set_no_dispatch( $no_dispatch_of{ $ident } );
|
||||
$client->set_outputxml( $outputtree_of{ $ident } ? 0 : 1 );
|
||||
|
||||
my $response = (blessed $data)
|
||||
? $client->call( $method, $data )
|
||||
: do {
|
||||
my $content = '';
|
||||
# TODO support RPC-encoding: Top-Level element + namespace...
|
||||
foreach my $part ( @{ $method_info_of{ $ident }->{ $method }->{ parts } } ) {
|
||||
$client->set_on_action( sub { $part->get_targetNamespace() . '/' . $_[1] } );
|
||||
$content .= $part->serialize( $method, $data,
|
||||
{
|
||||
%{ $serialize_options_of{ $ident } },
|
||||
readable => $readable_of{ $ident },
|
||||
} );
|
||||
}
|
||||
$client->call($method, $content);
|
||||
};
|
||||
|
||||
return $response if (
|
||||
$outputxml_of{ $ident }
|
||||
# || $outputhash_of{ $ident }
|
||||
|| $outputtree_of{ $ident }
|
||||
|| $no_dispatch_of{ $ident } );
|
||||
|
||||
return unless $response; # nothing to do for one-ways
|
||||
# now convert into SOAP::SOM - bah !
|
||||
require SOAP::Lite;
|
||||
return SOAP::Deserializer->new()->deserialize( $response );
|
||||
}
|
||||
|
||||
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 };
|
||||
return $self;
|
||||
} ## end sub servicename
|
||||
|
||||
sub portname {
|
||||
my $self = shift;
|
||||
return $self->{ _WSDL }->{ portname } if ( not @_ );
|
||||
$self->{ _WSDL }->{ portname } = shift;
|
||||
|
||||
my $ns = $self->{ _WSDL }->{ wsdl_definitions }->get_targetNamespace();
|
||||
|
||||
$self->{ _WSDL }->{ port } =
|
||||
$self->{ _WSDL }->{ service }
|
||||
->find_port( $ns, $self->{ _WSDL }->{ portname } )
|
||||
or die "No such port: " . $self->{ _WSDL }->{ portname };
|
||||
return $self;
|
||||
} ## end sub portname
|
||||
my $ident = ident shift;
|
||||
my $opt = $explain_options_of{ $ident };
|
||||
return $definitions_of{ $ident }->explain( $opt );
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
@@ -416,32 +278,53 @@ __END__
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL - SOAP with WSDL support
|
||||
|
||||
=head1 Overview
|
||||
|
||||
For creating Perl classes instrumenting a web service with a WSDL definition,
|
||||
read L<SOAP::WSDL::Manual>.
|
||||
|
||||
For using an interpreting (thus slow and somewhat troublesome) WSDL based
|
||||
SOAP client, which mimics L<SOAP::Lite|SOAP::Lite>'s API, read on.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
my $soap = SOAP::WSDL->new(
|
||||
wsdl => 'file://bla.wsdl',
|
||||
readable => 1,
|
||||
)->wsdlinit();
|
||||
);
|
||||
|
||||
my $result = $soap->call('MyMethod', %data);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
SOAP::WSDL provides easy access to Web Services with WSDL descriptions.
|
||||
|
||||
SOAP::WSDL provides easy access to Web Services with WSDL descriptions.
|
||||
|
||||
The WSDL is parsed and stored in memory.
|
||||
|
||||
Your data is serialized according to the rules in the WSDL and sent via
|
||||
SOAP::Lite's transport mechanism.
|
||||
Your data is serialized according to the rules in the WSDL.
|
||||
|
||||
The only transport mechanisms currently supported are http and https.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=head2 new
|
||||
|
||||
Constructor. All parameters passed are passed to the corresponding methods.
|
||||
|
||||
=head2 call
|
||||
|
||||
Performs a SOAP call. The result is either an object tree (with outputtree),
|
||||
a hash reference (with outputhash), plain XML (with outputxml) or a SOAP::SOM
|
||||
object (with neither of the above set).
|
||||
|
||||
my $result = $soap->call('method', %data);
|
||||
|
||||
=head2 wsdlinit
|
||||
|
||||
Reads the WSDL file and initializes SOAP::WSDL for working with it.
|
||||
|
||||
Must be called after the wsdl URL has been set, and before calling one of
|
||||
Is called automatically from call() if not called directly before.
|
||||
|
||||
servicename
|
||||
portname
|
||||
@@ -455,14 +338,6 @@ wsdlinit:
|
||||
portname => 'MyPort'
|
||||
);
|
||||
|
||||
=head2 call
|
||||
|
||||
Performs a SOAP call. The result is either an object tree (with outputtree),
|
||||
a hash reference (with outputhash), plain XML (with outputxml) or a SOAP::SOM
|
||||
object (with neither of the above set).
|
||||
|
||||
my $result = $soap->call('method', %data);
|
||||
|
||||
=head1 CONFIGURATION METHODS
|
||||
|
||||
=head2 outputtree
|
||||
@@ -515,8 +390,6 @@ SOAP::WSDL::XSD::ComplexType on how to build / generate one.
|
||||
Sets the service to operate on. If no service is set via servicename, the
|
||||
first service found is used.
|
||||
|
||||
Must be called after calling wsdlinit().
|
||||
|
||||
Returns the soap object, so you can chain calls like
|
||||
|
||||
$soap->servicename->('Name')->portname('Port');
|
||||
@@ -528,8 +401,6 @@ Returns the soap object, so you can chain calls like
|
||||
Sets the port to operate on. If no port is set via portname, the
|
||||
first port found is used.
|
||||
|
||||
Must be called after calling wsdlinit().
|
||||
|
||||
Returns the soap object, so you can chain calls like
|
||||
|
||||
$soap->portname('Port')->call('MyMethod', %data);
|
||||
@@ -539,12 +410,25 @@ Returns the soap object, so you can chain calls like
|
||||
When set, call() returns the plain request XML instead of dispatching the
|
||||
SOAP call to the SOAP service. Handy for testing/debugging.
|
||||
|
||||
=head2 _wsdl_init_methods
|
||||
|
||||
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>.
|
||||
=head1 ACCESS TO SOAP::WSDL's internals
|
||||
|
||||
=head2 get_client / set_client
|
||||
|
||||
Returns the SOAP client implementation used (normally a SOAP::WSDL::Client
|
||||
object).
|
||||
|
||||
Useful for enabling tracing:
|
||||
|
||||
# enable tracing via 'warn'
|
||||
$soap->get_client->set_trace(1);
|
||||
|
||||
# enable tracing via a custom facility -
|
||||
# Log::Log4perl in this case...
|
||||
$soap->get_client->set_trace(sub { Log::Log4perl->get_logger->info(@_) } );
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
See the examples/ directory.
|
||||
|
||||
=head1 Differences to previous versions
|
||||
|
||||
@@ -560,7 +444,8 @@ it's content.
|
||||
The object tree has two main functions: It knows how to serialize data passed
|
||||
as hash ref, and how to render the WSDL elements found into perl classes.
|
||||
|
||||
Yup your're right, there's a builting code generation facility.
|
||||
Yup your're right, there's a builting code generation facility. Read
|
||||
L<SOAP::WSDL::Manual> for using it.
|
||||
|
||||
=item * no_dispatch
|
||||
|
||||
@@ -581,33 +466,92 @@ You may pass the servicename and portname as attributes to wsdlinit, though.
|
||||
=back
|
||||
|
||||
=head1 Differences to SOAP::Lite
|
||||
|
||||
=head2 Message style/encoding
|
||||
|
||||
While SOAP::Lite supports rpc/encoded style/encoding only, SOAP::WSDL currently
|
||||
supports document/literal style/encoding.
|
||||
|
||||
=head2 autotype / type information
|
||||
|
||||
SOAP::Lite defaults to transmitting XML type information by default, where
|
||||
SOAP::WSDL defaults to leaving it out.
|
||||
|
||||
autotype(1) might even be broken in SOAP::WSDL - it's not well-tested, yet.
|
||||
|
||||
=head2 Output formats
|
||||
|
||||
In contrast to SOAP::Lite, SOAP::WSDL supports the following output formats:
|
||||
|
||||
=over
|
||||
|
||||
=item * SOAP::SOM objects.
|
||||
|
||||
This is the default. SOAP::Lite is required for outputting SOAP::SOM objects.
|
||||
|
||||
=item * Object trees.
|
||||
|
||||
This is the recommended output format.
|
||||
You need a class resolver (typemap) for outputting object trees.
|
||||
See L<class_resolver|class_resolver> above.
|
||||
|
||||
=item * Hash refs
|
||||
|
||||
This is for convnience: A single hash ref containing the content of the
|
||||
SOAP body.
|
||||
|
||||
=item * xml
|
||||
|
||||
See below.
|
||||
|
||||
=back
|
||||
|
||||
=head2 outputxml
|
||||
|
||||
=head2 Auto-Dispatching
|
||||
SOAP::Lite returns only the content of the SOAP body when outputxml is set
|
||||
to true. SOAP::WSDL returns the complete XML response.
|
||||
|
||||
=head3 Auto-Dispatching
|
||||
|
||||
SOAP::WSDL does B<does not> support auto-dispatching.
|
||||
|
||||
This is on purpose: You may easily create interface classes by using
|
||||
SOAP::WSDL and implementing something like
|
||||
SOAP::WSDL::Client and implementing something like
|
||||
|
||||
sub mySoapMethod {
|
||||
my $self = shift;
|
||||
$soap_wsdl_client->call( mySoapMethod, @_);
|
||||
}
|
||||
|
||||
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.
|
||||
You may even do this in a class factory - see L<wsdl2perl.pl> for creating
|
||||
such interfaces.
|
||||
|
||||
=head3 Debugging / Tracing
|
||||
|
||||
While SOAP::Lite features a global tracing facility, SOAP::WSDL
|
||||
allows to switch tracing on/of on a per-object base.
|
||||
|
||||
This has to be done in the SOAP client used by SOAP::WSDL - see
|
||||
L<get_client|get_client> for an example and L<SOAP::WSDL::Client> for
|
||||
details.
|
||||
|
||||
=head1 Bugs and Limitations
|
||||
|
||||
=over
|
||||
|
||||
=item * readable
|
||||
|
||||
readable() must be called before calling wsdlinit. This is a bug.
|
||||
|
||||
=item * SOAP Headers are not supported
|
||||
|
||||
There's no way to use SOAP Headers with SOAP::WSDL yet.
|
||||
|
||||
=item * Apache SOAP datatypes are not supported
|
||||
|
||||
You currently can't use SOAP::WSDL with Apache SOAP datatypes like map.
|
||||
|
||||
If you want this changed, email me a copy of the specs, please.
|
||||
|
||||
=item * outputhash
|
||||
|
||||
outputhash is not implemented yet.
|
||||
|
||||
=item * Unsupported XML Schema definitions
|
||||
|
||||
@@ -619,7 +563,7 @@ The following XML Schema definitions are not supported:
|
||||
simpleContent
|
||||
complexContent
|
||||
|
||||
=item * Serialization of hash refs dos not work for ambiguous values
|
||||
=item * Serialization of hash refs dos not work for ambiguos values
|
||||
|
||||
If you have list elements with multiple occurences allowed, SOAP::WSDL
|
||||
has no means of finding out which variant you meant.
|
||||
@@ -629,11 +573,11 @@ Passing in item => [1,2,3] could serialize to
|
||||
<item>1 2</item><item>3</item>
|
||||
<item>1</item><item>2 3</item>
|
||||
|
||||
Ambiguos data can be avoided by passing an object tree as data.
|
||||
Ambiguos data can be avoided by providing data as objects.
|
||||
|
||||
=item * XML Schema facets
|
||||
|
||||
Almost all XML schema facets are not yet implemented. The only facets
|
||||
Almost no XML schema facets are implemented yet. The only facets
|
||||
currently implemented are:
|
||||
|
||||
fixed
|
||||
@@ -651,7 +595,59 @@ The following facets have no influence yet:
|
||||
enumeration
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
There are lots of SOAP Clients on CPAN, lately.
|
||||
|
||||
You may wish to look at the following:
|
||||
|
||||
=over
|
||||
|
||||
=item * L<SOAP::Lite|SOAP::Lite>
|
||||
|
||||
Full featured SOAP-library, little WSDL support. Supports rpc-encoded style only. Many protocols supported.
|
||||
|
||||
=item * L<SOAP::Message|SOAP::Message>
|
||||
|
||||
A very basic SOAP library without transport facilities.
|
||||
|
||||
Handy if you got your XML message ready and just need an envelope around it.
|
||||
|
||||
=item * L<SOAP::MySOAP|SOAP::MySOAP>
|
||||
|
||||
An extremely basic SOAP client module - just HTTP support, no encoding / decoding,
|
||||
HTTP headers have to be set as arguments to 'new'
|
||||
|
||||
=item * <XML::Compile::WSDL|XML::Compile::WSDL>
|
||||
|
||||
A promising-looking approach derived from a cool functional DOM-based XML schema parser.
|
||||
|
||||
Will support encoding/decoding of SOAP messages based on WSDL definitions.
|
||||
|
||||
Not yet finished at the time of writing - but you may wish to give it a try, especially
|
||||
if you need to adhere very closely to the XML Schema / WSDL specs.
|
||||
|
||||
=back
|
||||
|
||||
=head1 ACKNOWLEDGMENTS
|
||||
|
||||
There are many people out there who fostered SOAP::WSDL's developement.
|
||||
I would like to thank them all (and apologize to all those I have forgotten).
|
||||
|
||||
Giovanni S. Fois wrote a improved version of SOAP::WSDL (which eventually became v1.23)
|
||||
|
||||
Damian A. Martinez Gelabert, Dennis S. Hennen, Dan Horne, Peter Orvos, Mark Overmeer,
|
||||
Jon Robens, Isidro Vila Verde and Glenn Wood spotted bugs and/or
|
||||
suggested improvements in the 1.2x releases.
|
||||
|
||||
Andreas 'ACID' Specht constantly asked for better performance.
|
||||
|
||||
Numerous people sent me their real-world WSDL files for testing. Thank you.
|
||||
|
||||
Paul Kulchenko and Byrne Reese wrote and maintained SOAP::Lite and thus provided a
|
||||
base (and counterpart) for SOAP::WSDL.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
Copyright 2004-2007 Martin Kutter.
|
||||
@@ -663,5 +659,12 @@ the same terms as perl itself
|
||||
|
||||
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
|
||||
|
||||
=head1 REPOSITORY INFORMATION
|
||||
|
||||
$Rev: 143 $
|
||||
$LastChangedBy: kutterma $
|
||||
$Id: WSDL.pm 143 2007-08-13 18:43:20Z kutterma $
|
||||
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL.pm $
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
@@ -3,11 +3,20 @@ 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 %name_of :ATTR(:name<name> :default<()>);
|
||||
my %documentation_of :ATTR(:name<documentation> :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 +29,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 +55,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 +73,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;
|
||||
|
||||
@@ -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,70 +59,55 @@ EOT
|
||||
my $input = $port_operation->first_fault();
|
||||
$input ? $input->explain($opt) : q{};
|
||||
};
|
||||
|
||||
|
||||
$txt .= <<"EOT";
|
||||
|
||||
=over
|
||||
|
||||
=item * $operation_name
|
||||
=head3 $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;
|
||||
}
|
||||
|
||||
@@ -2,26 +2,45 @@ package SOAP::WSDL::Client;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Carp;
|
||||
use Scalar::Util qw(blessed);
|
||||
use SOAP::WSDL::Envelope;
|
||||
use SOAP::Lite;
|
||||
|
||||
use Class::Std::Storable;
|
||||
use SOAP::WSDL::SAX::MessageHandler;
|
||||
use LWP::UserAgent;
|
||||
use HTTP::Request;
|
||||
use Scalar::Util qw(blessed);
|
||||
|
||||
use SOAP::WSDL::Envelope;
|
||||
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<()>);
|
||||
my %no_dispatch_of :ATTR(:name<no_dispatch> :default<()>);
|
||||
my %outputxml_of :ATTR(:name<outputxml> :default<()>);
|
||||
my %proxy_of :ATTR(:name<proxy> :default<()>);
|
||||
|
||||
my %fault_class_of :ATTR(:name<fault_class> :default<SOAP::WSDL::SOAP::Typelib::Fault11>);
|
||||
my %trace_of :ATTR(:set<trace> :init_arg<trace> :default<()> );
|
||||
my %on_action_of :ATTR(:name<on_action> :default<()>);
|
||||
my %content_type_of :ATTR(:name<content_type> :default<text/xml; charset=utf8>);
|
||||
|
||||
#/#trick editors
|
||||
|
||||
# TODO remove when preparing 2.01
|
||||
sub outputtree { warn 'outputtree is deprecated and'
|
||||
. 'will be removed before reaching v2.01 !' }
|
||||
|
||||
|
||||
sub get_trace {
|
||||
my $ident = ident $_[0];
|
||||
return $trace_of{ $ident }
|
||||
? ref $trace_of{ $ident } eq 'CODE'
|
||||
? $trace_of{ $ident }
|
||||
: sub { warn @_ }
|
||||
: ()
|
||||
}
|
||||
|
||||
# Mimic SOAP::Lite's behaviour for getter/setter routines
|
||||
SUBFACTORY: {
|
||||
no strict qw(refs);
|
||||
for (qw(class_resolver no_dispatch outputxml proxy)) {
|
||||
@@ -38,101 +57,89 @@ SUBFACTORY: {
|
||||
}
|
||||
|
||||
BEGIN {
|
||||
eval {
|
||||
require XML::LibXML;
|
||||
$PARSER = XML::LibXML->new();
|
||||
$MESSAGE_HANDLER = SOAP::WSDL::SAX::MessageHandler->new();
|
||||
$PARSER->set_handler( $MESSAGE_HANDLER );
|
||||
};
|
||||
if ($@) {
|
||||
require XML::SAX::ParserFactory;
|
||||
$MESSAGE_HANDLER = SOAP::WSDL::SAX::MessageHandler->new({
|
||||
base => 'XML::SAX::Base' });
|
||||
$PARSER = XML::SAX::ParserFactory->parser(
|
||||
handler => $MESSAGE_HANDLER );
|
||||
}
|
||||
$PARSER = SOAP::WSDL::Expat::MessageParser->new();
|
||||
}
|
||||
|
||||
sub call {
|
||||
my $self = shift;
|
||||
my $method = shift;
|
||||
my $data = ref $_[0] ? $_[0] : { @_ };
|
||||
my $content = q{};
|
||||
my ($envelope, $soap_action);
|
||||
my $self = shift;
|
||||
my $method = shift;
|
||||
my $ident = ident $self;
|
||||
my $data = ref $_[0]
|
||||
? $_[0]
|
||||
: (@_>1)
|
||||
? { @_ }
|
||||
: $_[0];
|
||||
|
||||
my $soap_action;
|
||||
my $trace_sub = $self->get_trace();
|
||||
my $envelope = SOAP::WSDL::Envelope->serialize( $method, $data );
|
||||
|
||||
if (blessed $data
|
||||
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
|
||||
# workaround...
|
||||
$soap_action = join '/', $data->get_xmlns(), $method;
|
||||
}
|
||||
else {
|
||||
$envelope = SOAP::WSDL::Envelope->serialize( $method, $data );
|
||||
# TODO add something like SOAP::Lite's on_action mechanism
|
||||
$soap_action = $on_action_of{$ident}->( $self, $method ) if ($on_action_of{$ident});
|
||||
}
|
||||
|
||||
}
|
||||
return $envelope 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
|
||||
# SAX-based filter using XML::LibXML to get the
|
||||
# result.
|
||||
# Filter should have the following methods:
|
||||
# get response via transport layer
|
||||
# maybe we should return a result with the following methods:
|
||||
# - result: returns the result of the call (like SOAP::Lite, but as
|
||||
# perl data structure)
|
||||
# object tree)
|
||||
# - header: returns the content of the SOAP header
|
||||
# - 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 $soap = SOAP::Lite->new()->proxy( $self->get_proxy() );
|
||||
my $response = $soap->transport->send_receive(
|
||||
context => $self, # this is provided for context
|
||||
endpoint => $soap->endpoint(),
|
||||
action => $soap_action, # SOAPAction, should be from binding
|
||||
envelope => $envelope, # use custom content
|
||||
);
|
||||
my $ua = LWP::UserAgent->new();
|
||||
my $request = HTTP::Request->new( 'POST',
|
||||
$self->get_proxy(),
|
||||
[ 'Content-Type', $content_type_of{ $ident },
|
||||
'Content-Length', length($envelope),
|
||||
'SOAPAction', $soap_action,
|
||||
],
|
||||
$envelope );
|
||||
|
||||
|
||||
$trace_sub->( $request->as_string() ) if $trace_of{ $ident }; # if for speed
|
||||
my $response = $ua->request( $request );
|
||||
$trace_sub->( $response->as_string() ) if $trace_of{ $ident }; # if for speed
|
||||
|
||||
return $response->content() if ($self->outputxml() );
|
||||
|
||||
# warn 'Received ' . length($response) . ' bytes of content';
|
||||
|
||||
return $response if ($self->outputxml() );
|
||||
|
||||
$MESSAGE_HANDLER->set_class_resolver( $self->get_class_resolver() );
|
||||
$PARSER->class_resolver( $self->get_class_resolver() );
|
||||
|
||||
# if we had no success (Transport layer error status code)
|
||||
# or if transport layer failed
|
||||
if (! $soap->transport->is_success() ) {
|
||||
|
||||
# TODO Fix deserializing message - there's something wrong with Fault11
|
||||
# or if transport layer failed
|
||||
if ($response->code() != 200) {
|
||||
# Try deserializing response - there may be some
|
||||
if ($response) {
|
||||
|
||||
eval { $PARSER->parse_string( $response ); };
|
||||
if ($@) {
|
||||
warn "could not deserialize response: $@";
|
||||
}
|
||||
else {
|
||||
return $MESSAGE_HANDLER->get_data();
|
||||
}
|
||||
if ($response->content) {
|
||||
eval { $PARSER->parse( $response->content() ); };
|
||||
return $PARSER->get_data() if (not $@);
|
||||
warn "could not deserialize response: $@";
|
||||
};
|
||||
|
||||
|
||||
require SOAP::WSDL::SOAP::Typelib::Fault11;
|
||||
# generate & return fault if we cannot serialize response
|
||||
# or have none...
|
||||
return SOAP::WSDL::SOAP::Typelib::Fault11->new({
|
||||
return $fault_class_of{$ident}->new({
|
||||
faultcode => 'soap:Server',
|
||||
faultactor => 'urn:localhost',
|
||||
faultstring => 'Error sending / receiving message: '
|
||||
. $soap->transport->message()
|
||||
. $response->message()
|
||||
#$soap->transport->message()
|
||||
});
|
||||
}
|
||||
eval { $PARSER->parse_string( $response ) };
|
||||
eval { $PARSER->parse( $response->content() ) };
|
||||
|
||||
# return fault if we cannot deserialize response
|
||||
if ($@) {
|
||||
return SOAP::WSDL::SOAP::Typelib::Fault11->new({
|
||||
return $fault_class_of{$ident}->new({
|
||||
faultcode => 'soap:Server',
|
||||
faultactor => 'urn:localhost',
|
||||
faultstring => "Error deserializing message: $@. \n"
|
||||
@@ -140,12 +147,58 @@ sub call {
|
||||
});
|
||||
}
|
||||
|
||||
return $MESSAGE_HANDLER->get_data();
|
||||
return $PARSER->get_data();
|
||||
} ## end sub call
|
||||
|
||||
1;
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::Client - SOAP::WSDL's SOAP Client
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=head2 call
|
||||
|
||||
=head2 Configuration methods
|
||||
|
||||
=head3 outputxml
|
||||
|
||||
$soap->outputxml(1);
|
||||
|
||||
When set, call() returns the raw XML of the SOAP Envelope.
|
||||
|
||||
=head3 set_content_type
|
||||
|
||||
$soap->set_content_type('application/xml; charset: utf8');
|
||||
|
||||
Sets the content type and character encoding.
|
||||
|
||||
You probably should not use a character encoding different from utf8:
|
||||
SOAP::WSDL::Client will not convert the request into a different encoding
|
||||
(yet).
|
||||
|
||||
To leave out the encoding, just set the content type without appendet charset
|
||||
like in
|
||||
|
||||
text/xml
|
||||
|
||||
Default:
|
||||
|
||||
text/xml; charset: utf8
|
||||
|
||||
=head3 set_trace
|
||||
|
||||
$soap->set_trace(1);
|
||||
$soap->set_trace( sub { Log::Log4perl::get_logger()->debug( @_ ) } );
|
||||
|
||||
When set to a true value, tracing (via warn) is enabled.
|
||||
|
||||
When set to a code reference, this function will be called on every
|
||||
trace call, making it really easy for you to set up log4perl logging
|
||||
or whatever you need.
|
||||
|
||||
=head2 Features different from SOAP::Lite
|
||||
|
||||
@@ -158,7 +211,7 @@ 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:
|
||||
A few things are quite different from SOAP::Lite, though:
|
||||
|
||||
=head3 SOAP request data
|
||||
|
||||
@@ -210,9 +263,33 @@ 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
|
||||
for generating such interfaces.
|
||||
You may even do this in a class factory - see L<wsdl2perl.pl> for creating
|
||||
such interfaces.
|
||||
|
||||
=head3 Debugging / Tracing
|
||||
|
||||
While SOAP::Lite features a global tracing facility, SOAP::WSDL::Client
|
||||
allows to switch tracing on/of on a per-object base.
|
||||
|
||||
See L<set_trace|set_trace> on how to enable tracing.
|
||||
|
||||
=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>
|
||||
|
||||
=head1 REPOSITORY INFORMATION
|
||||
|
||||
$Rev: 139 $
|
||||
$LastChangedBy: kutterma $
|
||||
$Id: Client.pm 139 2007-08-12 19:15:59Z kutterma $
|
||||
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Client.pm $
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
|
||||
@@ -1,31 +1,47 @@
|
||||
#!/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 } };
|
||||
|
||||
return $self->SUPER::call( $method, @param );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$SOAP::WSDL::Client::Base::VERSION = sprintf("0.%d", q$LastChangedRevision: 1$ =~/(\d+)/ );
|
||||
1;
|
||||
|
||||
__PACKAGE__->mk_accessors(
|
||||
qw//
|
||||
);
|
||||
|
||||
my $log = undef; # Global logger to speed up performance
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
@@ -35,93 +51,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
|
||||
@@ -1,6 +1,11 @@
|
||||
package SOAP::WSDL::Definitions;
|
||||
use utf8;
|
||||
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 +14,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,34 +27,41 @@ 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;
|
||||
}
|
||||
my $self = shift;
|
||||
my $opt = shift;
|
||||
$opt->{ wsdl } ||= $self;
|
||||
$opt->{ namespace } ||= $self->get_xmlns() || {};
|
||||
my $txt = '';
|
||||
|
||||
sub to_typemap {
|
||||
for my $service (@{ $self->get_service() }) {
|
||||
$txt .= $service->explain( $opt ) . "\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{};
|
||||
@@ -60,6 +71,235 @@ sub to_typemap {
|
||||
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();
|
||||
$service_name =~s{\.}{\:\:}xmsg;
|
||||
# TODO: iterate over ports.
|
||||
# - ignore non-SOAP ports
|
||||
# - generate interface for all SOAP ports...
|
||||
my $binding = $self->find_binding( $self->_expand( $opt->{ service }->first_port()->get_binding() ) );
|
||||
my $porttype = $self->find_portType( $self->_expand( $binding->get_type() ) );
|
||||
|
||||
my $port_operation_ref = $porttype->get_operation();
|
||||
my $operation_ref = $binding->get_operation();
|
||||
|
||||
# make up operations map - name => [ part types / elements class names ]
|
||||
#
|
||||
my %operations = ();
|
||||
for my $operation ( @{ $operation_ref } ) {
|
||||
my $operation_name = $operation->get_name();
|
||||
my $port_op = first { $_->get_name() eq $operation_name } @{ $port_operation_ref };
|
||||
|
||||
$operations{ $operation_name }->{ documentation } = $port_op->get_documentation();
|
||||
|
||||
my %msg_from = (
|
||||
'input' => ($port_op->first_input() ) ? $port_op->first_input()->get_message() : undef,
|
||||
'output' => ($port_op->first_output()) ? $port_op->first_output()->get_message(): undef,
|
||||
'fault' => ($port_op->first_fault()) ? $port_op->first_fault()->get_message() : undef,
|
||||
);
|
||||
|
||||
for my $msg (keys %msg_from) {
|
||||
next if not $msg_from{ $msg };
|
||||
for my $part (@{ $self->find_message( $self->_expand( $msg_from{$msg} ) )->get_part }) {
|
||||
my $name;
|
||||
if (my $element_name = $part->get_element() ) {
|
||||
$name = $element_name;
|
||||
push @{ $operations{ $operation_name }->{$msg}->{ types } },
|
||||
$self->first_types()->find_element( $self->_expand( $element_name ) )
|
||||
->explain({ wsdl => $self , anonymous => 1 });
|
||||
|
||||
}
|
||||
elsif (my $type_name = $part->get_element() ) {
|
||||
push @{ $operations{ $operation_name }->{$msg}->{ types } },
|
||||
$self->first_types()->find_type( $self->_expand( $element_name ) )
|
||||
->explain({ wsdl => $self });
|
||||
$name = $type_name;
|
||||
}
|
||||
my ($prefix, $localname) = split m{:}xms , $name;
|
||||
push @{ $operations{ $operation_name }->{$msg}->{ class } },
|
||||
"$opt->{ element_prefix }$localname";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# use Data::Dumper;
|
||||
# die Dumper \%operations;
|
||||
|
||||
my $template = <<'EOT';
|
||||
package [% interface_prefix %][% service.get_name.replace('\.', '::') %];
|
||||
|
||||
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.replace('\.', '::') %]',
|
||||
proxy => '[% service.first_port.get_location %]',
|
||||
%{ $arg_ref }
|
||||
});
|
||||
return bless $self, $class;
|
||||
}
|
||||
|
||||
__PACKAGE__->__create_methods(
|
||||
[% FOREACH name = operations.keys -%]
|
||||
[% name %] => [ [% FOREACH class = operations.$name.input.class %]'[% class %]', [% END %]],
|
||||
[% END %]
|
||||
);
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
[% MACRO pod BLOCK %]=pod[% END %]
|
||||
[% MACRO cut BLOCK %]=pod[% END %]
|
||||
[% MACRO head1 BLOCK %]=head1[% END %]
|
||||
[% MACRO head2 BLOCK %]=head2[% 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 %]();
|
||||
|
||||
|
||||
[% head1 %] METHODS
|
||||
[% FOREACH name=operations.keys;
|
||||
operation=operations.$name;
|
||||
%]
|
||||
[% head2 %] [% name %]
|
||||
|
||||
[% operation.documentation %]
|
||||
|
||||
SYNOPSIS:
|
||||
|
||||
$service->[% name %]({
|
||||
[% FOREACH type = operation.input.types; type; END %] });
|
||||
|
||||
[% END %]
|
||||
|
||||
[% cut %]
|
||||
|
||||
EOT
|
||||
|
||||
require Template;
|
||||
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 $tt = Template->new(
|
||||
OUTPUT_PATH => $path,
|
||||
);
|
||||
$tt->process(\$template,
|
||||
{ %{ $opt }, operations => \%operations, binding => $binding, wsdl => $self },
|
||||
$name,
|
||||
binmode => ':utf8'
|
||||
)
|
||||
or die $tt->error();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub _create_typemap {
|
||||
my $self = shift;
|
||||
my $opt = shift;
|
||||
my $service_name = $opt->{ service }->get_name();
|
||||
$service_name =~s{\.}{\:\:}xmsg;
|
||||
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.replace('\.', '::') %];
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my %typemap = (
|
||||
# SOAP 1.1 fault typemap
|
||||
'Fault' => 'SOAP::WSDL::SOAP::Typelib::Fault11',
|
||||
'Fault/faultcode' => 'SOAP::WSDL::XSD::Typelib::Builtin::anyURI',
|
||||
'Fault/faultactor' => 'SOAP::WSDL::XSD::Typelib::Builtin::TOKEN',
|
||||
'Fault/faultstring' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
||||
'Fault/detail' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
||||
|
||||
# generated 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,
|
||||
binmode => ':utf8',
|
||||
)
|
||||
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;
|
||||
|
||||
@@ -166,6 +406,97 @@ Try something like this for creating typemap classes:
|
||||
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
|
||||
|
||||
|
||||
210
lib/SOAP/WSDL/Expat/MessageParser.pm
Normal file
210
lib/SOAP/WSDL/Expat/MessageParser.pm
Normal file
@@ -0,0 +1,210 @@
|
||||
#!/usr/bin/perl
|
||||
package SOAP::WSDL::Expat::MessageParser;
|
||||
use strict;
|
||||
use warnings;
|
||||
use SOAP::WSDL::XSD::Typelib::Builtin;
|
||||
use XML::Parser::Expat;
|
||||
|
||||
sub new {
|
||||
my ($class, $args) = @_;
|
||||
my $self = {
|
||||
class_resolver => $args->{ class_resolver }
|
||||
};
|
||||
bless $self, $class;
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub class_resolver {
|
||||
my $self = shift;
|
||||
$self->{ class_resolver } = shift;
|
||||
}
|
||||
|
||||
sub _initialize {
|
||||
my ($self, $parser) = @_;
|
||||
|
||||
delete $self->{ data };
|
||||
|
||||
my $characters;
|
||||
my $current = undef;
|
||||
my $ignore = [ 'Envelope', 'Body' ]; # top level elements to ignore
|
||||
my $list = []; # node list
|
||||
my $path = []; # current path (without
|
||||
# number)
|
||||
my $skip = 0; # skip elements
|
||||
|
||||
# use "globals" for speed
|
||||
my ($_prefix, $_localname, $_element, $_method,
|
||||
$_class, $_parser, %_attrs) = ();
|
||||
|
||||
no strict qw(refs);
|
||||
$parser->setHandlers(
|
||||
Start => sub {
|
||||
($_parser, $_element, %_attrs) = @_;
|
||||
($_prefix, $_localname) = split m{:}xms , $_element;
|
||||
|
||||
$_localname ||= $_element; # for non-prefixed elements
|
||||
|
||||
# ignore top level elements
|
||||
if (@{ $ignore } && $_localname eq $ignore->[0]) {
|
||||
shift @{ $ignore };
|
||||
return;
|
||||
}
|
||||
|
||||
push @{ $path }, $_localname; # step down in path
|
||||
return if $skip; # skip inside __SKIP__
|
||||
|
||||
# resolve class of this element
|
||||
$_class = $self->{ class_resolver }->get_class( $path )
|
||||
or die "Cannot resolve class for "
|
||||
. join('/', @{ $path }) . " via $self->{ class_resolver }";
|
||||
|
||||
# maybe write as "return $skip = join ... if (...)" ?
|
||||
# would save a BLOCK...
|
||||
return $skip = join('/', @{ $path }) if ($_class eq '__SKIP__');
|
||||
|
||||
push @$list, $current; # step down in tree ()remember current)
|
||||
|
||||
$characters = q{}; # empty characters
|
||||
|
||||
# Check whether we have a primitive - we implement them as classes
|
||||
# We could replace this with UNIVERSAL->isa() - but it's slow...
|
||||
# match is a bit faster if the string does not match, but WAY slower
|
||||
# if $class matches...
|
||||
|
||||
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 $@;
|
||||
}
|
||||
|
||||
$current = $_class->new({ %_attrs }); # set new current object
|
||||
|
||||
# remember top level element
|
||||
defined $self->{ data }
|
||||
or ($self->{ data } = $current);
|
||||
},
|
||||
|
||||
Char => sub {
|
||||
return if $skip;
|
||||
$characters .= $_[1];
|
||||
},
|
||||
|
||||
End => sub {
|
||||
$_element = $_[1];
|
||||
|
||||
($_prefix, $_localname) = split m{:}xms , $_element;
|
||||
$_localname ||= $_element; # for non-prefixed elements
|
||||
|
||||
pop @{ $path }; # step up in path
|
||||
|
||||
if ($skip) {
|
||||
return if $skip ne join '/', @{ $path }, $_localname;
|
||||
$skip = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
# This one easily handles ignores for us, too...
|
||||
return if not ref $$list[-1];
|
||||
|
||||
# set characters in current if we are a simple type
|
||||
# we may have characters in complexTypes with simpleContent,
|
||||
# too - maybe we should rely on the presence of characters ?
|
||||
# may get a speedup by defining a ident method in anySimpleType
|
||||
# and looking it up via exists &$class::ident;
|
||||
if ( $current->isa('SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType') ) {
|
||||
$current->set_value( $characters );
|
||||
}
|
||||
# currently doesn't work, as anyType does not implement value -
|
||||
# maybe change ?
|
||||
# $current->set_value( $characters ) if ($characters);
|
||||
|
||||
# set appropriate attribute in last element
|
||||
# multiple values must be implemented in base class
|
||||
$_method = "add_$_localname";
|
||||
$$list[-1]->$_method( $current );
|
||||
|
||||
$current = pop @$list; # step up in object hierarchy...
|
||||
}
|
||||
);
|
||||
return $parser;
|
||||
}
|
||||
|
||||
sub parse {
|
||||
$_[0]->_initialize( XML::Parser::Expat->new() )->parse( $_[1] );
|
||||
return $_[0]->{ data };
|
||||
}
|
||||
|
||||
sub parsefile {
|
||||
$_[0]->_initialize( XML::Parser::Expat->new() )->parsefile( $_[1] );
|
||||
return $_[0]->{ data };
|
||||
}
|
||||
|
||||
sub get_data {
|
||||
return $_[0]->{ 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.
|
||||
|
||||
=head2 Skipping unwanted items
|
||||
|
||||
Sometimes there's unneccessary information transported in SOAP messages.
|
||||
|
||||
To skip XML nodes (including all child nodes), just edit the type map for
|
||||
the message and set the type map entry to '__SKIP__'.
|
||||
|
||||
=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: $
|
||||
|
||||
75
lib/SOAP/WSDL/Expat/MessageStreamParser.pm
Normal file
75
lib/SOAP/WSDL/Expat/MessageStreamParser.pm
Normal file
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/perl
|
||||
package SOAP::WSDL::Expat::MessageStreamParser;
|
||||
use strict;
|
||||
use warnings;
|
||||
use XML::Parser::Expat;
|
||||
use SOAP::WSDL::Expat::MessageParser;
|
||||
use base qw(SOAP::WSDL::Expat::MessageParser);
|
||||
|
||||
sub parse_start {
|
||||
my $self = shift;
|
||||
$self->{ parser } = $_[0]->_initialize( XML::Parser::ExpatNB->new() );
|
||||
}
|
||||
sub init;
|
||||
*init = \&parse_start;
|
||||
|
||||
sub parse_more {
|
||||
$_[0]->{ parser }->parse_more( $_[1] );
|
||||
}
|
||||
|
||||
sub parse_done {
|
||||
$_[0]->{ parser }->parse_done();
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
See SOAP::WSDL::Expat::MessageParser
|
||||
|
||||
=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: $
|
||||
|
||||
225
lib/SOAP/WSDL/Manual.pod
Normal file
225
lib/SOAP/WSDL/Manual.pod
Normal file
@@ -0,0 +1,225 @@
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::Manual - accessing WSDL based web services
|
||||
|
||||
=head1 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.
|
||||
|
||||
=head2 Interface class creation
|
||||
|
||||
To create interface classes, follow the steps above from
|
||||
L<Quick walk-through for the unpatient|Quick walk-through for the unpatient>.
|
||||
|
||||
If this works fine for you, skip the next paragraphs. If not, read on.
|
||||
|
||||
The steps to instrument a web service with SOAP::WSDL perl bindings
|
||||
(in detail) are as follows:
|
||||
|
||||
=over
|
||||
|
||||
=item * Gather web service information
|
||||
|
||||
You'll need to know at least a URL pointing to the web service's WSDL
|
||||
definition.
|
||||
|
||||
If you already know more - like which methods the service provides, or
|
||||
how the XML messages look like, that's fine. All these things will help you
|
||||
later.
|
||||
|
||||
=item * Create WSDL bindings
|
||||
|
||||
perl wsdl2perl.pl -b base_dir URL
|
||||
|
||||
This will generate the perl bindings in the directory specified by base_dir.
|
||||
|
||||
For more options, see L<wsdl2perl.pl> - you may want to specify class
|
||||
prefixes for XML type and element classes, type maps and interface classes,
|
||||
and you may even want to add custom typemap elements.
|
||||
|
||||
=item * Check the result
|
||||
|
||||
There should be a bunch of classes for types (in the MyTypes:: namespace by
|
||||
default), elements (in MyElements::), and at least one typemap
|
||||
(in MyTypemaps::) and one interface class (in MyInterfaces::).
|
||||
|
||||
If you don't already know the details of the web service you're going to
|
||||
instrument, it's now time to read the perldoc of the generated interface
|
||||
classes. It will tell you what methods each service provides, and which
|
||||
parameters they take.
|
||||
|
||||
If the WSDL definition is informative about what these methods do,
|
||||
the included perldoc will be, too.
|
||||
|
||||
=item * Write a perl script (or module) accessing the web service.
|
||||
|
||||
use MyInterface::SERVICE_NAME;
|
||||
my $service = MyInterface::SERVICE_NAME->new();
|
||||
|
||||
my $result = $service->SERVICE_METHOD();
|
||||
die $result if not $result;
|
||||
print $result;
|
||||
|
||||
The above handling of errors ("die $result if not $result") may look a bit
|
||||
strange - it is due to the nature of
|
||||
L<SOAP::WSDL::SOAP::Typelib::Fault11|SOAP::WSDL::SOAP::Typelib::Fault11>
|
||||
objects SOAP::WSDL uses for signalling failure.
|
||||
|
||||
These objects are false in boolean context, but serialize to their XML structure
|
||||
on stringification.
|
||||
|
||||
You may, of course, access individual fault properties, too. To get a list of
|
||||
fault properties, see L<SOAP::WSDL::SOAP::Typelib::Fault11>
|
||||
|
||||
=back
|
||||
|
||||
=head2 Adding missing information
|
||||
|
||||
Sometimes, WSDL definitions are incomplete. In most of these cases, proper
|
||||
fault definitions are missing. This means that though the specification sais
|
||||
nothing about it, Fault messages include extra elements in the
|
||||
E<lt>detailE<gt> section, or faults are even indicated by non-fault messages.
|
||||
|
||||
There are two steps you need to perform for adding additional information.
|
||||
|
||||
=over
|
||||
|
||||
=item * Provide required type classes
|
||||
|
||||
For each extra data type used in the XML messages, a type class has to be
|
||||
created.
|
||||
|
||||
It is strongly discouraged to use the same namespace for hand-written and
|
||||
generated classes - while generated classes may be many, you probably will
|
||||
only implement a few by hand. These (precious) few classes may get lost
|
||||
in the mass of (cheap) generated ones. Just imagine one of your co-workers
|
||||
(or even yourself) deleting the whole bunch and re-generating everything
|
||||
- oops - almost everything. You got the point.
|
||||
|
||||
For simplicity, you probably just want to use builtin types wherever
|
||||
possible - you are probably not interested in whether a fault detail's
|
||||
error code is presented to you as a simpleType ranging from 1 to 10
|
||||
(which you have to write) or as a int (which is a builtin type ready
|
||||
to use).
|
||||
|
||||
Using builtin types for simpleType definitions may greatly reduce the
|
||||
number of additional classes you need to implement.
|
||||
|
||||
If the extra type classes you need include E<lt>complexType E<gt>
|
||||
or E<lt>element /E<gt> definitions, see
|
||||
L<SOAP::WSDL::SOAP::Typelib::ComplexType> and
|
||||
L<SOAP::WSDL::SOAP::Typelib::Element> on how to create ComplexType
|
||||
and Element type classes.
|
||||
|
||||
=item * Provide a typemap snippet to wsdl2perl.pl
|
||||
|
||||
SOAP::WSDL uses typemaps for finding out into which class' object
|
||||
a XML node should be transformed.
|
||||
|
||||
Typemaps basically map the path of every XML element inside the Body
|
||||
tag to a perl class.
|
||||
|
||||
Typemap snippets have to look like this (which is actually the
|
||||
default Fault typemap included in every generated one):
|
||||
|
||||
'Fault' => 'SOAP::WSDL::SOAP::Typelib::Fault11',
|
||||
'Fault/faultcode' => 'SOAP::WSDL::XSD::Typelib::Builtin::anyURI',
|
||||
'Fault/faultactor' => 'SOAP::WSDL::XSD::Typelib::Builtin::anyURI',
|
||||
'Fault/faultstring' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
||||
'Fault/detail' => 'SOAP::WSDL::XSD::Typelib::Builtin::anyType',
|
||||
|
||||
The lines are hash key - value pairs. The keys are the XPath
|
||||
expression relative to the Body element.
|
||||
|
||||
If you don't know about XPath: They are just the names of the XML
|
||||
tags, starting from the one inside E<lt>BodyE<gt> up to the current
|
||||
one joined by /.
|
||||
|
||||
One line for every XML node is required.
|
||||
|
||||
You may use all builtin, generated or custom type class names as
|
||||
values.
|
||||
|
||||
Use wsdl2perl.pl -mi=FILE to include custom typemap snippets.
|
||||
|
||||
Your extra statements are included last, so they override potential
|
||||
typemap statements with the same keys.
|
||||
|
||||
=back
|
||||
|
||||
=head1 Accessing a web service without a WSDL definition
|
||||
|
||||
=head1 Troubleshooting
|
||||
|
||||
|
||||
=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
|
||||
51
lib/SOAP/WSDL/Manual/Glossary.pod
Normal file
51
lib/SOAP/WSDL/Manual/Glossary.pod
Normal 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
|
||||
some internet protocol, 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 objects, 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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -3,7 +3,10 @@ use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw/SOAP::WSDL::Base/;
|
||||
|
||||
|
||||
# this class may be used for both soap::operation and wsdl::operation.
|
||||
# which one it is depends on context...
|
||||
|
||||
my %operation_of :ATTR(:name<operation> :default<()>);
|
||||
my %input_of :ATTR(:name<input> :default<()>);
|
||||
my %output_of :ATTR(:name<output> :default<()>);
|
||||
|
||||
201
lib/SOAP/WSDL/Parser.pod
Normal file
201
lib/SOAP/WSDL/Parser.pod
Normal file
@@ -0,0 +1,201 @@
|
||||
=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 Skipping unwanted items
|
||||
|
||||
Sometimes there's unneccessary information transported in SOAP messages.
|
||||
|
||||
To skip XML nodes (including all child nodes), just edit the type map for
|
||||
the message and set the type map entry to '__SKIP__'.
|
||||
|
||||
In the example above, EnqueueMessage/StuffIDontNeed and all child elements
|
||||
are skipped.
|
||||
|
||||
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',
|
||||
'EnqueueMessage/StuffIDontNeed' => '__SKIP__',
|
||||
'EnqueueMessage/StuffIDontNeed/Foo' => 'SOAP::WSDL::XSD::Builtin::string',
|
||||
'EnqueueMessage/StuffIDontNeed/Bar' => 'SOAP::WSDL::XSD::Builtin::string',
|
||||
);
|
||||
|
||||
Note that only SOAP::WSDL::Expat::MessageParser implements skipping elements
|
||||
at the time of writing.
|
||||
|
||||
=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
|
||||
@@ -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);
|
||||
@@ -20,20 +21,20 @@ sub serialize
|
||||
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 )
|
||||
or die "type $item_name , $ns_map{ $prefix } not found";
|
||||
|
||||
my ($prefix, $localname) = split /:/ , $item_name, 2;
|
||||
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 },
|
||||
$ns_map{ $prefix },
|
||||
$localname
|
||||
)
|
||||
or die "element $item_name , $ns_map{ $prefix } not found";
|
||||
)
|
||||
or die "element $item_name , $ns_map{ $prefix } not found";
|
||||
$opt->{ qualify } = 1;
|
||||
return $element->serialize( undef, $data->{ $element->get_name() }, $opt );
|
||||
}
|
||||
@@ -41,54 +42,44 @@ sub serialize
|
||||
}
|
||||
|
||||
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() );
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -76,6 +76,11 @@ my %data_of :ATTR(:default<()>);
|
||||
}
|
||||
}
|
||||
|
||||
sub class_resolver {
|
||||
my $self = shift;
|
||||
$class_resolver_of{ ident $self } = shift;
|
||||
}
|
||||
|
||||
sub start_document {
|
||||
my $ident = ident $_[0];
|
||||
$list_of{ $ident } = [];
|
||||
@@ -114,11 +119,17 @@ sub start_element {
|
||||
# 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 (not $class=~m{^SOAP::WSDL::XSD::Typelib::Builtin}xms) {
|
||||
if (index $class, 'SOAP::WSDL::XSD::Typelib::Builtin', 0 < 0) {
|
||||
eval "require $class" ## no critic qw(ProhibitStringyEval)
|
||||
or die $@;
|
||||
|
||||
# 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
|
||||
# set current object
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package SOAP::WSDL::SAX::WSDLHandler;
|
||||
package SOAP::WSDL::SAX::WSDLHandler;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Carp;
|
||||
use Class::Std::Storable;
|
||||
# use base qw(XML::SAX::Base);
|
||||
use SOAP::WSDL::TypeLookup;
|
||||
|
||||
my %tree_of :ATTR(:name<tree> :default<{}>);
|
||||
my %order_of :ATTR(:name<order> :default<[]>);
|
||||
my %targetNamespace_of :ATTR(:name<targetNamespace> :default<()>);
|
||||
my %current_of :ATTR(:name<current> :default<()>);
|
||||
my %characters_of :ATTR();
|
||||
|
||||
{
|
||||
# we have to implement our own new - we need a blessed Hash ref as $self
|
||||
@@ -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,33 @@ 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
|
||||
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 +71,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,88 +79,100 @@ 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 }
|
||||
);
|
||||
|
||||
$characters_of{ $ident } = q{};
|
||||
return if not $action;
|
||||
|
||||
if ($action->{ type } eq 'CLASS') {
|
||||
eval "require $action->{ class }";
|
||||
croak $@, $tree_of{ $ident } if ($@);
|
||||
|
||||
if ($action)
|
||||
{
|
||||
if ($action->{ type } eq 'CLASS')
|
||||
{
|
||||
eval "require $action->{ class }";
|
||||
croak $@, $tree_of{ $ident } if ($@);
|
||||
my $class = $action->{ class };
|
||||
my $obj = $class->new({ parent => $current_of{ $ident } })->init(
|
||||
values %{ $element->{ Attributes } }
|
||||
);
|
||||
|
||||
my $class = $action->{ class };
|
||||
my $obj = $class->new()->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 characters {
|
||||
$characters_of{ ident $_[0] } .= $_[1]->{ Data };
|
||||
}
|
||||
|
||||
sub end_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->{ type } && $action->{ type } eq 'CLASS' )
|
||||
{
|
||||
$current_of{ $ident } = pop @{ $order_of{ $ident } };
|
||||
}
|
||||
return if not ($action->{ type });
|
||||
if ( $action->{ type } eq 'CLASS' ) {
|
||||
$current_of{ $ident } = pop @{ $order_of{ $ident } };
|
||||
}
|
||||
elsif ($action->{ type } eq 'CONTENT' ) {
|
||||
my $method = $action->{ method };
|
||||
no strict qw(refs);
|
||||
# strip of leading and trailing whitespace
|
||||
$characters_of{ $ident } =~s{ ^ \s+ (.+) \s+ $ }{$1}xms;
|
||||
# replace multi whitespace by one
|
||||
$characters_of{ $ident } =~s{ \s+ }{ }xmsg;
|
||||
$current_of{ $ident }->$method( $characters_of{ $ident } );
|
||||
}
|
||||
}
|
||||
|
||||
sub fatal_error {
|
||||
die @_;
|
||||
}
|
||||
|
||||
sub get_data {
|
||||
my $self = shift;
|
||||
return $tree_of{ ident $self };
|
||||
my $self = shift;
|
||||
return $tree_of{ ident $self };
|
||||
}
|
||||
1;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,129 +1,157 @@
|
||||
package SOAP::WSDL::TypeLookup;
|
||||
|
||||
my %TYPES = (
|
||||
# wsdl:
|
||||
'http://schemas.xmlsoap.org/wsdl/' => {
|
||||
binding => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::Binding',
|
||||
},
|
||||
definitions => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::Definitions',
|
||||
},
|
||||
portType => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::PortType',
|
||||
},
|
||||
types => {
|
||||
type => 'SKIP',
|
||||
},
|
||||
message => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::Message',
|
||||
},
|
||||
part => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::Part',
|
||||
},
|
||||
service => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::Service',
|
||||
},
|
||||
port => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::Port',
|
||||
},
|
||||
operation => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::Operation',
|
||||
},
|
||||
input => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::OpMessage',
|
||||
},
|
||||
output => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::OpMessage',
|
||||
},
|
||||
fault => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::OpMessage',
|
||||
},
|
||||
types => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::Types',
|
||||
}
|
||||
},
|
||||
# soap:
|
||||
'http://schemas.xmlsoap.org/wsdl/soap/' => {
|
||||
operation => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::SoapOperation',
|
||||
},
|
||||
binding => {
|
||||
type => 'PARENT',
|
||||
},
|
||||
body => {
|
||||
type => 'PARENT',
|
||||
},
|
||||
address => {
|
||||
type => 'PARENT',
|
||||
}
|
||||
},
|
||||
'http://www.w3c.org/2001/XMLSchema' => {
|
||||
schema => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::XSD::Schema',
|
||||
},
|
||||
element => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::XSD::Element',
|
||||
},
|
||||
simpleType => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::XSD::SimpleType',
|
||||
},
|
||||
complexType => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::XSD::ComplexType',
|
||||
},
|
||||
# wsdl:
|
||||
'http://schemas.xmlsoap.org/wsdl/' => {
|
||||
binding => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::Binding',
|
||||
},
|
||||
definitions => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::Definitions',
|
||||
},
|
||||
portType => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::PortType',
|
||||
},
|
||||
message => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::Message',
|
||||
},
|
||||
part => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::Part',
|
||||
},
|
||||
service => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::Service',
|
||||
},
|
||||
port => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::Port',
|
||||
},
|
||||
operation => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::Operation',
|
||||
},
|
||||
input => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::OpMessage',
|
||||
},
|
||||
output => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::OpMessage',
|
||||
},
|
||||
fault => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::OpMessage',
|
||||
},
|
||||
types => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::Types',
|
||||
},
|
||||
documentation => {
|
||||
type => 'CONTENT',
|
||||
method => 'set_documentation',
|
||||
}
|
||||
},
|
||||
# soap:
|
||||
'http://schemas.xmlsoap.org/wsdl/soap/' => {
|
||||
operation => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::SoapOperation',
|
||||
},
|
||||
binding => {
|
||||
type => 'PARENT',
|
||||
},
|
||||
body => {
|
||||
type => 'PARENT',
|
||||
},
|
||||
address => {
|
||||
type => 'PARENT',
|
||||
}
|
||||
},
|
||||
'http://www.w3.org/2001/XMLSchema' => {
|
||||
schema => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::XSD::Schema',
|
||||
},
|
||||
attribute => {
|
||||
type => 'SKIP' # not implemented yet
|
||||
},
|
||||
attributeGroup => {
|
||||
type => 'SKIP', # not implemented yet
|
||||
},
|
||||
key => {
|
||||
type => 'SKIP', # not implemented yet
|
||||
},
|
||||
keyref => {
|
||||
type => 'SKIP', # not implemented yet
|
||||
},
|
||||
unique => {
|
||||
type => 'SKIP', # not implemented yet
|
||||
},
|
||||
notation => {
|
||||
type => 'SKIP', # not implemented yet
|
||||
},
|
||||
annotation => {
|
||||
type => 'SKIP', # not implemented yet
|
||||
},
|
||||
appinfo => {
|
||||
type => 'SKIP', # not implemented yet
|
||||
},
|
||||
description => {
|
||||
type => 'SKIP', # not implemented yet
|
||||
},
|
||||
element => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::XSD::Element',
|
||||
},
|
||||
simpleType => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::XSD::SimpleType',
|
||||
},
|
||||
complexType => {
|
||||
type => 'CLASS',
|
||||
class => 'SOAP::WSDL::XSD::ComplexType',
|
||||
},
|
||||
simpleContent => {
|
||||
type => 'METHOD',
|
||||
method => 'set_contentModel',
|
||||
value => 'simpleContent'
|
||||
},
|
||||
complexContent => {
|
||||
type => 'METHOD',
|
||||
method => 'set_contentModel',
|
||||
value => 'complexContent'
|
||||
},
|
||||
restriction => {
|
||||
type => 'METHOD',
|
||||
method => 'set_restriction',
|
||||
},
|
||||
complexContent => {
|
||||
list => {
|
||||
type => 'METHOD',
|
||||
method => 'set_contentModel',
|
||||
value => 'complexContent'
|
||||
method => 'set_list',
|
||||
},
|
||||
union => {
|
||||
type => 'METHOD',
|
||||
method => 'set_union',
|
||||
},
|
||||
enumeration => {
|
||||
type => 'METHOD',
|
||||
method => 'push_enumeration',
|
||||
},
|
||||
restriction => {
|
||||
type => 'METHOD',
|
||||
method => 'set_restriction',
|
||||
},
|
||||
list => {
|
||||
type => 'METHOD',
|
||||
method => 'set_list',
|
||||
},
|
||||
union => {
|
||||
type => 'METHOD',
|
||||
method => 'set_union',
|
||||
},
|
||||
enumeration => {
|
||||
type => 'METHOD',
|
||||
method => 'push_enumeration',
|
||||
},
|
||||
group => {
|
||||
type => 'METHOD',
|
||||
method => 'set_flavor',
|
||||
value => 'all',
|
||||
},
|
||||
all => {
|
||||
type => 'METHOD',
|
||||
method => 'set_flavor',
|
||||
value => 'all',
|
||||
},
|
||||
all => {
|
||||
type => 'METHOD',
|
||||
method => 'set_flavor',
|
||||
value => 'all',
|
||||
},
|
||||
choice => {
|
||||
type => 'METHOD',
|
||||
method => 'set_flavor',
|
||||
@@ -133,16 +161,10 @@ my %TYPES = (
|
||||
type => 'METHOD',
|
||||
method => 'set_flavor',
|
||||
value => 'sequence',
|
||||
},
|
||||
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
# thei're equal (typo ?)
|
||||
$TYPES{ 'http://www.w3.org/2001/XMLSchema' } = $TYPES{
|
||||
'http://www.w3c.org/2001/XMLSchema'
|
||||
};
|
||||
|
||||
|
||||
sub lookup {
|
||||
my $self = shift;
|
||||
|
||||
46
lib/SOAP/WSDL/XSD/Builtin.pm
Normal file
46
lib/SOAP/WSDL/XSD/Builtin.pm
Normal file
@@ -0,0 +1,46 @@
|
||||
package SOAP::WSDL::XSD::Builtin;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::Base);
|
||||
use Data::Dumper;
|
||||
|
||||
sub serialize {
|
||||
my ($self, $name, $value, $opt) = @_;
|
||||
my $xml;
|
||||
$opt->{ indent } ||= "";
|
||||
$opt->{ attributes } ||= [];
|
||||
|
||||
$xml .= $opt->{ indent } if ($opt->{ readable });
|
||||
$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() . '"' if ($self->get_name() );
|
||||
}
|
||||
|
||||
if (defined $value) {
|
||||
$xml .= '>';
|
||||
$xml .= "$value";
|
||||
$xml .= '</' . $name . '>' ;
|
||||
}
|
||||
else {
|
||||
$xml .= '/>';
|
||||
}
|
||||
$xml .= "\n" if ($opt->{ readable });
|
||||
return $xml;
|
||||
}
|
||||
|
||||
sub explain {
|
||||
my ($self, $opt, $name ) = @_;
|
||||
$opt->{ indent } = q{} if not defined $opt->{ indent };
|
||||
return "$opt->{ indent }'$name' => \$someValue,\n"
|
||||
}
|
||||
|
||||
sub toClass {
|
||||
warn "# builtin";
|
||||
}
|
||||
|
||||
1;
|
||||
@@ -57,8 +57,7 @@ sub init {
|
||||
$self->SUPER::init( @args );
|
||||
}
|
||||
|
||||
sub serialize
|
||||
{
|
||||
sub serialize {
|
||||
my ($self, $name, $value, $opt) = @_;
|
||||
|
||||
$opt->{ indent } ||= q{};
|
||||
@@ -74,7 +73,7 @@ sub serialize
|
||||
|
||||
|
||||
$xml .= join q{ } , "<$name" , @{ $opt->{ attributes } };
|
||||
delete $opt->{ attributes }; # don't propagate...
|
||||
delete $opt->{ attributes }; # don't propagate...
|
||||
|
||||
if ( $opt->{ autotype }) {
|
||||
my $ns = $self->get_targetNamespace();
|
||||
@@ -120,39 +119,42 @@ sub serialize
|
||||
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";
|
||||
$xml .= join q{}, map { $_->explain( $opt ) }
|
||||
@{ $self->get_element() };
|
||||
$opt->{ indent } =~s/\t$//; # step back
|
||||
$xml .= $opt->{ indent } . "},\n";
|
||||
}
|
||||
elsif ($flavor eq "complexContent")
|
||||
{
|
||||
return q{} if not $flavor; # empty complexType
|
||||
$opt->{ indent } ||= q{ };
|
||||
my $xml = q{};
|
||||
$xml .= "$opt->{indent}\'$name'=> {\n" if $name;
|
||||
|
||||
}
|
||||
elsif ($flavor eq "simpleContent")
|
||||
{
|
||||
if ( ($flavor eq "sequence") or ($flavor eq "all") ) {
|
||||
$opt->{ indent } .= " ";
|
||||
for my $element (@{ $self->get_element() }) {
|
||||
$xml .= $element->explain( $opt )
|
||||
}
|
||||
$opt->{ indent } =~s/\s{2}$//; # step back
|
||||
}
|
||||
elsif ($flavor eq "complexContent")
|
||||
{
|
||||
|
||||
}
|
||||
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";
|
||||
}
|
||||
|
||||
|
||||
# if we're called inside a element...
|
||||
$xml .= "$opt->{indent}},\n" if $name;
|
||||
|
||||
return $xml;
|
||||
}
|
||||
|
||||
sub to_typemap {
|
||||
@@ -172,12 +174,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;
|
||||
@@ -190,23 +192,47 @@ my %[% element.get_name %]_of :ATTR(:get<[% element.get_name %]>);
|
||||
[% END %]
|
||||
|
||||
__PACKAGE__->_factory(
|
||||
[ qw([% FOREACH element=self.get_element -%]
|
||||
[% element.get_name %]
|
||||
[ qw([% FOREACH element=self.get_element -%]
|
||||
[% element.get_name %]
|
||||
[% END %]) ],
|
||||
{
|
||||
[% FOREACH element=self.get_element %] [% element.get_name %] => \%[% element.get_name %]_of,
|
||||
[% END %]
|
||||
{
|
||||
[% 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); # element 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 (element.get_ref); # element ref="..."
|
||||
split_name = element.get_ref.split(':');
|
||||
prefix = split_name.0;
|
||||
localname = split_name.1; %]
|
||||
[% element.get_name %] => '[% type_prefix %][% localname %]',
|
||||
[% 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 %]
|
||||
}
|
||||
);
|
||||
@@ -214,21 +240,80 @@ __PACKAGE__->_factory(
|
||||
sub get_xmlns { '[% self.get_targetNamespace %]' }
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
[% MACRO pod BLOCK %]=pod[% END %]
|
||||
[% MACRO cut BLOCK %]=cut[% END %]
|
||||
[% MACRO head1 BLOCK %]=head1[% END %]
|
||||
[% MACRO head2 BLOCK %]=head2[% 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 (element.get_ref); # element ref="..."
|
||||
split_name = element.get_ref.split(':');
|
||||
prefix = split_name.0;
|
||||
localname = split_name.1; %]
|
||||
[% element.get_name %] => '[% type_prefix %][% localname %]',
|
||||
[% 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 {
|
||||
@@ -236,26 +321,3 @@ sub _check_value {
|
||||
}
|
||||
1;
|
||||
|
||||
=pod
|
||||
|
||||
=head1 Bugs and limitations
|
||||
|
||||
=over
|
||||
|
||||
=item * attribute definitions
|
||||
|
||||
Attribute definitions are ignored
|
||||
|
||||
=item * abstract, block, final, mixed
|
||||
|
||||
Handling of these attribute is not implemented yet.
|
||||
|
||||
=item * simpleContent, complexContent, extension, restriction, group, choice
|
||||
|
||||
Handling of these child elements is not implemented yet
|
||||
|
||||
=item * explain may produce erroneous results
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
@@ -43,8 +43,7 @@ sub first_complexType {
|
||||
}
|
||||
|
||||
# serialize type instead...
|
||||
sub serialize
|
||||
{
|
||||
sub serialize {
|
||||
my ($self, $name, $value, $opt) = @_;
|
||||
my $type;
|
||||
my $typelib = $opt->{ typelib };
|
||||
@@ -91,8 +90,8 @@ sub serialize
|
||||
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);
|
||||
$type = $typelib->find_element( $ns, $localname );
|
||||
die "no element for ref $prefix:$localname" if (not $type);
|
||||
return $type->serialize( $name, $value, $opt );
|
||||
}
|
||||
|
||||
@@ -109,21 +108,34 @@ sub serialize
|
||||
return $type->serialize( $name, $value, $opt );
|
||||
}
|
||||
|
||||
sub explain
|
||||
{
|
||||
sub explain {
|
||||
my ($self, $opt, $name) = @_;
|
||||
my $type;
|
||||
my $text = q{};
|
||||
my $text = q{};
|
||||
|
||||
# if we have a simple / complexType, explain right here
|
||||
if ($type = $self->first_simpleType() )
|
||||
{
|
||||
$text .= $type->explain( $opt, $self->get_name() );
|
||||
if ($opt->{ anonymous }) {
|
||||
delete $opt->{ anonymous };
|
||||
return $type->explain( $opt, undef );
|
||||
}
|
||||
return $type->explain( $opt, $self->get_name() );
|
||||
}
|
||||
elsif ($type = $self->first_complexType() )
|
||||
{
|
||||
$text .= $type->explain( $opt, $self->get_name() )
|
||||
if ($opt->{ anonymous }) {
|
||||
delete $opt->{ anonymous };
|
||||
return $type->explain( $opt, undef );
|
||||
}
|
||||
return $type->explain( $opt, $self->get_name() );
|
||||
}
|
||||
elsif (my $element_name = $self->get_ref() ) {
|
||||
my $element = $opt->{ wsdl }->first_types()->find_element(
|
||||
$opt->{ wsdl }->_expand( $element_name )
|
||||
);
|
||||
return $element->explain( $opt, $self->get_name() );
|
||||
}
|
||||
|
||||
# return if it's not a derived type - we don't handle
|
||||
# other stuff yet.
|
||||
@@ -131,16 +143,22 @@ 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);
|
||||
|
||||
return $text .= $type->explain( $opt, $self->get_name() );
|
||||
use Data::Dumper;
|
||||
die "no type for $prefix:$localname ($ns_map{ $prefix })"
|
||||
. Dumper $opt->{ wsdl }->first_types()->first_schema()->_DUMP
|
||||
if (not $type);
|
||||
|
||||
if ($opt->{ anonymous }) {
|
||||
delete $opt->{ anonymous };
|
||||
return $text .= $type->explain( $opt, undef );
|
||||
}
|
||||
return $text .= $type->explain( $opt, $name || $self->get_name() );
|
||||
return 'ERROR: '. $@;
|
||||
}
|
||||
|
||||
@@ -150,10 +168,10 @@ sub to_typemap {
|
||||
my $txt = q{};
|
||||
|
||||
my %nsmap = reverse %{ $opt->{ wsdl }->get_xmlns() };
|
||||
|
||||
my $type;
|
||||
|
||||
push @{ $opt->{path} }, $self->get_name();
|
||||
# referenced types need type_prefix
|
||||
|
||||
if ( my $typename = $self->get_type() ) {
|
||||
my ($prefix, $localname) = split /:/, $self->get_type();
|
||||
my $ns = $nsmap{ $prefix };
|
||||
@@ -166,18 +184,21 @@ sub to_typemap {
|
||||
else
|
||||
{
|
||||
$type = $opt->{ wsdl }->first_types()->find_type( $ns, $localname );
|
||||
|
||||
# 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";
|
||||
@@ -194,7 +215,8 @@ sub to_typemap {
|
||||
elsif ($type = $self->first_complexType() ) {
|
||||
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";;
|
||||
@@ -205,21 +227,26 @@ 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;
|
||||
|
||||
[% IF (type = self.first_simpleType) %]
|
||||
# <element name="[% self.get_name %]"><simpleType> definition
|
||||
use SOAP::WSDL::XSD::Typelib::SimpleType;
|
||||
@@ -227,7 +254,18 @@ 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 (ref_name = self.get_ref);
|
||||
split_name = ref_name.split(':');
|
||||
prefix = split_name.0;
|
||||
localname = split_name.1;
|
||||
ref_class = element_prefix _ localname;
|
||||
%]
|
||||
# <element name="[% self.get_name %]" ref="[% ref_name %]"> definition
|
||||
# use [% ref_class %];
|
||||
use base qw(
|
||||
[% ref_class %]
|
||||
);
|
||||
[% ELSIF (type = self.first_complexType) %]
|
||||
# atomic complexType
|
||||
@@ -243,7 +281,7 @@ my %[% element.get_name %]_of :ATTR(:get<[% element.get_name %]>);
|
||||
[% END %]
|
||||
|
||||
__PACKAGE__->_factory(
|
||||
[ qw([% FOREACH element = type.get_element %]
|
||||
[ qw([% FOREACH element = type.get_element %]
|
||||
[% element.get_name %]
|
||||
[% END %]) ],
|
||||
{
|
||||
@@ -256,25 +294,26 @@ __PACKAGE__->_factory(
|
||||
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 %]',
|
||||
[% element.get_name %] => 'SOAP::WSDL::XSD::Typelib::Builtin::[% localname %]',
|
||||
[% ELSE %]
|
||||
[% element.get_name %] => '[% type_prefix %]::[% localname %]',
|
||||
[% END %]
|
||||
[% 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 = type_prefix _ '::' _ localname;
|
||||
base_class = type_prefix _ localname;
|
||||
-%]
|
||||
|
||||
use [% base_class %];
|
||||
@@ -283,10 +322,6 @@ use base qw(
|
||||
SOAP::WSDL::XSD::Typelib::Element
|
||||
[% base_class %]
|
||||
);
|
||||
[% ELSIF (element = self.get_ref)
|
||||
%]
|
||||
# element ref"element" definition
|
||||
# Sorry, we don't handle this yet...
|
||||
[% END %]
|
||||
|
||||
sub get_xmlns { '[% self.get_targetNamespace %]' }
|
||||
@@ -298,66 +333,70 @@ __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 },
|
||||
type_prefix => $opt->{ type_prefix },
|
||||
self => $self,
|
||||
nsmap => { reverse %{ $opt->{ wsdl }->get_xmlns() } },
|
||||
},
|
||||
$opt->{ output },
|
||||
)
|
||||
or die $tt->error();
|
||||
|
||||
__END__
|
||||
|
||||
[% MACRO pod BLOCK %]=pod[% END %]
|
||||
[% MACRO cut BLOCK %]=cut[% END %]
|
||||
[% MACRO head1 BLOCK %]=head1[% END %]
|
||||
[% MACRO head2 BLOCK %]=head2[% 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;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Element - XSD Element representation
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Represents a XML Schema Definition's Element element for serializing into
|
||||
various forms.
|
||||
|
||||
=head1 Bugs and limitations
|
||||
|
||||
=over
|
||||
|
||||
=item * block
|
||||
|
||||
Handling of the block attribute is not implemented yet.
|
||||
|
||||
=item * final
|
||||
|
||||
Handling of the final attribute is not implemented yet.
|
||||
|
||||
=item * substitutionGroup
|
||||
|
||||
Handling of the substitutionGroup attribute is not implemented yet
|
||||
|
||||
=item * explain may produce erroneous results
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYING
|
||||
|
||||
This module is part of SOAP-WSDL. See SOAP::WSDL for license.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Insert @ instead of whitespace into e-mail.
|
||||
|
||||
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
|
||||
|
||||
=cut
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
package SOAP::WSDL::XSD::Primitive;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::Base);
|
||||
use Data::Dumper;
|
||||
|
||||
sub serialize
|
||||
{
|
||||
my ($self, $name, $value, $opt) = @_;
|
||||
my $xml;
|
||||
$opt->{ indent } ||= "";
|
||||
$opt->{ attributes } ||= [];
|
||||
|
||||
$xml .= $opt->{ indent } if ($opt->{ readable });
|
||||
$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() . '"' if ($self->get_name() );
|
||||
}
|
||||
|
||||
if (defined $value)
|
||||
{
|
||||
$xml .= '>';
|
||||
$xml .= "$value";
|
||||
$xml .= '</' . $name . '>' ;
|
||||
}
|
||||
else
|
||||
{
|
||||
$xml .= '/>';
|
||||
}
|
||||
$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 toClass {
|
||||
warn "# primitive";
|
||||
}
|
||||
1;
|
||||
@@ -7,6 +7,7 @@ use base qw(SOAP::WSDL::Base);
|
||||
# child elements
|
||||
my %type_of :ATTR(:name<type> :default<[]>);
|
||||
my %element_of :ATTR(:name<element> :default<[]>);
|
||||
my %group_of :ATTR(:name<group> :default<[]>);
|
||||
|
||||
# attributes
|
||||
my %attributeFormDefault_of :ATTR(:name<attributeFormDefault> :default<()>);
|
||||
|
||||
@@ -3,11 +3,11 @@ use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use SOAP::WSDL::XSD::Schema;
|
||||
use SOAP::WSDL::XSD::Primitive;
|
||||
use SOAP::WSDL::XSD::Builtin;
|
||||
use base qw(SOAP::WSDL::XSD::Schema);
|
||||
|
||||
# all builtin types - add validation (e.g. content restrictions) later...
|
||||
my %PRIMITIVES = (
|
||||
my %BUILTINS = (
|
||||
'string' => {},
|
||||
'boolean' => {},
|
||||
'decimal' => {},
|
||||
@@ -50,9 +50,9 @@ sub START {
|
||||
my $self = shift;
|
||||
my @args = @_;
|
||||
|
||||
while (my ($name, $value) = each %PRIMITIVES )
|
||||
while (my ($name, $value) = each %BUILTINS )
|
||||
{
|
||||
$self->push_type( SOAP::WSDL::XSD::Primitive->new({
|
||||
$self->push_type( SOAP::WSDL::XSD::Builtin->new({
|
||||
name => $name,
|
||||
targetNamespace => 'http://www.w3.org/2001/XMLSchema',
|
||||
} )
|
||||
|
||||
@@ -5,55 +5,52 @@ 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
|
||||
{
|
||||
sub push_enumeration {
|
||||
my $self = shift;
|
||||
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' };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,23 +100,21 @@ sub _serialize_single {
|
||||
}
|
||||
|
||||
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;
|
||||
my ($self, $opt, $name ) = @_;
|
||||
$opt->{ indent } = q{} if not defined $opt->{ indent };
|
||||
return "$opt->{ indent }'$name' => \$someValue,\n"
|
||||
}
|
||||
|
||||
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'
|
||||
@@ -155,25 +150,4 @@ EOT
|
||||
return $code;
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
=pod
|
||||
|
||||
=head1 Bugs and limitations
|
||||
|
||||
=over
|
||||
|
||||
=item * simpleContent, complexContent
|
||||
|
||||
These child elements are not implemented yet
|
||||
|
||||
=item * union
|
||||
|
||||
union simpleType definitions probalbly serialize wrong
|
||||
|
||||
=item * explain may produce erroneous results
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
@@ -172,6 +172,163 @@ 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
|
||||
|
||||
date values are automatically converted into XML date strings during setting:
|
||||
|
||||
YYYY-MM-DD+zz:zz
|
||||
|
||||
The time zone is set to the local time zone if not included.
|
||||
|
||||
All input variants supported by Date::Parse are supported. You may even pass
|
||||
in dateTime strings - the time part will be ignored. Note that
|
||||
set_value is around 100 times slower when setting non-XML-time strings
|
||||
|
||||
=head2 SOAP::WSDL::XSD::Typelib::Builtin::dateTime
|
||||
|
||||
dateTime values are automatically converted into XML dateTime strings during setting:
|
||||
|
||||
YYYY-MM-DDThh:mm:ss.nnnnnnn+zz:zz
|
||||
|
||||
The optional nanoseconds parts is excluded in converted values, as it would always be 0.
|
||||
|
||||
All input variants supported by Date::Parse are supported. Note that
|
||||
set_value is around 100 times slower when setting non-XML-time strings
|
||||
|
||||
=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
|
||||
|
||||
List of SOAP::WSDL::XSD::Typelib::Builtin::IDREF objects.
|
||||
|
||||
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
|
||||
|
||||
time values are automatically converted into XML time strings during setting:
|
||||
|
||||
hh:mm:ss.nnnnnnn+zz:zz
|
||||
hh:mm:ss+zz:zz
|
||||
|
||||
The time zone is set to the local time zone if not included. The optional
|
||||
nanoseconds part is not included in converted values, as it would always be 0.
|
||||
|
||||
All input variants supported by Date::Parse are supported. You may even pass
|
||||
in dateTime strings - the date part will be ignored. Note that
|
||||
set_value is around 100 times slower when setting non-XML-time strings
|
||||
|
||||
=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
|
||||
|
||||
|
||||
@@ -1,27 +1,25 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::ENTITY;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::NCName);
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::ENTITY - ENTITY objects
|
||||
|
||||
=head1 LICENSE
|
||||
# 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);
|
||||
|
||||
Copyright 2004-2007 Martin Kutter.
|
||||
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;
|
||||
};
|
||||
};
|
||||
|
||||
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
|
||||
1;
|
||||
|
||||
@@ -5,22 +5,3 @@ use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::NCName);
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::ID - ID objects
|
||||
|
||||
=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
|
||||
@@ -5,22 +5,3 @@ use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::ID);
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::IDREF - IDREF objects
|
||||
|
||||
=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
|
||||
@@ -7,26 +7,3 @@ use base qw(
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::IDREF);
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::IDREFS - IDREFS objects
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
IDREFS is a list datatype implemented by list derivation from IDREF.
|
||||
|
||||
=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
|
||||
@@ -1,26 +1,25 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::NCName;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::Name);
|
||||
|
||||
# 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;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::NCName - NCName objects
|
||||
|
||||
=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
|
||||
@@ -1,26 +1,26 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::NMTOKEN;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::token);
|
||||
|
||||
# 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;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::NMTOKEN - NMTOKEN objects
|
||||
|
||||
=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
|
||||
@@ -1,33 +1,26 @@
|
||||
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::NMTOKEN);
|
||||
|
||||
# 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;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::NMTOKENS - NMTOKENS objects
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
List of NMTOKEN objects.
|
||||
|
||||
Implemented by derivation via SOAP::WSDL::XSD::Typelib::Builtin::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
|
||||
@@ -1,8 +1,6 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::NOTATION;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
|
||||
|
||||
my %length_of :ATTR(:name<length> :default<()>);
|
||||
my %minLength_of :ATTR(:name<minLength> :default<()>);
|
||||
@@ -10,36 +8,26 @@ 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;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::NOTATION - NOTATION object
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
NOTATION represents the NOTATION attribute type from
|
||||
XML 1.0 (Second Edition)
|
||||
|
||||
=head1 BUGS AND LIMITATIONS
|
||||
|
||||
Facets are implemented but don't have any influence yet.
|
||||
|
||||
No constraints are implemented yet.
|
||||
|
||||
=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
|
||||
@@ -1,26 +1,25 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::Name;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::token);
|
||||
|
||||
# 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;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::Name - Name objects
|
||||
|
||||
=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
|
||||
@@ -1,8 +1,27 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::QName;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
|
||||
|
||||
# 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<()>);
|
||||
@@ -13,33 +32,3 @@ my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::QName - qualified Name object
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
QName represents XML qualified names. The <20>value space<63> of QName
|
||||
is the set of tuples {namespace name, local part}, where namespace
|
||||
name is an anyURI and local part is an NCName.
|
||||
|
||||
=head1 BUGS AND LIMITATIONS
|
||||
|
||||
Facets are implemented but don't have any influence yet.
|
||||
|
||||
No constraints are implemented yet.
|
||||
|
||||
=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
|
||||
@@ -1,8 +1,11 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anyType);
|
||||
|
||||
BEGIN {
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anyType);
|
||||
}
|
||||
|
||||
my %value_of :ATTR(:get<value> :init_arg<value> :default<()>);
|
||||
|
||||
@@ -26,41 +29,14 @@ sub as_bool :BOOLIFY {
|
||||
return $value_of { ident $_[0] };
|
||||
}
|
||||
|
||||
Class::Std::initialize(); # make :BOOLIFY overloading serializable
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType - All builtin and all simpleType types inherit from anySimpleType
|
||||
|
||||
=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 LICENSE
|
||||
sub _get_handlers {
|
||||
my $parser = $_[1];
|
||||
return {
|
||||
Char => $parser->characters(),
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
Class::Std::initialize(); # make :BOOLIFY overloading serializable
|
||||
|
||||
|
||||
1;
|
||||
|
||||
@@ -27,23 +27,3 @@ Class::Std::initialize(); # make :STRINGIFY overloading serializable
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::anyType - Base of all XSD Types
|
||||
|
||||
=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
|
||||
@@ -1,8 +1,26 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::anyURI;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
|
||||
|
||||
# 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<()>);
|
||||
@@ -13,36 +31,3 @@ my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
|
||||
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::anyURI - URI object
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
anyURI represents a Uniform Resource Identifier Reference (URI).
|
||||
An anyURI value can be absolute or relative, and may have an optional
|
||||
fragment identifier (i.e., it may be a URI Reference).
|
||||
|
||||
=head1 BUGS AND LIMITATIONS
|
||||
|
||||
Facets are implemented but don't have any influence yet.
|
||||
|
||||
No constraints are implemented yet.
|
||||
|
||||
=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
|
||||
@@ -1,8 +1,28 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::base64Binary;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
|
||||
|
||||
|
||||
# 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<()>);
|
||||
@@ -13,23 +33,3 @@ my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::base64Binary - base64 encoded binary objects
|
||||
|
||||
=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
|
||||
@@ -1,13 +1,32 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::boolean;
|
||||
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 %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
|
||||
my %value_of :ATTR(:get<value> :init_attr<value> :default<()>);
|
||||
|
||||
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) = @_;
|
||||
@@ -21,7 +40,7 @@ sub serialize {
|
||||
, $self->end_tag($opt);
|
||||
}
|
||||
|
||||
sub as_num :NUMERIFY {
|
||||
sub as_num :NUMERIFY :BOOLIFY {
|
||||
return $_[0]->get_value();
|
||||
}
|
||||
|
||||
@@ -33,37 +52,8 @@ sub set_value {
|
||||
: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Class::Std::initialize(); # make :BOOLIFY overloading serializable
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::boolean - boolean objects
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
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.
|
||||
|
||||
=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
|
||||
@@ -1,33 +1,26 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::byte;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::short);
|
||||
|
||||
# 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;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::byte - byte integer objects
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Subclass of short.
|
||||
|
||||
=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
|
||||
@@ -1,8 +1,9 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::date;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
|
||||
|
||||
use Date::Parse;
|
||||
use Date::Format;
|
||||
|
||||
my %pattern_of :ATTR(:name<pattern> :default<()>);
|
||||
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
|
||||
@@ -12,25 +13,53 @@ 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 set_value {
|
||||
# use set_value from base class if we have a XML-DateTime format
|
||||
#2037-12-31+01:00
|
||||
if (
|
||||
$_[1] =~ m{ ^\d{4} \- \d{2} \- \d{2}
|
||||
(:? [\+\-] \d{2} \: \d{2} )?$
|
||||
}xms
|
||||
) {
|
||||
$_[0]->SUPER::set_value($_[1])
|
||||
}
|
||||
# use a combination of strptime and strftime for converting the date
|
||||
# Unfortunately, strftime outputs the time zone as [+-]0000, whereas XML
|
||||
# whants it as [+-]00:00
|
||||
# We know that the latter part of the TZ is always :00 (there's no time
|
||||
# zone whith minute offset yet), so we just use substr to get the part
|
||||
# up to the last 2 timezone digits and append :00
|
||||
# We leave out the optional nanoseconds part, as it would always be empty.
|
||||
else {
|
||||
# strptime sets empty values to undef - and strftime doesn't like that...
|
||||
my @time_from = map { ! defined $_ ? 0 : $_ } strptime($_[1]);
|
||||
my $time_str = strftime( '%Y-%m-%d%z', @time_from );
|
||||
substr $time_str, -2, 0, ':';
|
||||
$_[0]->SUPER::set_value($time_str);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::date - date objects
|
||||
|
||||
=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
|
||||
|
||||
@@ -3,6 +3,8 @@ use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
|
||||
use Date::Parse;
|
||||
use Date::Format;
|
||||
|
||||
my %pattern_of :ATTR(:name<pattern> :default<()>);
|
||||
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
|
||||
@@ -12,26 +14,52 @@ 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 set_value {
|
||||
# use set_value from base class if we have a XML-DateTime format
|
||||
#2037-12-31T00:00:00.0000000+01:00
|
||||
if (
|
||||
$_[1] =~ m{ ^\d{4} \- \d{2} \- \d{2}
|
||||
T \d{2} \: \d{2} \: \d{2} (:? \. \d{1,7} )?
|
||||
[\+\-] \d{2} \: \d{2} $
|
||||
}xms
|
||||
) {
|
||||
$_[0]->SUPER::set_value($_[1])
|
||||
}
|
||||
# use a combination of strptime and strftime for converting the date
|
||||
# strptime does not emit timezone info, so we're pretty fucked up here.
|
||||
#
|
||||
# Unfortunately, strftime outputs the time zone as [+-]0000, whereas XML
|
||||
# whants it as [+-]00:00
|
||||
# We leave out the optional nanoseconds part, as it would always be empty.
|
||||
else {
|
||||
# strptime sets empty values to undef - and strftime doesn't like that...
|
||||
my @time_from = map { ! defined $_ ? 0 : $_ } strptime($_[1]);
|
||||
undef $time_from[-1];
|
||||
|
||||
my $time_str = strftime( '%Y-%m-%dT%H:%M:%S%z', @time_from );
|
||||
substr $time_str, -2, 0, ':';
|
||||
$_[0]->SUPER::set_value($time_str);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::dateTime - dateTime objects
|
||||
|
||||
=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
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::decimal;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
|
||||
|
||||
my %totalDigits_of :ATTR(:name<totalDigits> :default<()>);
|
||||
my %fractionDigits_of :ATTR(:name<fractionDigits> :default<()>);
|
||||
@@ -13,6 +11,27 @@ 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();
|
||||
@@ -21,24 +40,3 @@ sub as_num :NUMERIFY :BOOLIFY {
|
||||
Class::Std::initialize(); # make :NUMERIFY :BOOLIFY overloading serializable
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::decimal - decimal object, base of all non-float numbers
|
||||
|
||||
=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
|
||||
@@ -1,9 +1,27 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::double;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
|
||||
|
||||
# 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();
|
||||
}
|
||||
@@ -11,46 +29,3 @@ sub as_num :NUMERIFY {
|
||||
Class::Std::initialize(); # make :NUMERIFY overloading serializable
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::double - double precision float objects
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The double datatype corresponds to IEEE double-precision 64-bit floating point type.
|
||||
The basic <20>value space<63> of double consists of the values m <20> 2^e, where m is an
|
||||
integer whose absolute value is less than 2^53, and e is an integer between
|
||||
-1075 and 970, inclusive.
|
||||
|
||||
In addition to the basic <20>value space<63> described above, the <20>value space<63> of double
|
||||
also contains the following special values: positive and negative zero, positive and
|
||||
negative infinity and not-a-number. The <20>order-relation<6F> on double is:
|
||||
|
||||
x < y iff y - x is positive.
|
||||
|
||||
Positive zero is greater than negative zero.
|
||||
|
||||
Not-a-number equals itself and is greater than all double values including
|
||||
positive infinity.
|
||||
|
||||
=head1 BUGS AND LIMITATIONS
|
||||
|
||||
None of the "special" behaviours and values are implemented yet.
|
||||
|
||||
=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
|
||||
@@ -1,8 +1,26 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::duration;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
|
||||
|
||||
# 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<()>);
|
||||
@@ -12,25 +30,5 @@ my %maxExclusive_of :ATTR(:name<maxExclusive> :default<()>);
|
||||
my %minInclusive_of :ATTR(:name<minInclusive> :default<()>);
|
||||
my %minExclusive_of :ATTR(:name<minExclusive> :default<()>);
|
||||
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::duration - duration objects
|
||||
|
||||
=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
|
||||
@@ -1,8 +1,6 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::float;
|
||||
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<()>);
|
||||
@@ -12,6 +10,26 @@ 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();
|
||||
@@ -21,23 +39,3 @@ Class::Std::initialize(); # make :NUMERIFY overloading serializable
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::float - float objects
|
||||
|
||||
=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
|
||||
@@ -1,8 +1,6 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::gDay;
|
||||
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<()>);
|
||||
@@ -12,25 +10,25 @@ my %maxExclusive_of :ATTR(:name<maxExclusive> :default<()>);
|
||||
my %minInclusive_of :ATTR(:name<minInclusive> :default<()>);
|
||||
my %minExclusive_of :ATTR(:name<minExclusive> :default<()>);
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::gDay - day objects
|
||||
|
||||
=head1 LICENSE
|
||||
# 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);
|
||||
|
||||
Copyright 2004-2007 Martin Kutter.
|
||||
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;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
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
|
||||
1;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::gMonth;
|
||||
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<()>);
|
||||
@@ -12,25 +10,25 @@ my %maxExclusive_of :ATTR(:name<maxExclusive> :default<()>);
|
||||
my %minInclusive_of :ATTR(:name<minInclusive> :default<()>);
|
||||
my %minExclusive_of :ATTR(:name<minExclusive> :default<()>);
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::gMonth - month objects
|
||||
|
||||
=head1 LICENSE
|
||||
# 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);
|
||||
|
||||
Copyright 2004-2007 Martin Kutter.
|
||||
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;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
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
|
||||
1;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::gMonthDay;
|
||||
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<()>);
|
||||
@@ -12,25 +10,25 @@ my %maxExclusive_of :ATTR(:name<maxExclusive> :default<()>);
|
||||
my %minInclusive_of :ATTR(:name<minInclusive> :default<()>);
|
||||
my %minExclusive_of :ATTR(:name<minExclusive> :default<()>);
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::gMonthDay - month day objects
|
||||
|
||||
=head1 LICENSE
|
||||
# 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);
|
||||
|
||||
Copyright 2004-2007 Martin Kutter.
|
||||
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;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
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
|
||||
1;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::gYear;
|
||||
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<()>);
|
||||
@@ -12,25 +10,25 @@ my %maxExclusive_of :ATTR(:name<maxExclusive> :default<()>);
|
||||
my %minInclusive_of :ATTR(:name<minInclusive> :default<()>);
|
||||
my %minExclusive_of :ATTR(:name<minExclusive> :default<()>);
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::gYear - year objects
|
||||
|
||||
=head1 LICENSE
|
||||
# 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);
|
||||
|
||||
Copyright 2004-2007 Martin Kutter.
|
||||
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;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
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
|
||||
1;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::gYearMonth;
|
||||
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<()>);
|
||||
@@ -12,23 +10,24 @@ 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;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::gYearMonth - year and month objects
|
||||
|
||||
=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
|
||||
@@ -1,8 +1,26 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::hexBinary;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
|
||||
|
||||
# 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<()>);
|
||||
@@ -12,22 +30,3 @@ my %enumeration_of :ATTR(:name<enumeration> :default<()>);
|
||||
my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::hexBinary - hex encoded binary objects
|
||||
|
||||
=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
|
||||
@@ -1,31 +1,26 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::int;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::long);
|
||||
|
||||
# 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;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::int - int objects
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Subclass of long.
|
||||
|
||||
=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
|
||||
@@ -1,8 +1,28 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::integer;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::decimal);
|
||||
|
||||
# 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();
|
||||
@@ -11,22 +31,3 @@ sub as_num :NUMERIFY {
|
||||
Class::Std::initialize(); # make :NUMERIFY overloading serializable
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::integer - integer objects
|
||||
|
||||
=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
|
||||
@@ -1,26 +1,26 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::language;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::token);
|
||||
|
||||
# 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;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::language - language objects
|
||||
|
||||
=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
|
||||
@@ -1,31 +1,25 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::long;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::integer);
|
||||
|
||||
|
||||
# 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;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::long - long integer objects
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Subclass of integer.
|
||||
|
||||
=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
|
||||
@@ -1,30 +1,25 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::negativeInteger;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::nonPositiveInteger);
|
||||
|
||||
# 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;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::egativeInteger - negative integer objects
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Subclass of integer.
|
||||
|
||||
=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
|
||||
@@ -1,30 +1,25 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::nonNegativeInteger;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::integer);
|
||||
|
||||
# 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;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::nonNegativeInteger - non negative integer objects
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Subclass of integer.
|
||||
|
||||
=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
|
||||
@@ -1,30 +1,26 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::nonPositiveInteger;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::integer);
|
||||
|
||||
# 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;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::nonPositiveInteger - nonPositiveInteger objects
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Subclass of integer.
|
||||
|
||||
=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
|
||||
@@ -1,26 +1,26 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::normalizedString;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::string);
|
||||
|
||||
# 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;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::normalizedString - normalizedString objects
|
||||
|
||||
=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
|
||||
@@ -1,31 +1,25 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::positiveInteger;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::nonNegativeInteger);
|
||||
|
||||
# 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::positiveInteger - positive 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
|
||||
@@ -1,31 +1,25 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::short;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::int);
|
||||
|
||||
# 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;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::short - short int objects
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Subclass of int.
|
||||
|
||||
=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
|
||||
@@ -1,24 +1,44 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::string;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
# use HTML::Entities qw(encode_entities);
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
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{&},
|
||||
q{<} => q{<},
|
||||
q{>} => q{>},
|
||||
q{"} => q{&qout;},
|
||||
q{'} => q{'},
|
||||
);
|
||||
);
|
||||
|
||||
sub serialize {
|
||||
my ($self, $opt) = @_;
|
||||
@@ -38,27 +58,3 @@ sub serialize {
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::string - string objects
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
String objects. XML entities (&, E<lt> E<gt> " ') are encoded on
|
||||
serialization.
|
||||
|
||||
=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
|
||||
@@ -1,8 +1,8 @@
|
||||
package SOAP::WSDL::XSD::Typelib::Builtin::time;
|
||||
use strict;
|
||||
use warnings;
|
||||
use Class::Std::Storable;
|
||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
|
||||
use Date::Parse;
|
||||
use Date::Format;
|
||||
|
||||
my %pattern_of :ATTR(:name<pattern> :default<()>);
|
||||
my %enumeration_of :ATTR(:name<enumeration> :default<()>);
|
||||
@@ -12,23 +12,50 @@ 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 set_value {
|
||||
# use set_value from base class if we have a XML-Time format
|
||||
# 00:00:00.0000000+01:00
|
||||
if (
|
||||
$_[1] =~ m{ ^ \d{2} \: \d{2} \: \d{2} (:? \. \d{1,7} )?
|
||||
[\+\-] \d{2} \: \d{2} $
|
||||
}xms
|
||||
) {
|
||||
$_[0]->SUPER::set_value($_[1])
|
||||
}
|
||||
# use a combination of strptime and strftime for converting the date
|
||||
# Unfortunately, strftime outputs the time zone as [+-]0000, whereas XML
|
||||
# whants it as [+-]00:00
|
||||
# We leave out the optional nanoseconds part, as it would always be empty.
|
||||
else {
|
||||
# strptime sets empty values to undef - and strftime doesn't like that...
|
||||
# we even need to set it to 1 to prevent a "Day '0' out of range 1..31" warning...
|
||||
my @time_from = map { ! defined $_ ? 1 : $_ } strptime($_[1]);
|
||||
my $time_str = strftime( '%H:%M:%S%z', @time_from );
|
||||
substr $time_str, -2, 0, ':';
|
||||
$_[0]->SUPER::set_value($time_str);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
SOAP::WSDL::XSD::Typelib::Builtin::time - time objects
|
||||
|
||||
=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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user