Parsing the Web Services XML result into Smalltalk objects

VA Smalltalk is a "100% VisualAge compatible" IDE that includes the original VisualAge technology and the popular VA Assist and WidgetKit add-ons.

Moderators: Eric Clayberg, wembley, tc, Diane Engles, solveig

Parsing the Web Services XML result into Smalltalk objects

Postby Livardo » Fri Feb 01, 2008 8:36 am

Hi all,

Before I attempt to get my elbows dirty, I thought I'd ask here first, something which may or may not have a simple answer. I've waded through the Web Services guide but I haven't quite digested how to go about doing this.

I used the sample someone posted in another thread to invoke a "Document / Literal SOAP formatted" web service:

Code: Select all

| aContainer aServiceCollection contName parm result |

SstWSContainer clearAll.
aContainer := SstWSContainer createContainerNamed: 'TEST' .
aServiceCollection := aContainer deploy: 'test.wsdl'.
schemas := (aContainer serializationManager schemas at: 'http://test.com') content.
schema := schemas detect: [ :s | s name = 'getProductsWithName' ].
mappedElement := schema asMappedElement.
mappedElement aName: 'sale'.
result := ((aServiceCollection first) invoke: 'getMessagesWithName' withArguments: (Array with: mappedElement)).



the "result" variable now holds an instance of "SstSoapMappedElement".

The question is.. how do I serialize the SstSoapMappedElement result into Smalltalk objects I can query?

Thanks!
Livardo
 
Posts: 27
Joined: Thu Nov 01, 2007 6:33 am

Re: Parsing the Web Services XML result into Smalltalk objects

Postby tc » Sat Feb 02, 2008 10:23 am

Hello,

There are a few ways to do that. First, here is a doc/literal web service that gets the new year date for a given year:


Code: Select all
SstWSContainer clearAll.
[
  | aContainer aServiceCollection contName parm |

    contName := SciSocketManager default getHostName.
    aContainer := SstWSContainer containerNamed: contName
    ifNone: [ SstWSContainer createContainerNamed: contName ].
    aServiceCollection := aContainer
        deploy: 'http://www.holidaywebservice.com/Holidays/US/Dates/USHolidayDates.asmx?WSDL'.
    schemas := (aContainer serializationManager schemas at: 'http://www.27seconds.com/Holidays/US/Dates/') content.
    schema := schemas detect: [ :s | s name = 'GetNewYear' ].
    mappedElement := schema asMappedElement.
    mappedElement year: '2008'.
    ((aServiceCollection first) invoke: 'GetNewYear' withArguments: (Array with: mappedElement)) inspect
] fork


An instance of SstSoapMappedElement is returned. One way to proceed is to look at the XML by sending abtXmlPrintString to this object, which results in:


Code: Select all
'<GetNewYearResponse
    xmlns="http://www.27seconds.com/Holidays/US/Dates/">
   <GetNewYearResult>2008-01-01T00:00:00.0000000-05:00</GetNewYearResult>
</GetNewYearResponse>'


. . . and getting the name of the element of interest, such as 'GetNewYearResult'. Once the element name is known, the following can be done:


Code: Select all
anSstSoapMappedElement getObjectNamed: 'GetNewYearResult'


. . . this code can be executed in the block above. Another way to get the result is by iterating over the elements. For example, one could do the following:


Code: Select all
anSstSoapMappedElement elements inject: Dictionary new into: [ :dict :elem |
   elem object isNil
      ifFalse: [ dict at: elem abtXmlName put: elem object]. 
   dict ]


To see all the services this web service has, go to http://www.soapclient.com/soaptest.html and enter the WSDL file address from above, http://www.holidaywebservice.com/Holidays/US/Dates/USHolidayDates.asmx?WSDL .


Pullling all the above together, here is the script to get the date for Cinco de Mayo for a given year:
Code: Select all
SstWSContainer clearAll.
[
  | aContainer aServiceCollection contName parm soapMappedElement dictionary |

    contName := SciSocketManager default getHostName.
    aContainer := SstWSContainer containerNamed: contName
    ifNone: [ SstWSContainer createContainerNamed: contName ].
    aServiceCollection := aContainer
        deploy: 'http://www.holidaywebservice.com/Holidays/US/Dates/USHolidayDates.asmx?WSDL'.
    schemas := (aContainer serializationManager schemas at: 'http://www.27seconds.com/Holidays/US/Dates/') content.
    schema := schemas detect: [ :s | s name = 'GetCincoDeMayo' ].
    mappedElement := schema asMappedElement.
    mappedElement year: '2008'.
    soapMappedElement := ((aServiceCollection first)
        invoke: 'GetCincoDeMayo' withArguments: (Array with: mappedElement)).
    dictionary := soapMappedElement elements inject: Dictionary new into: [ :dict :elem |
        elem object isNil
            ifFalse: [ dict at: elem abtXmlName put: elem object]. 
        dict ].
    dictionary inspect
] fork


--tc
tc
Moderator
 
Posts: 304
Joined: Tue Oct 17, 2006 7:40 am
Location: Raleigh, NC

Re: Parsing the Web Services XML result into Smalltalk objects

Postby Livardo » Thu Mar 27, 2008 12:14 pm

Here's what I want to do:

In Java someone created an object called "address":

address
-residentName
-street
-unit
-city
-state
-zip

which is returned as an SstSoap object when I call a webservice: getAddressFor: 'John Doe'.

I can call the webservice fine, and Java knows to send me the address object because when I retrieve it in Smalltalk, I get a sstSoap object which is a xml representation of the "address" object. Ok so far.

Problem is I need to send the "address" object back to another web service: modifyAddress: anAddress.

The java web service apparently does not complain if I send back the SstSoap object I get from the first call:

modifyAddress: addressAsSstSoap

Sometimes I do need to create an address object from scratch and it doesn't like it when I just send a Smalltalk Object:

modifyAddress: anAddress

So what's the magic that I'm missing? How do convert my Smalltalk object into an SstSoap object?

Thanks!
Livardo
 
Posts: 27
Joined: Thu Nov 01, 2007 6:33 am

Re: Parsing the Web Services XML result into Smalltalk objects

Postby Livardo » Fri Mar 28, 2008 11:33 am

For posterity, here's what I had to do to get this to work.

I created my "Address" object and put all my setters and getters under a @WS-API category. I faintly remembered doing this, but I had only done it for when the Smalltalk was acting as the server. I created the methods, instantiated it, put some values there, and passed it along as a parameter without doing anything else to it, and voila! Java can handle it!


cheers!
Livardo
 
Posts: 27
Joined: Thu Nov 01, 2007 6:33 am


Return to VA Smalltalk 7.0, 7.5 & 8.0

Who is online

Users browsing this forum: Yahoo [Bot] and 1 guest