1
2  Introduction
3
4wsdlpull is a C++ web services client library. It includes a WSDL
5Parser,a XML Schema Parser and Validator and XML Parser and serializer
6and an API and command line tool for dynamic WSDL inspection and
7invocation.
8
9wsdlpull comes with a generic web service client.Using wsdlpull's /wsdl/
10tool you can invoke most web services from command line without writing
11any code.
12
13
14  Table of Contents
15
16   1. *Overview
17   2. *Download <http://sf.net/projects/wsdlpull>*
18   3. *Installation
19   4. *Usage
20   5. *Writing a web service client
21   6. *Parsing WSDL*
22   7. *Using the Schema Parser API
23   8. *Using the schema validation tool
24   9. *Examples
25  10. *XML processing
26  11. *API Documentation <documentation.html>*
27  12. *wsdlpull Discussion <http://groups.yahoo.com/group/wsdlpull>*
28  13. *Reporting bugs and Submitting patches
29
30------------------------------------------------------------------------
31
32
33      Overview
34
35wsdlpull uses the xml pull api to parse a WSDL1.1 document. This makes
36wsdlpull /highly efficient/ which is why you can process and invoke a
37WSDL in no time.
38
39The Web service Invocation API <#client> allows you to /dynamically/
40inspect and invoke a web service. Unlike other toolkits there is no need
41to generate stubs or type serializers.
42You can use the dynamic invocation API to write your own web service
43clients in one step. Writing a web service client involves providing the
44WSDL URL,setting the operation,the input types and getting back the
45results. No knowledge of SOAP is needed to write a web service client
46using wsdlpull. The invocation API is quite protocol independent and
47focusses on presenting a simple and intutive interface and abstracts
48away protocol specific details.
49
50wsdlpull comes with a generic web service invocation tool /wsdl/
51which uses the above API. Both the API and the tool are *very dynamic*
52and allow invocation of WSDLs which have complex types and simple types
53in the schema.Using the /wsdl/ tool you can invoke complex
54web services from command line /without writing any code./
55
56The WSDL parser <#parse> provides APIs to access various WSDL elements
57such as operations,messages,bindings,port types.Although wsdlpull is
58based on the pull parsing style of xml parsing the API is meant to be
59semantically as close as possible to the standard API for parsing
60WSDL,namely WSDL4J.
61
62The schema parser <#schemap> and validator provides an API for parsing
63XSD schema documents and validating their xml instance documents. The
64schema parser is used to parse the types section of the WSDL document.
65The schema <#schema> tool can be used for many purposes such as
66validating schemas and accessing REST services <#examples>.
67
68The Xml parser and serializer provide a C++ implementation of the XML
69Pull API <http://www.xmlpull.org>.WSDL processing,XSD schema
70processing,sending and receiving SOAP messages use the parser and
71serializer.
72
73Download wsdlpull <http://sourceforge.net/projects/wsdlpull> and follow
74the instructions below. The package has detailed doxygen documentation
75for all the APIs
76
77
78
79------------------------------------------------------------------------
80
81
82      Installation
83
84Linux/Unix *Installing from source*
85
86Unpack the archive and give the following commands
87./configure --help
88./configure --prefix=%{prefix} [other options]
89make
90make install
91
92This will compile all the targets excluding examples. If you want to
93compile the examples use the --enable-examples option with configure.
94
95Normally ,g++ does optimization of c++ code and it becomes impossible to
96debug.If you wish to debug then do --disable-opt with configure.
97
98For logging related code to be present add --with-log with configure.
99
100To write a web service client using wsdlpull make sure to add the
101$(prefix)/include in your include path and add $(prefix)/libs and -lwsdl
102-lschema -lxmlpull to your LDFLAGS .
103
104*Installing from rpms/debian packages*
105Many packages are available for wsdlpull via various distributions on the web.
106You can install using rpm -i <package name> or dpkg -i  <package name>
107
108Windows
109The wsdl.exe is present in the win32 directory.Copy it to the main wsdlpull directory and start using it.
110
111To build users can find MSVC++ project files in the win32 directory.
112Open wsdlpull.dsw in MSVC++ and do a clean build. For logging related code to
113be present add LOGGING in the preprocessor defines of the MSVC++ project
114
115Additionally a windows makefile is included which allows singlethreaded,multighreaded and dll builds.
116
117Since the soap.xsd schema is required for parsing wsdl documents with
118soap binding elements (which means almost all wsdl documents) you need
119to adjust the relative path so that the parser can locate the soap
120binding schema. Soap.cpp file has the path to the soap schema. Hence for
121win32 platforms executables for the wsdl tool is generated in the
122wsdlpull root directory ,and has the path to the soap.xsd schema
123hardcoded relative to the wsdlpull root directory .So be wary before you
124move try to execute this from another location ,because you would have
125to change some code to make it work from other locations.
126
127Some older compilers may give errors with the << operator on Qname.If this is
128the case then change those statments to use the << on Qname::getLocalName().
129
130------------------------------------------------------------------------
131
132
133      Usage
134
135wsdlpull has a tool called /wsdl/,a generic web service invocation tool
136which uses the invocation API.Using this command you can see the web
137service operations,their descriptions and provide operation's inputs and
138get the output.
139
140A way to use it is like this.
141
142[user@localhost]wsdl http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl getQuote XYZW
14327.101
144
145If you do not specify the operation name or any of the parameters,the
146tool gives a choice of operations to invoke and prompts for the
147operation's parameters.With the -d option you can also see the
148operation's documentation.
149
150[user@localhost]wsdl  http://www.xmethods.net/sd/2001/CurrencyExchangeService.wsdl
1511.getRate :
152Choose one of the above operations [1-1] :1
153country1:Japan
154country2:India
15546.23
156
157If you just want it in one shot then you can do
158
159[user@localhost]wsdl  http://www.xmethods.net/sd/2001/CurrencyExchangeService.wsdl getRate "United States" India
16043.81
161
162If the parameter is a space separated string make sure you enclose it in
163" " or else the shell would treat it as 2 arguments.
164
165The -l option simply lists the operations of the web service.The below
166command shows how you can see a list of operations available for the
167MovieSearch Web service from www.ignyte.com along with a description of
168what each operation does.
169
170[user@localhost]wsdl -l -d http://www.ignyte.com/webservices/ignyte.whatsshowing.webservice/moviefunctions.asmx?wsdl
1711.GetTheatersAndMovies(This method will retrieve a list of all theaters and the movies playing today.)
1722.GetUpcomingMovies(This method will retrieve a list of all movies that are scheduled to be released in the future and their anticipated release dates.)
173
174The -v options runs the tool in the verbose mode. It displays wsdl
175operations' documentation and also logs the SOAP requests and response.
176
177Invoking the tool with no arguments shows the usage of the command.
178
179The /wsdl/ invocation tool can invoke web services which accept and/or
180return complex types and simple types in their description.If a web
181service needs a complex type then only its constituent simple type
182particles,are passed as inputs. Simple types are validated for basic
183checks and also against any schema provided restrictions such as
184enumeration. For example invoking the instant messenger service from
185/http://www.bindingpoint.com/ws/imalert// involves sending a complex
186type defined as below
187
188
189      <s:element name="SendYahoo">
190        <s:complexType>
191          <s:sequence>
192            <s:element minOccurs="0" maxOccurs="1" name="LKEY" type="s:string" />
193            <s:element minOccurs="0" maxOccurs="1" name="FromName" type="s:string" />
194            <s:element minOccurs="0" maxOccurs="1" name="ToUserID" type="s:string" />
195            <s:element minOccurs="0" maxOccurs="1" name="Message" type="s:string" />
196          </s:sequence>
197        </s:complexType>
198
199When you run the /wsdl / tool on the IM web service you will have to
200just enter the 4 simple constituent elements.
201
202[user@localhost wsdls]$wsdl im.wsdl
2031.SendAIM
2042.SendICQ
2053.SendMSN
2064.SendYahoo
207Choose one of the above operations [1-4] :4
208LKEY: ******
209FromName: Foo
210ToUserID: bar666
211Message:Message1
212### or a one liner
213[user@localhost wsdls]$wsdl im.wsdl SendYahoo   *****   Foo  bar666   "This is a test message"
214
215Sometimes a schema can specify how many times or a
216range(minOccurs..maxOccurs) a particle can occur inside its content
217model. This is often used to implement arrays by specifiying the
218maxOccurs as unbounded. By using the -o options the /wsdl/ tool prompts
219for occurrences of input parameters.
220
221*Notes*
222
223Obviously there is a limit on the expressive power of providing
224parameters from command line for wsdl invocation. Here are a few notes.
225
226   1. There is no way yet to handle correctly and completely,web
227      services which expect soapenc:Array.Some support exists for web
228      services returning soap arrays since 1.9.5.GoogleSearch/mp3 search
229      works.Although multidimensional SOAP arrays are not and probably
230      never will be supported since SOAP arrays themselves are
231      deprecated as per section 5.2.3 of the WS-I basic profile.
232   2. Web services which return complex derived types cannot be invoked
233      dynamically as of release 1.9.5b.
234   3. A web service which accepts a complex type which has a content
235      model(group,sequence) with possible multiple occurrences can
236      accept only one occurrence via the invocaton API as of
237      1.9.5b.Return complex types can be arbitrarily complex except for
238      the above 2 cases.
239   4. Simple types are validated via facets/restriction provided in the
240      schema.If a simple string type is a restricted by an enumeration
241      with values "Male" and "Female",anything other than those values
242      is considered illegal and the tool exits with an error
243      message.There is no way as of now to turn this kind of checking off.
244   5. There is no way as of now to specify occurrence constraints
245      (minOccurs, maxOccurs) of particles in complex types in the input
246      of an operation using the command line in the non interactive
247      mode.Using -o starts the tool in the interactive mode. The
248      invocation API however supports multiple occurences. If you want
249      anything more than the default behavior of the wsdl tool then you
250      should consider writing your own client using the api.
251   6. HTTP POST needed to send SOAP messages and HTTP GET needed to
252      fetch WSDL uri's are done using curl on linux/unix
253      platforms.libcurl is available on most platforms so shouldn't be a
254      problem though.
255
256
2572,3,4  are likely to be fixed in later releases.
258
259
260
261------------------------------------------------------------------------
262
263
264      Writing a web service client
265
266You can use the invocation API to write a web service client. Unlike
267many other toolkits you don't need to generate skeleton stubs or write
268type serializers or even have any knowledge of SOAP.The below example
269illustrates how to write  a client for the StockQuotes.wsdl web service
270included in the distribution.
271
272
273<s:element name="GetQuotes">
274<s:complexType>
275<s:sequence>
276<s:element minOccurs="0" maxOccurs="1" name="QuoteTicker" type="s:string" />
277</s:sequence>
278</s:complexType>
279</s:element>
280<s:element name="GetQuotesResponse">
281<s:complexType>
282<s:sequence>
283<s:element minOccurs="0" maxOccurs="1" name="GetQuotesResult"
284type="s0:ArrayOfQuote" />
285</s:sequence>
286</s:complexType>
287</s:element>
288<s:complexType name="ArrayOfQuote">
289<s:sequence>
290<s:element minOccurs="0" maxOccurs="unbounded" name="Quote"
291type="s0:Quote" />
292</s:sequence>
293</s:complexType>
294<s:complexType name="Quote">
295<s:sequence>
296<s:element minOccurs="0" maxOccurs="1" name="CompanyName" type="s:string" />
297<s:element minOccurs="0" maxOccurs="1" name="StockTicker" type="s:string" />
298<s:element minOccurs="0" maxOccurs="1" name="StockQuote" type="s:string" />
299<s:element minOccurs="0" maxOccurs="1" name="LastUpdated" type="s:string" />
300<s:element minOccurs="0" maxOccurs="1" name="Change" type="s:string" />
301<s:element minOccurs="0" maxOccurs="1" name="OpenPrice" type="s:string" />
302<s:element minOccurs="0" maxOccurs="1" name="DayHighPrice"
303type="s:string" />
304<s:element minOccurs="0" maxOccurs="1" name="DayLowPrice" type="s:string" />
305<s:element minOccurs="0" maxOccurs="1" name="Volume" type="s:string" />
306<s:element minOccurs="0" maxOccurs="1" name="MarketCap" type="s:string" />
307<s:element minOccurs="0" maxOccurs="1" name="YearRange" type="s:string" />
308</s:sequence>
309</s:complexType>
310<s:element name="ArrayOfQuote" nillable="true" type="s0:ArrayOfQuote" />
311</s:schema>
312
313
314
315<message name="GetQuotesSoapIn">
316<part name="parameters" element="s0:GetQuotes" />
317</message>
318<message name="GetQuotesSoapOut">
319<part name="parameters" element="s0:GetQuotesResponse" />
320</message>
321
322
323
324<portType name="StockQuotesSoap">
325<operation name="GetStockQuotes">
326<input name="GetQuotes" message="s0:GetQuotesSoapIn" />
327<output name="GetQuotes" message="s0:GetQuotesSoapOut" />
328</operation>
329</portType>
330
331
332First,include the relevant header file.
333
334| #include <wsdlparser/WsdlInvoker.h> |
335
336The convention while including files from wsdlpull is to specify the
337root include directory in the include path and then specify the actually
338directory while #include -ing. Files belonging to the schema parser
339would be included like
340
341| #include <schemaparser/SchemaParser.h>|
342
343Create an instance of the WsdlInvoker.
344
345| |
346
347
348  WsdlInvoker invoker;
349  if (!invoker.setWSDLUri("StockQuotes.wsdl")) {
350    std::cerr<<invoker.errors()<<std::endl; return 2;
351  }
352
353
354Now set the operation .Before that you can also get a list of operations
355available
356
357| |
358
359
360  std::vector<std::string> ops;
361  invoker.getOperations(ops);
362  if(!invoker.setOperation("GetStockQuotes")){
363
364      std::cerr<<"Error calling GetStockQuotes "<<std::endl;
365      return 2;
366   }
367
368Set the input values. Setting the input values can be done by passing a
369void* or by passing a string representation of the value.
370The string representation is provided for convinience so that you can
371just read something from the standard input using scanf or cin and pass
372it on to the WsdlInvoker to do the type validation check.You dont have
373to bother about reading an int or a float or a string.Just read the data
374from the stream as a string and allow the invoker to do all the validation.
375
376| |
377
378
379   if (invoker.status()){
380
381       std::string ticker("XYZ");
382       if (!invoker.setValue("QuoteTicker",(void*)(&ticker))){
383
384            std::cerr<<"Incorrect input value "<<ticker<<std::endl;
385            return 2;
386       }
387
388        if (invoker.invoke()){
389
390         Schema::Type type;
391         void *val = invoker.getValue("OpenPrice",type);
392         //type is a string
393         cout<<*((std::string*)val)<<std::endl;
394   }
395
396The above example is illustrates the simple API usage. However you can
397get more control over the input and output with more of the API. You can
398set the occurrence constraints like this. | |
399
400
401     std::vector<std::string> stocks
402     stocks.push_back("IBM");
403     stocks.push_back("YHOO");
404     stocks.push_back("MSFT");
405     stocks.push_back("MOT");
406     //4 occurrences of the <QuoteTicker> element
407     invoker.setValue("QuoteTicker",stocks);
408
409
410After invoking the web service ,you can get the individual elements
411using getValue() like above.
412
413The getValue() method returns a type via reference ,which can be used to
414typecast the return void*. xsdType:string is serialized as std::string
415and others are fairly obvious such as int and float for xsdType:int and
416xsdType:float respectively.
417
418See examples/stocks/stocks.cpp to see the above code in action. Apart
419from the simple style above there are apis to examine all the inputs of
420a web service and set values with occurrence constraints for each of
421them. ||
422
423    int getNextInput(std::string & param ,Schema::Type & type,int & min,int & max);
424
425The above API exposes all the simple types that need to be passed as
426input.Even if a web service accepts a complex type ,calls to
427getNextInput exposes the constituent particles which are of a simple
428type. You can either use this style or directly set the value using
429setValue() as shown earlier.
430
431Outputs can be read either using getValue() or by getting the
432TypeContainer for all the message response parts using
433getNextOutput().The TypeContainer interface is more complicated but
434allows better access to the XML structure,such as reading
435attributes,multiple occurrences etc. The api is in the
436schemaparser/TypeContainer.h
437
438The generic web service invocation tool 'wsdl' in wsdlparser/wsdl.cpp
439uses the complex style.Check that for an example
440
441
442
443------------------------------------------------------------------------
444
445
446      Parsing and validating a schema
447
448wsdlpull also includes a schema parser. The Schema parser itself can be
449used in isolation to parse xsd schemas. The schema parser can validate
450an instance document of the xsd schema just parsed.
451Create a SchemaParser object
452||
453
454  #include <schemaparser/SchemaParser.h>
455  #include <schemaparser/SchemaValidator.h>
456  ...
457  SchemaParser sParser= new SchemaParser(uri,"target namespace");
458
459
460Calling SchemaParser::parseSchemaTag() parses the entire document. Use
461getter methods to get types/elements and attributes .Use SchemaValidator
462to parse an instance of a type or element by calling
463| |
464
465 SchemaValidator::validate(int xType, XmlPullParser* ,TypeContainer*)
466
467
468The TypeContainer returned is a recursvive container structure holding
469the values of xml elements and attributes in the instance. See
470src/schemaparser/schema.cpp to understand how to do this.
471
472See the doxygen documentation of the API that comes with the package
473
474
475
476------------------------------------------------------------------------
477
478
479      Schema Validation tool
480
481wsdlpull includes a schema validation tool 'schema' Take the schema
482below which has a bunch of restricted schema types
483
484<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
485<xsd:simpleType name="USState">
486  <xsd:restriction base="xsd:string">
487    <xsd:enumeration value="AK"/>
488    <xsd:enumeration value="AL"/>
489    <xsd:enumeration value="AR"/>
490    <xsd:enumeration value="TX"/>
491    <xsd:enumeration value="IL"/>
492    <xsd:enumeration value="FL"/>
493  </xsd:restriction>
494</xsd:simpleType>
495
496<xsd:simpleType name="myInteger">
497  <xsd:restriction base="xsd:integer">
498    <xsd:minExclusive value="10000"/>
499    <xsd:maxInclusive value="99999"/>
500  </xsd:restriction>
501</xsd:simpleType>
502
503<xsd:simpleType name="listOfMyIntType">
504  <xsd:list itemType="myInteger"/>
505</xsd:simpleType>
506
507<xsd:simpleType name="listOfInt">
508  <xsd:list itemType="xsd:int"/>
509</xsd:simpleType>
510
511<xsd:simpleType name="USStateList">
512 <xsd:list itemType="USState"/>
513</xsd:simpleType>
514
515<xsd:simpleType name="SixUSStates">
516 <xsd:restriction base="USStateList">
517  <xsd:length value="8"/>
518 </xsd:restriction>
519</xsd:simpleType>
520
521<xsd:element name="listOfMyInt" type="listOfMyIntType"/>
522<xsd:element name="sixStates" type="SixUSStates"/>
523</xsd:schema>
524
525
526The below xml is an instance of the above schema which we want to
527validate with the /schema/ tool.
528
529
530<listOfMyInt>20003 15037 95977 95945</listOfMyInt>
531<listOfMyInt>10000 10001</listOfMyInt>
532<sixStates>PA NY CA NY LA AK</sixStates>
533<sixStates>FL IL</sixStates>
534<listOfMyInt>3 4 5</listOfMyInt>
535<sixStates>FL IL AK</sixStates>
536<sixStates>PA IL AK</sixStates>
537
538The output below catches the errors that some of the data types have wrt
539the schema,including violation of enumeration,length,max and min facets.
540
541 [user@localhost]schema list.xsd -i list.xml
542Successfully parsed schema
543:listOfMyInt 20003 15037 95977 95945
544:listOfMyInt 10000 10001 -->Invalid value for data type
545:sixStates PA NY CA NY LA AK -->Invalid value for data type
546:sixStates FL IL -->Invalid value for data type
547:listOfMyInt 3 4 5 -->Invalid value for data type
548:sixStates FL IL AK
549:sixStates PA IL AK -->Invalid value for data type
550
551The tool can flag many other validation errors including violation of
552occurrence constraints,and missing attributes
553
554
555
556------------------------------------------------------------------------
557
558
559      Examples
560
561Invoking the popular stock quotes web service and the currency exchange
562services
563
564wsdl http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl getQuote SYMBOL
565wsdl  http://www.xmethods.net/sd/2001/CurrencyExchangeService.wsdl getRate "United States" India
566
567Get the local time in you city
568
569wsdl http://www.nanonull.com/TimeService/TimeService.asmx?wsdl getCityTime Tokyo
570
571Or a more complex google search whose wsdl is included in the test
572directory.Get the first 5 google search results for 'wsdlpull'
573
574wsdl GoogleSearch.wsdl doGoogleSearch "****license-key****" wsdlpull 1 5 0 1 1 1 1 1
575
576Get a dictionary/thesarus on your command line
577
578wsdl http://services.aonaware.com/DictService/DictService.asmx?WSDL DefineInDict wn thesaurus
579wsdl http://services.aonaware.com/DictService/DictService.asmx?WSDL DefineInDict moby-thes thesaurus
580
581Use the /schema/ tool to access the Yahoo REST API like this below to
582search for Madonna video.
583
584schema
585http://api.search.yahoo.com/VideoSearchService/V1/VideoSearchResponse.xsd
586-i
587"http://api.search.yahoo.com/VideoSearchService/V1/videoSearch?appid=YahooDemo&query=madonna&results=1"
588
589
590The below code returns a list of movies running within a radius of 3
591miles from Beverly Hills,CA.The result is a huge list but takes hardly a
592few seconds on a high speed connection to parse the wsdl,send requests
593and get back the response!
594
595wsdl
596http://www.ignyte.com/webservices/ignyte.whatsshowing.webservice/moviefunctions.asmx?wsdl GetTheatersAndMovies 90209 3
597
598
599------------------------------------------------------------------------
600
601
602      Xml Processing
603
604XML parser and serializer can be used to handle XML .The api is the xml
605pull api <http://www.xmlpull.org> and can be used in the same
606fashion.The roundtrip example in examples/xml gives a demonstration.
607
608
609
610------------------------------------------------------------------------
611
612
613      Reporting Bugs and Submitting patches
614
615Send a bug report to http://groups.yahoo.com/group/wsdlpull or to the
616author <mailto:vivek200120@users.sourceforge.net?subject=wsdlpull>.
617You may also use the sourceforge.net tracker.
618
619If you are submitting a patch then do send the diffs either on the
620mailing list or to the author.Also send a brief description of the patch
621and whether you tested it or if it needs testing. If you need to check
622in to the CVS contact the author for developer access.
623
624Before submitting a patch ,please perform some unit tests to ensure if
625the fix hasnt broken any existing functionality.
626
627   1. If the fix is in the xml parser then run the roundtrip example on
628      as many xml files as possible.Atleast on all the wsdl,schema and
629      xml files that come in the test directory.
630   2. If the fix is in the schema parser then build and run the /schema/
631      tool on the schema files and their instances in the test/schema
632      directory.
633   3. If the fix is in the wsdl parser then invoke the web services in
634      the test/wsdls directory and check if they work You must atleast
635      test one RPC style web service and one Doc/Literal style from the
636      test suite.
637
638If you fixed the xml parser then you must do all of the above,If you
639fixed the schema parser you need to do steps 2 and 3. If you fixed
640something in the wsdlparser,test step 3. If what you fixed was in one of
641the two tools /wsdl/ or /schema/ or in the examples then test them as
642instructed in the documentation of the tools.
643
644
645If you are reporting a bug with the invocation tool make sure to run
646with -v option and send the SOAP request and response along with a link
647to the WSDL
648
649------------------------------------------------------------------------
650
651
652      Authors
653
654Vivek Krishna <mailto:vivek200120@users.sourceforge.net>
655SourceForge.net Logo <http://sourceforge.net>
656