Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Calling AirportWeather with the SOAP Toolkit
Message
General information
Forum:
Visual FoxPro
Category:
Web Services
Miscellaneous
Thread ID:
00735988
Message ID:
00739138
Views:
57
Here's a more elaborate version. The GlobalWeather service returns quite a bit more data than the AirportWeather service does.
*!* http://www.capescience.net/webservices/globalweather/index.shtml
*!* Choose your own airport: see the link above for details.
#DEFINE AIRPORT_LOCATION "KORD"

SET ALTERNATE TO output.txt
SET ALTERNATE ON

LOCAL loConn as MSSoap.HttpConnector, ;
   loSerializer as MSSoap.SoapSerializer, ;
   loReader as MSSoap.SoapReader
   
loConn = CREATEOBJECT("MSSoap.HttpConnector")
loSerializer = CREATEOBJECT("MSSoap.SoapSerializer")
loReader = CREATEOBJECT("MSSoap.SoapReader")

*!* loConn is an HTTPConnector: it actually sends the messages through HTTP to the 
*!* web service which is specified as the EndPointURL. Many connector properties are 
*!* exposed through the Property() collection, rather than being addressed as
*!* loConn.EndPointURL, for example.
loConn.Property("EndPointURL") = "http://live.capescience.com/ccx/GlobalWeather"
loConn.Connect()

*!* BeginMessage tells the web service that we're going to start talking to it.
*!* The Connector has an InputStream and an OutputStream -- we send data by 
*!* writing to the InputStream, and read it out from the OutputStream.
loConn.BeginMessage()
   *!* The SOAPSerializer object builds a SOAP message while hiding us from the
   *!* nitty-gritty of the XML it's building. It builds the message, and sends
   *!* it out on the InputStream it's passed in the Init.
   loSerializer.Init(loConn.InputStream)

   *!* Here's where we start building the message. Inside the envelope, you can
   *!* specify other parameters, such as encoding: however, I found that this
   *!* service works fine with the defaults.
   loSerializer.startEnvelope()
      loSerializer.startBody
         *!* The method call and its parameters are all XML elements within the message, 
         *!* so we just need to add them as such. First we add the name of the element.
         *!* Then we add the namespace within which it is found, and the encoding it uses.
         loSerializer.startElement("getWeatherReport", "capeconnect:GlobalWeather:GlobalWeather", "NONE")
            *!* The parameters are elements within the method element.
            loSerializer.startElement("code")
               *!* WriteString is how we send straight text to the serializer.
               loSerializer.writeString(AIRPORT_LOCATION)
            *!* Here we close the various elements we've opened.
            loSerializer.endElement()
         loSerializer.endElement()
      loSerializer.endBody()
   loSerializer.endEnvelope()
loConn.endMessage()

*!* We now load the outputStream from the HTTPConnector into a SOAPReader.
*!* This changes the XML into an object that we can operate on.
loReader.Load(loConn.OutputStream)
*!* Write the XML out so we can look at it separately -- e.g., in IE.
STRTOFILE(loReader.DOM.xml, "gw.xml")

*!* To get down to the actual forecast, we have to open the envelope and the other
*!* layers that wrap the returned data.
loEnvelope = loReader.DOM.childNodes(1)
loBody = loEnvelope.childNodes(1)
loResponse = loBody.childNodes(1)
loForecast = loResponse.childNodes(1)

*!* Now, we walk down the tree recursively, formatting the XML as we go along. I'm 
*!* removing the XML tags and indenting the text with tabs to match the layers 
*!* within the file.
*!*
*!* There is one known bug in this code: when it gets down to the Sky conditions, 
*!* if there's only one layer, it will output the layer as a text string instead 
*!* of parsing it out. Feel free to fix this. :-)
lcTab = ""
? ParseNode(loForecast, lcTab)

SET ALTERNATE OFF
SET ALTERNATE TO
MODIFY FILE output.txt


FUNCTION ParseNode
LPARAMETERS toNode, tcTab
LOCAL lcRetVal as string, loChild as MSXML2.IXMLDOMNode

lcRetVal = ""

IF toNode.childNodes.Length <= 1
   *!* If there's nothing else to recurse, output the information from this node.
   lcRetVal = toNode.Text
ELSE
   *!* Otherwise, scan through the child nodes and parse each one of them.
   FOR EACH loChild IN toNode.ChildNodes
      *!* If you don't check this, you get an extra blank entry for the
      *!* container before you recurse into it.
      IF NOT EMPTY(loChild.baseName)
         lcRetVal = "" + lcRetVal + ;
            CHR(13) + CHR(10) + ;
            tcTab + loChild.baseName + " -- " + ParseNode(loChild, tcTab + CHR(9))
      ENDIF
   ENDFOR
ENDIF

RETURN lcRetVal
My blog
My consulting page
My home page

Member of the Trim Your Auto-Quote Campaign!
What's another word for thesaurus?
Previous
Reply
Map
View

Click here to load this message in the networking platform