Caché provides many classes that provide useful APIs. This week's Tip looks at the available %Net.HttpRequest and %XML.TextReader interfaces.
As discussed in my MultiValue eLearning topic and in my recent MV Tip on XML, the web is based on text files containing mark-up text to tell the browser how to format and display the text, where to find images, etc.
Browsers offer a View Source option to display the raw text including the mark-ups (instead of the formatted text).
One of Google's main activities is visiting every web site and page it can, and indexing the results. It does not need to grab the text from a browser. Rather, there are web APIs that will return the web page source directly.
Caché provides access to such an API via the %Net, package.
If a website provides some useful information you want to examine programmatically, there are a number of ways to capture and analyze the webpage.
For today's example, I will query Google's weather API (mentioned in my XML tip), and capture the current temperature in Boston (also provided is a 4-day forecast).
You could use similar code to visit a stock, auto or real estate site and, for example, determine the current price of an item of interest.
If I point my web browse to:
www.google.com/ig/api?weather=Boston+MA
the browser displays a nested display of the result. But if I View Source, I see the unformatted text:
<?xml version="1.0"?><xml_api_reply version="1"><weather module_id="0" tab_id="0" mobile_row="0" mobile_zipped="1" row="0" section="0" ><forecast_information><city data="Boston, MA"/><postal_code data="Boston MA"/><latitude_e6 data=""/><longitude_e6 data=""/><forecast_date data="2012-04-23"/><current_date_time data="2012-04-23 19:17:00 +0000"/><unit_system data="US"/></forecast_information><current_conditions><condition data="Light rain"/><temp_f data="61"/><temp_c data="16"/><humidity data="Humidity: 82%"/><icon data="/ig/images/weather/mist.gif"/><wind_condition data="Wind: S at 15 mph"/></current_conditions><forecast_conditions><day_of_week data="Mon"/><low data="46"/><high data="70"/><icon data="/ig/images/weather/rain.gif"/><condition data="Rain"/></forecast_conditions><forecast_conditions><day_of_week data="Tue"/><low data="45"/><high data="57"/><icon data="/ig/images/weather/chance_of_rain.gif"/><condition data="Chance of Showers"/></forecast_conditions><forecast_conditions><day_of_week data="Wed"/><low data="37"/><high data="61"/><icon data="/ig/images/weather/chance_of_rain.gif"/><condition data="Chance of Showers"/></forecast_conditions><forecast_conditions><day_of_week data="Thu"/><low data="39"/><high data="66"/><icon data="/ig/images/weather/mostly_sunny.gif"/><condition data="Partly Sunny"/></forecast_conditions></weather></xml_api_reply>
It is one long string of text.
If I examine the original nested display, I see:
This is in the raw source text as:
...<current_conditions><condition data="Light rain"/><temp_f data="61"/>...
This is interpreted as XML element current_conditions contains element condition and element temp_f, condition contains attribute data with value "Light rain", and temp_f contains attribute data with value "61".
Once I have the string of text, I could use a simple text editor or expression parser to find this string and return the current temp.
But XML makes this more convenient. There are many tools available, either from InterSystems or publicly, that can parse and/or transform XML or HTTP files.
For this Tip, I will use our %Net.HttpRequest class to grab this result from the internet and put it in a variable. I will then use our %XML.TextReader class to walk thru the result, and find the current temp.
This MVBasic program gets the text, walks thru it, and prints the full result in an indented format to highlight that it understands the structure.
This is the result.
This MVBasic program gets the text as above, walks thru it, and reports just the current temp.
Here is the result.
You could replace “Boston+MA” with your zip code (in double quotes) and display your data.
The big difference between general HTTP access and a web service, is that the web service describes the structure of the result (with a WSDL), while you are on your own with parsing general web pages.
This example captured the text as a variable. Methods are also provided to capture it as a string, stream or file.
Also, many methods are provided to navigate the resulting structure, depending on your needs and inclination.
The Caché Class Reference provides a number of other useful classes under %XML.
There is another useful example using the %XML.TextReader class in the docs under Caché XML Tutorial
Enjoy!
It is super to get such an example in mvbasic given that when we
convert from the cos examples in SAMPLES or documentation there are
usually still a few tough conversions for us (particularly macros
which should not be such a mystery for me at this point, but I still
haven't figured out how to convert them for mvbasic). It would be
great if examples like this could be provided in the SAMPLES namespace
in the future, but at least being able to find them here is terrific!
We will eventually be writing the server side of non-soap web services
too, providing an api as well as consuming them ourselves from Zen
pages. We have not yet dived into that, so maybe by the time we get
there, you guys might have provided examples of that too??
Keep up the good work with the tips. They are much appreciated. --dawn
> --
> You received this message because you are subscribed to the Google Groups
> "InterSystems: MV Community" group.
> To post to this group, send email to Cac...@googlegroups.com
> To unsubscribe from this group, send email to
> CacheMV-u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/CacheMV?hl=en
--
Dawn M. Wolthuis
Take and give some delight today
Very interesting...but would have been nice to see the code in COS,
using the class. Thx! JJ
--
You received this message because you are subscribed to the Google Groups "InterSystems: MV Community" group.
To post to this group, send email to Cac...@googlegroups.com
To unsubscribe from this group, send email to CacheMV-u...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/CacheMV?hl=en
Thanks for the tip. Great work. I have it working but I have another problem. Is it possible to post xml getting a response? I modified this code, looked at Cache documentation but could only come up with something like this:
xml="<ippay><TransactionType>PING</TransactionType><TerminalID>TESTTERMINAL</TerminalID></ippay>"httprequest->Server="testgtwy.ippay.com"
httprequest->EntityBody->Write(xml)
*httprequest->ContentType = "text/xml"*httprequest->Https = 1httprequest->Send("Post","/ippay/")