[ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ]

Building a Web Page that uses the Web Service


wwSOAP and Objects

As you can see in Figure 3 a portfolio consists of several stocks that are stored in portfolio table with a customer id that is to be tracked (in this case simply with a Session id attached to a cookie for the demo's sake). The application backend needs to retrieve a live quote for each one of the stocks in the portfolio. As I mentioned previously making repeated SOAP calls to the server to retrieve each quote individually is not a great idea from a performance point of view, so rather than making one SOAP call per stock I decided to add another method to my Web Service that receives an XML input with a list of stocks, and an XML output that returns several objects one for each stock in a single XML document. I'll use wwXML for the packaging of those objects.




Figure 7 This SOAP Stock Portfolio example retrieves stock quotes via SOAP and demonstrates server to server and browser to server SOAP communication.

Add the following method to the Web Service:

    * StockService :: GetStockQuotes
    ***  Function: Returns a set of Stock Quotes based on an XML input
    ***            string <quotes><symbol>IBM</symbol><symbol>MSFT</symbol><quote>
    ***    Assume: Pulls data from msn.moneycentral.com
    ***      Pass: lcSymbol  -  MSFT, IBM etc.
    ***    Return: Object
    FUNCTION GetStockQuotes(lcXMLSymbols as String) as String
    LOCAL oDOM, lcXML, x, loQuotes, loQuote
    IF EMPTY(lcXMLSymbols)
       RETURN ""
    IF !EMPTY(oDOM.ParseError.Reason)
       RETURN ""
    loQuotes = oDOM.selectnodes("/quotes/symbol")
    IF ISNULL(loQuotes)
      RETURN ""
    lcXML = ""
    FOR x = 0 to loQuotes.Length -1
       lcSymbol = loQuotes.item(x).Text
       loQuote = THIS.GetStockQuote(lcSymbol)
       IF ISNULL(loQuote)
       lcQuoteXML = loXML.CreateObjectXML( loQuote,"quote" )   
       lcXML = lcxML + STRTRAN(lcQuoteXML, ;
                      "<quote>",[<quote symbol="]+lcSymbol+[">])
    lcXML = [<?xml version="1.0"?>] + CHR(13) + CHR(10) + ;
                    [<stockquotes>] + ;
                    lcXML + ;

The method receives an input XML string that retrieves XML in the following format:


The symbols are retrieved using the XMLDOM parser. The for loop runs through all of the Symbol nodes in the XML document.


For each symbol, a call to GetStockQuote() is made which goes out to the NASDAQ site and retrieves a single quote as an object. This object is turned into an XML fragment with wwXML::CreateObjectXML() which is concatenated with the other symbol retrievals to create a large XML document.


You can review the full source code of about 100 lines of code and the HTML script page used to display the page by clicking on the Show Code links on the bottom of the page. The Web Service relevant piece of code in the Web server processing occurs in the following block:

    *** Now Refresh the profile
    IF llRefresh
       *** Select all items for this user
       SELECT * from Portfolio ;
          where UserId = lcUserId ;
          INTO Cursor TQuery
       *** Create stock quote request in XML format
       *** This will be our SOAP parameter
       lcXML = ;
       [<?xml version="1.0"?>] + CRLF +;
       [<quotes>] + CRLF
          lcxml = lcxml + ;
           [<symbol>] + symbol + [</symbol>] + CRLF
       lcXML = lcXML + [</quotes>] +CRLF
       *** SOAP CALL RIGHT HERE ***
       *** Make the SOAP call and retrieve XML result
       oSOAP.cServerUrl = ;
       lvResult = oSOAP.CallMethod("GetStockQuotes")
       IF oSOAP.lError
          THIS.errormsg("SOAP Error",oSOAP.cErrorMsg)
       *** Parse the XML result
       loQuote = CREATEOBJECT("Quote")
       oDOM = CREATEOBJECT("Microsoft.XMLDOM")
       IF !EMPTY(oDOM.parseerror.reason)
          THIS.errormsg("XML Result Error",oDOM.parseerror.reason)
       *** Loop through all of the quotes and update
       *** the user's portfolio
          *** Load each symbol into an object
          lcSymbol = TRIM(Symbol)
          loSymbol = oDOM.selectSingleNode( ;
                   "/stockquotes/quote[@symbol='" + lcSymbol+ "']")
          IF ISNULL(loSymbol)
          loXML = CREATEOBJECT("wwXML")
          loQuote = loXML.ParseXMLToObject(loSymbol,loQuote)
          IF !ISNULL(loQuote)
             SELECT Portfolio
             LOCATE FOR UserId = lcUserId AND SYMBOL = lcSymbol
             REPLACE Descript with loQuote.cCompany,;
                     updated with loQuote.tUpdated,;
                     price with loQuote.nLast
       pcMessage = "Portfolio refreshed at: " + TIME() + " PST"
    *** End of refreshing profile

The code starts by building an XML string that contains all the symbols to retrieve from the portfolio. That string is then used in the SOAP call as a parameter to the GetStockQuotes() method call. Notice that the actual SOAP call in this example is 3 lines of code plus error checking. Once the call returns it should have returned to us an XML string that contains a set of quote objects for each of the symbols in the portfolio.


The result string looks something like this:

    <?xml version="1.0"?>
    <stockquotes><quote symbol="INTC">
       <ccompany>Intel Corporation</ccompany>
    <quote symbol="MSFT">
       <ccompany>Microsoft Corporation</ccompany>

[ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ]