logo

Creating HTTP Requests using Microsoft's XML Parser

Thought I would write a quick one about something useful I've been wanting to do for sometime now and finally figured out. It is yet another one of those things that can be quite helpful when applied correctly to solve a problem. Our problem seemed simple enough, as the hard ones often do! We were building an e-commerce solution for a client of ours and got to the portion of the application where we had built the shopping cart, but needed to figure out the shipping rate for the entire order. Our client wanted to use the United States Postal Service's (USPS) API for calculating shipping rate. As we began to read the USPS API we quickly realized that the generated request had to be in XML. Personally, you can fit all of my XML knowledge into a very small container - that's how much XML experience I've had. I do however know a fair amount about HTML and creating HTTP POST requests. As we

read through the USPS API, which is about 92 pages (ouch), we discovered basically all we needed to do was build the HTTP Post request, send it, wait for the response, and parse it. Try searching on Notes.net for XML parser and lotusscript and you get a ton of articles mentioning how "nice it would be" to have such functionality. Luckily we found an article by Paul Ray that we modified to solve our problem.

Prerequisites:

This script must be running on the Win32 platform to work, so if you're still reading this - you're in luck. This example describes creating a new HTTP Post request using calls to the MSXML parser that is installed with Internet Explorer 5. We are running Lotus Domino 5.08 on a Windows 2000 Advanced Server platform with Internet Explorer 5 installed and the script worked like a charm.


The Basics:

In our situation, we needed to calculate the shipping rate before we opened the document in "checkout" mode. The Lotusscript agent is called in the WebQueryOpen event to give us the ability to modify field values before the document is opened. Here is the basic structure of the agent:

  1. Get a handle on the current web document through the session.documentContext
  2. Strip off some values that were appended to the ?OpenAgent URL
  3. Initialize the MSXML Object
  4. Build the HTTP POST Request in Lotusscript string format
  5. Send the HTTP POST Request
  6. Receive the response
  7. Parse out the XML Tag value
  8. Add that parsed value to a field on the current web document
  9. Save the current web document
  10. Null out the MSXML Object
  11. Open the web document

The Parsing:

The parsing of the XML response is simplified using the above method because the response is now basically just a very large text string. All of you Lotusscript gurus no doubt have tons of scripts to manipulate string data. We used two very basic functions that allowed us to grab the value that was between the <Postage> opening XML tag and the </Postage> closing XML tag. There are several ways to manipulate the text once you've received the response - your method for text parsing is as good as any one elses.

Where improvements can be made:

Obviously not every solution is fool proof unless you develop a solution with superb error checking. In our example, very little error checking is used. Once you receive the MSXML response, you could opt to use the objHTTP.status to test the response code (e.g., 200, 401, etc.).

The Code:

Our Lotusscript agent was created so as to be run from the WebQueryOpen event on one of our forms. The agent itself was set to Run Manually from the Agent List and Run Once(@Commands may be used). See Figure 1 below.

image
Figure 1: The agent property.


Sub Initialize
%REM
This routine will create a new HTTP POST request, send values, and retrieve the response from the server. This is done via the XMLHTTP object of the MSXML parser.
%END REM

Dim s As New NotesSession
Dim doc As NotesDocument
Dim objHttp As Variant
Dim response As String
Dim request As String
Dim beginTag As String
Dim endTag As String
Dim rightHalf As String
Dim leftHalf As String


On Error Goto ErrHandler

Set db = s.CurrentDatabase
Set doc = s.DocumentContext

query_string = doc.getitemvalue("Query_String")(0)

If Instr(query_string, "&ZC=") Then

destZipCode = Strright(query_string,"&ZC=")

' --- instantiate an MSXML XMLHTTP object
set objHttp = CreateObject("Microsoft.XMLHTTP")

' --- open a new POST request and set the Content-type header

url = |Http://production.shippingapis.com/ShippingAPI.dll|
req = |API=Rate&XML=<RateRequest USERID="5555555555"
PASSWORD="777777777777"><Package ID="TestID">
<Service>Priority</Service><ZipOrigination>55555
</ZipOrigination><ZipDestination>|+destZipCode+|
</ZipDestination><Pounds>5</Pounds><Ounces>10
</Ounces><Container>None</Container><Size>REGULAR
</Size><Machinable></Machinable></Package>
</RateRequest>|

objHttp.open "POST", url, False, "", ""
objHttp.setRequestHeader "Content-type", "application/x-www-form-urlencoded"

objHttp.send(req)

response = objHttp.responseText

beginTag = "<Postage>"
endTag = "</Postage>"

rightHalf = RightBack(response,beginTag)
LeftHalf = myLeft(rightHalf,endTag)

doc.Shipping = Ccur(LeftHalf)
Call doc.Save(True, True)


Cleanup:

Set objHttp=Nothing

newHREF = "/" + db.FilePath + "/0/" + doc.UniversalID + "?OpenDocument"
Print |[| + newHREF + |]|

End If
Exit Sub

ErrHandler:

' --- runtime error occurred
Msgbox Error$, 48, "Runtime Error"
Resume Cleanup

End Sub

The following two functions are those referenced in the above routine and used to extract the required string from within the XML.

Function RightBack ( sourceString As String, searchString As String ) As String

For i% = Len(sourceString) To 1 Step -1
sourceStringBack$=sourceStringBack$ & Mid(sourceString, i%, 1)
Next

For i% = Len(searchString) To 1 Step -1
searchStringBack$=searchStringBack$ & Mid(searchString, i%, 1)
Next

pos% = Instr ( sourceStringBack$, searchStringBack$ )

If pos% > 0 Then pos% = pos% -1
result$ = Left ( sourceStringBack$, pos% )

For i% = Len(result$) To 1 Step -1
turn$=turn$ & Mid(result$, i%, 1)
Next

RightBack=turn$
End Function

Function myLeft ( sourceString As String, searchString As String ) As String

pos% = Instr ( sourceString, searchString )
If pos% > 0 Then pos% = pos% -1

myLeft = Left ( sourceString, pos% )
End Function


In Summary:

Hopefully the method I have described above demonstrates how you too can use the MSXML object and tailor it to your own needs. To do this all you need do is edit the code modifying the URL and the req values and you're off and running! Let your imagination run wild as the possible solutions you can build are endless. You can even use this method to automatically fill out Notes Forms over the web without any user interaction.


About the Author:


With over seven years experience as a Lotus Notes professional, Patrick has worked on some of the largest and most complex groupware implementations. Specializing in infrastructure design, messaging, and application development, Patrick has a broad range of experience designing, developing, deploying, and supporting departmental and enterprise messaging and groupware solutions. A CLP Principal Application Developer and CLP Principal Systems Administrator, Patrick has developed and implemented large scale messaging solutions, business to business (b2b) architecture and development solutions, and production migrations and rollouts. Patrick has coordinated with and traveled to numerous organizations to provide on site business process analysis, groupware consulting, application development, and messaging implementations. Patrick is the CEO and Senior Software Engineer at Ixion, L.L.C. (http://www.ixiononline.com) As an established Lotus Domino developer, Patrick has contributed development articles to and is published in the Domino Update periodical.

Feedback

    • avatar
    • Bertie
    • Fri 28 Jun 2002

    Great article

    Wonderful article - thanks a lot, we modified the example in order to be able to send data to SAP via an interation tool ( Business connector by web methods ). Previously we tried a java agent to send the data, but this tended to lock the workstation up, this works 100% all the time.

      • avatar
      • Jack
      • Tue 29 Oct 2002

      Re: Great article

      Hi guys i tried this hoping to make a call to a url and post data and the thid party url to call mine back and post data ut it hangs up my application evrytime i try this function. Jack

    • avatar
    • Rita
    • Wed 23 Apr 2003

    Thanks for sharing !!!

    Thanks, Patrick, for sharing what you learned here. Your article has been very helpful. I was going to use a Java agent to send XML, but ran into a problem because it couldn't send in HTTPS mode.

    Your solution with the Microsoft XML Parser works great with HTTPS. Thanks again !!!

  1. XMLHTTP

    can you help me how can i receive request XML in domino if the request is coming from ASP using XMLHTTP

  2. Operation is disallowed in this session.

    Hello,

    I am getting the following error when running this script, "Operation is disallowed in this session." The agent runs fine when I run it from my pc, but from the server it gives me this error. The user is not login to the server, it is a public "Anonymous" access form.

    Could you please shine some light into my problem.

    Thanks.

    Ignacio

      • avatar
      • emi
      • Wed 28 Mar 2007

      Re: Operation is disallowed in this session.

      set the agent property to "Allow restricted operations" but be carefuly what the agent does. See these http://www-1.ibm.com/support/docview.wss?uid=swg21106729

    • avatar
    • Pria
    • Thu 23 Sep 2004

    OLE Automation Object

    Hi...

    I am using a similar code in a scheduled agent . When I run the agent from my client machine it runs perfectly , the moment I schedule it , it gives the following error. I am struggling with this. Please can you help.

    Thanks.

  3. Here is a javascript version of the RightBack fn

    I needed a @RightBack function in Javascript.

    Thanks Patrick, for providing a LotusScript version that is easier to transcribe into Javascript than the one I have in my library.

    Here it is,

    function rightBack (strSource, strSearch) { sourceStringBack = ""; searchStringBack = ""; result = ""; turn = ""; pos = -1; for (i = strSource.length; i>-1; i--) { sourceStringBack=sourceStringBack + strSource.charAt(i) } //end for for (i = strSearch.length; i>-1; i--) { searchStringBack=searchStringBack + strSearch.charAt(i) } //end for pos = sourceStringBack.indexOf(searchStringBack); result = sourceStringBack.substring(0,pos) for (i = result.length; i>-1; i--) { turn=turn + result.charAt(i) } return turn }

  4. help needed

    Hello Sir,

    Can you please please me how to

    send the xml request to the prodution server

    in usps on .net

    • avatar
    • Jeff
    • Mon 7 Aug 2006

    Fantastic

    This was an excellent post, thanks for sharing!

  5. Hi Patrick,

    I think your article is very helpful.

    Just wanted to know, can I use the same for sending the xml to an XML server.

    Thanks

    Saurabh

    • avatar
    • Philippe
    • Sun 13 Nov 2011

    Hello Patrick,

    Just to let you know, your article saved my day !

    FYI I used it to query a Cisco Call Manager from within a Lotus Notes app.

    Greatly appreciated,

    Philippe

Your Comments

Name:
E-mail:
(optional)
Website:
(optional)
Comment:



Navigate other articles in the category "Agents"

« Previous Article Next Article »
Passing arguments to a LotusScript agent   Sending HTML emails, the final word

About This Article

Author: Patrick Ransom
Category: Agents
Keywords: XML; parse; HTTP;

Options

Feedback
Print Friendly

Let's Get Social


About This Website

CodeStore is all about web development. Concentrating on Lotus Domino, ASP.NET, Flex, SharePoint and all things internet.

Your host is Jake Howlett who runs his own web development company called Rockall Design and is always on the lookout for new and interesting work to do.

You can find me on Twitter and on Linked In.

Read more about this site »