Solved

Generate XML document through ASP

Posted on 2004-03-24
37
1,561 Views
Last Modified: 2013-11-19
Hello Experts,

I am currently developing a site in ASP, with a shopping cart concept. Before checkout, the users enter the quantity and address details. Based on this, we have to send info to UPS in XML format (an example is given in the documentation they provided). UPS will then process this info and return us the rate info (again in XML - example is given)

I am a newbie to XML. I realise that my ASP page has to generate an XML page, send it to the server and upon receipt of data, it has to extract rate information and store it in the database. Then the control proceeds to the next asp page which takes user credit card info for charging.

I know exactly what data to retreive and what data to send but don't know how to do either

1 . I would greatly appreciate it if someone gave me the ASP code for generating XML document, send it to the server and then extract the info I need.
2. Would all this happen on one ASP page with subsequent calls to the server, or would I have to use Response.Redirect method (after sending info to UPS) to process their response?

The points are high - this is urgent ;)
0
Comment
Question by:poshlivin
  • 19
  • 10
  • 4
  • +2
37 Comments
 
LVL 46

Assisted Solution

by:fritz_the_blank
fritz_the_blank earned 50 total points
ID: 10673265
Here is a sample for you based on the Northwind database:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>
      <title>Untitled</title>
</head>
<body>
<%
'create connection to database
dim  strDataPath, strConnectString, objConnection,strSQL,objRS

strDataPath = server.MapPath("NorthWind.mdb")
strConnectString = "Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;"_
                  + " Data Source= " & strDataPath & ";"_
                  + " Mode=Share Deny None;User Id=admin;PASSWORD=;"
                  
if not IsObject("ojbConnection") then
      set objConnection=Server.CreateObject("ADODB.Connection")
      objConnection.ConnectionTimeout = 15
      objConnection.CommandTimeout =  10
      objConnection.Mode = 3 'adModeReadWrite
      if objConnection.state = 0 then
            objConnection.Open strConnectString
      end if
end if


'create your database and populate it with your sql
if not isObject("objRS") then
      set objRS=Server.CreateObject("ADODB.RecordSet")
end if
if objRS.state <> 0 then
      objRS.close
end if
strSQL = "SELECT Customers.CompanyName, Customers.ContactName, Customers.Phone FROM Customers ORDER BY Customers.CompanyName, Customers.ContactName"
objRS.Open strSQL,objConnection,3,3
objRS.Save "D:\My Documents\InProgress\Northwind.xml",1
Response.write("XML File Written!")

'clean up objects!
   if IsObject(objRS) then
        if not objRS is Nothing Then
             if objRS.state <> 0 then
                  objRS.close
             end if
             set objRS = Nothing
        end if
   end if

   if IsObject(objConnection) then
        if not objConnection is Nothing Then
             if objConnection.state <> 0 then
                  objConnection.close
             end if
             set objConnection = Nothing
        end if
   end if

%>


</body>
</html>

0
 
LVL 46

Expert Comment

by:fritz_the_blank
ID: 10673329
The above code will generate the xml data that you need. You can incorporate this into your existing code without needing to modify the flow of your current layout.

Fritz the Blank
0
 

Author Comment

by:poshlivin
ID: 10673633
Thanks Fritz the Blank.

The code you mentioned will create the XML file that I need. How do I then send it to the UPS server (like we have forms on html pages whose action is set to the URL it calls)?
Would this code snippet in an ASP page work?
.......
set xdoc = Server.CreateObject("MSXML2.DOMDocument")
xdoc.setProperty "ServerHTTPRequest", true      
xdoc.validateOnParse = true
xdoc.async=false
xdoc.load(url or file)
.......

Also, once I send the XML to the UPS server, how do I get it back and extract the info I need?
0
 
LVL 15

Expert Comment

by:deighc
ID: 10675595
What I would do is created a basic XML "template" that forms the basis of the XML you have to send to UPS. This can be saved as an .xml file on the filesystem. You can then load this document into an XML DOM, programatically created the dynamic information required for each shopping cart, send this XML using XMLHTTP, then load the response into a new XML DOM and parse the response.

I can't provide you a full answer to your problem because I don't the format of either the document you have to send to UPS or the format of the XML they return to you.
0
 

Author Comment

by:poshlivin
ID: 10677385
This is the technical ref provided in the documentation:

********
Every request containing a message body should include a Content-type header, exmple :
Request: POST /toolname/1.0
(Example: POST /register HTTP/1.0)
Content-Type: application/x-www-form-urlencoded
Content-Length: 273
<?xml version="1.0" encoding="UTF-8"?>

The message body contains the information to be processed by a tool. The message must be XPCI-
compliant.
********

Q : I have to put in the content length, how do I calculate that?

Further in the doc.
************
Each transaction is made up of two separate XML request documents. These requests are concatenated and
posted to the UPS web servers using a single HTTP Post. This is a sample request file:

<?xml version="1.0"?>
<AccessRequest xml:lang="en-US">
<AccessLicenseNumber>TEST262223144CAT</AccessLicenseNumber>
<UserId>REG111111</UserId>
<Password>REG111111</Password>
</AccessRequest>

<?xml version="1.0"?>
<RatingServiceSelectionRequest xml:lang="en-US">
<Request>
<TransactionReference>
<CustomerContext>Bare Bones Rate Request</CustomerContext>
<XpciVersion>1.0001</XpciVersion>
</TransactionReference>
<RequestAction>Rate</RequestAction>
<RequestOption>Rate</RequestOption>
</Request>
<Shipment>
<Shipper>
<Address>
<PostalCode>44129</PostalCode>
<CountryCode>US</CountryCode>
</Address>
</Shipper>
</Shipment>
.............. other nodes here
</RatingServiceSelectionRequest>

The Response File looks something like this:
<?xml version="1.0" encoding="UTF-8"?>
<RatingServiceSelectionResponse>
<Response>
<TransactionReference>
<CustomerContext>Bare Bones Rate Request</CustomerContext>
<XpciVersion>1.0001</XpciVersion>
</TransactionReference>
<ResponseStatusCode>1</ResponseStatusCode>
<ResponseStatusDescription>Success</ResponseStatusDescription>
</Response>
<RatedShipment>
.......other nodes here
<RatedPackage>
<TransportationCharges>
<CurrencyCode>USD</CurrencyCode>
<MonetaryValue>108.61</MonetaryValue>
</TransportationCharges>
<ServiceOptionsCharges>
<CurrencyCode>USD</CurrencyCode>
<MonetaryValue>0.00</MonetaryValue>
</ServiceOptionsCharges>
<TotalCharges>
<CurrencyCode>USD</CurrencyCode>
<MonetaryValue>108.61</MonetaryValue>
</TotalCharges>
</RatedPackage>
</RatedShipment>

*************

Based on this I will have to create an XML template. Within the template, do I just leave the values blank?
Also, could you give the code to dynamically generate the XML file from the template?
Plus how I should make a call to the UPS server, and extract info from that.

Thanks a whole bunch
0
 
LVL 15

Accepted Solution

by:
deighc earned 450 total points
ID: 10677609
> Based on this I will have to create an XML template. Within the template, do I just leave the values blank?

Yes. Leave them blank then set them programatically using an XML DOM object. I don't know exactly which information you need to provide but you should be able to get the idea from my code.

<%
dim xmlDOM, xmlHTTP

set xmlDOM = Server.CreateObject("MSXML2.DOMDocument")
xmlDOM.async = false
if xmlDOM.load("<full path to your xml template here>")
    ' Now you have to fill in the values in the template.
    ' You have to select the node then set it's text property. Specify the full path to the node from the root (RatingServiceSelectionRequest)
    xmlDOM.selectSingleNode("/RatingServiceSelectionRequest/Shipment/Shipper/Address/PostalCode").text = <set the value you want here>
    .... set as many node values as you need to....
    ' Now create an XML HTTP object to post the document to UPS
    set xmlHTTP = Server.CreateObject("Msxml2.XMLHTTP")
    xmlHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
    xmlHTTP.setRequestHeader "Content-Length", LenB(xmlDOM.xml)
    xmlHTTP.Open "POST", <url of UPS server>, false
    ' Send the text of the xml DOM as part of the request body
    xmlHTTP.Send xmlDOM.xml
    ' You can now access the XML generated by the UPS system by using responseText property of the xmlHTTP object.
    ' Load this into the XML DOM using the loadXML method (this ovewrites the previous data in the XML DOM)
    if xmlDOM.loadXML(xmlHTTP.responseText) then
         ' Now you have the UPS XML loaded into your DOM
         .... parse whatever information you want from the DOM here....
    else
         ' There was a request problem or a parse error in the UPS XML
    end if
    set xmlHTTP = nothing
else
    ' Error loading XML template
end if
set xmlDOM = nothing
%>
0
 

Author Comment

by:poshlivin
ID: 10677654
Thanks....
I am going to customise the code you gave and post the results
0
 

Author Comment

by:poshlivin
ID: 10677701
One more question. I have to send the AccessRequest info as an XML file as well (as mentioned in my previous post).
> Each transaction is made up of two separate XML request documents. These requests are concatenated and
posted to the UPS web servers using a single HTTP Post.

I know I'm asking too much, but how would I send info from 2 XML files using a single HTTP Post?

Thanks
0
 
LVL 15

Expert Comment

by:deighc
ID: 10677836
I assume that by "concatenated" they mean simply one after the other???

In that case load both XML documents into seperate XML DOM objects.
Then use the following code to post them (say your DOM objects are called xmlDOM1 and xmlDOM2):

set xmlHTTP = Server.CreateObject("Msxml2.XMLHTTP")
xmlHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
xmlHTTP.setRequestHeader "Content-Length", LenB(xmlDOM1.xml & xmlDOM2.xml)
xmlHTTP.Open "POST", <url of UPS server>, false
' Send the text of the xml DOM as part of the request body
xmlHTTP.Send xmlDOM1.xml & xmlDOM2.xml
   
0
 

Author Comment

by:poshlivin
ID: 10683452
For testing purposes, I created 2 fixed XMLfiles with static data.
I susbstituted the UPS URL and other stuff in the code you had given.
Since I needed to load 2 files in the xmlDOM and xml2DOM variables, this is the line of code I used

********
if xmlDOM.load("UPSRateRequest.xml") AND xmlDOM2.load("UPSLicenseInfo.xml") then
' other code to send the xml to the URL and get the response
end if
********

But this gives me an "error loading xml files" error.

(I tried loading just one xml document to run the code, but that gave the same error.

The XML files I am loading are in the same directory as this asp page, so I wonder why it couldn't find them?! What did I do wrong?

0
 
LVL 15

Expert Comment

by:deighc
ID: 10685716
The load method requires a full path to the files.

Something like: c:\wwwroot\inetpub\myweb\myfolder\UPSRateRequest.xml

You can use Server.Mappath to map a relative path to a full file path.

Depending on where your XML files are relative to the .asp file, it'll be something like this:

********
if xmlDOM.load(Server.Mappath("UPSRateRequest.xml")) AND xmlDOM2.load(Server.Mappth("UPSLicenseInfo.xml")) then
' other code to send the xml to the URL and get the response
end if
********

This assumes that the XML docuements and the .asp file are in the same directory. If they're not then you have to use a relative path(eg. "../../<file name>", "/<file name>" etc)
0
 
LVL 46

Expert Comment

by:fritz_the_blank
ID: 10686773
Hello all:

The reason that I have stopped participating in this thread is because I am a little green in working with XML, and deighc has things well in hand. If I tried to contribute here, I would just confuse things.

Listening and learning,

FtB
0
 

Author Comment

by:poshlivin
ID: 10687804
I have been so dumb.... I just didin't realise that I could use Sever.Mappath. Thanks so much.
But....now I get this error:

msxml3.dll error '80004005'

Unspecified error

/UPS_trial.asp, line 22

and line 22 is
xmlHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"

Help....
0
 
LVL 46

Expert Comment

by:fritz_the_blank
ID: 10687897
That error translates roughly as the file does not exist, or it exists but you do not have sufficient permissions. Does the IUSR account have access to the necessary directories?

FtB
0
 

Author Comment

by:poshlivin
ID: 10687960
The XML file is present there. We have the line

if load xmlDOM.load(Server.Mappath("file.xml")......then
   set xmlHTTP = Server.CreateObject("Msxml2.XMLHTTP")
   xmlHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
   ' send and receive data here
else
  Response.Write "file can't be loaded"
end if

This means that it found the file and loaded it as well, right? When it gets to the setRequestHeader method, that's where it gives the error.

Both the XML files and the asp file to send the XML files reside in the same folder as well. So I don't have to access another directiry.
0
 
LVL 15

Expert Comment

by:deighc
ID: 10687969
I think I made a stupid mistake. With XMLHTTP you must call the Open method first then call setRequestHeader.

So:

xmlHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
xmlHTTP.setRequestHeader "Content-Length", LenB(xmlDOM.xml)
xmlHTTP.Open "POST", <url of UPS server>, false

should actually be:

xmlHTTP.Open "POST", <url of UPS server>, false
xmlHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
xmlHTTP.setRequestHeader "Content-Length", LenB(xmlDOM.xml)
   
0
 

Author Comment

by:poshlivin
ID: 10688101
Bingo! It returns a document!

One last question (I know you are probably fed up of me now....)

This is th error I get when I try to read a particular node from the XMLHTTP object
*******
Returned VALUE (to indicate that send and receive was successful)

Microsoft VBScript runtime error '800a01a8'

Object required: '[object]'

/UPS_trial.asp, line 25
****
I am using

Response.Write xmlDOM.selectSingleNode("/RatingServiceSelectionResponse/RatedShipment/TotalCharges/MonetaryValue").text

to display the value of shipment (I have the full path to the node correct).

0
 
LVL 15

Expert Comment

by:deighc
ID: 10688243
I'm not 100% sure I know what you mean, but it sounds like you're trying to access a node directly from the XMLHTTP object. You can't do this - the XMLHTTP object is not the same thing as an XML DOM object.

You have two options:

1) You can do something similar to what I showed in my code example. ie. load the responseText of the XMLHTTP object into an XML DOM:

     if xmlDOM.loadXML(xmlHTTP.responseText) then
       ' responseText from XMLHTTP loaded OK
       ' ** Now you access nodes from xmlDOM ** eg.
       xmlDOM.selectSingle("/RatingServiceSelectionResponse/RatedShipment/RatedPackage/TransportationCharges/MonetaryValue").text
     else
        ' something wrong with UPS XML
     end if

2) You can access the responseXML property of the XMLHTTP object. This IS an XML DOM (ie. it's an object property of the XMLHTTP object), so you can access nodes from it directly. eg

    xmlHTTP.responseXML.selectSingle("/RatingServiceSelectionResponse/RatedShipment/RatedPackage/TransportationCharges/MonetaryValue").text
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 15

Expert Comment

by:deighc
ID: 10688248
Oops.. small typo in my examples.

Where I use the keyword "selectSingle" I should've used "selectSingleNode".
0
 

Author Comment

by:poshlivin
ID: 10688327
I am sorry...I had placed the "returns value" in the else part.

The problem is with the UPS XML.
I have to contact them before I can close this question.

Thanks a lot though
0
 

Author Comment

by:poshlivin
ID: 10717751
After 3 days of back and forth with UPS, they said that the static XML was alright and they received a response from the CIE. Further, they added, "It appears as you stated that the Rate Request is successful, but your application is not properly returning the response from the server."

For connecting and messaging...
.....
4. Receive the XML response message from the tool.  To read a response from a  tool, an application reads the response in XML format via a secure TCP/IP socket or secure URL connection.
5. Parse the XML response message to retrieve data.
...........


I am sending the request and response over a secure URL connection, but I still get error with UPS file.
Please help!
0
 

Author Comment

by:poshlivin
ID: 10717950
Just to make sure I am doing the right thing....here are excerpts from the documentation:

"Each transaction is made up of two separate XML request documents. These requests are concatenated and
posted to the UPS web servers using a single HTTP Post.
When validating the request XML documents, do not treat the two concatenated documents as a single XML
document. XML parsers can not parse two concatenated documents. Validate each XML Request separately.
UPS will separate the two documents and parse them individually. To ensure this occurs, verify that          
<?xml version="1.0"?> is at the top of each XML request document."

And....
Request Line
The request line comprises the following three elements:
• Method
• Request-URL
• HTTP-version, and ending with carriage-return-line-feed (CRLF) string

Request Line Elements:
Header Fields
Header fields provide general information about a request.
Empty Line
After the necessary headers are added to the request, an empty line must be added to indicate the end of
the header fields and the start of the message body, if there is one.
Message Body
The message body contains the information to be processed by a tool. The message must be XPCI-
compliant.

HTTP Request Example
Request: POST /toolname/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 273
<?xml version="1.0" encoding="UTF-8"?>LF...
Within the request line, each element is separated by a blank space (SP). No CRs or LFs are allowed,
except in the final CRLF sequence. The structure of the request line is shown below, followed by an
example.
Request Line = Method SP Request-URL SP HTTP-version CRLF
Example: POST /register HTTP/1.0

***********

Based on this documentation, is my ASP code correct?
(The XML files are valid - as per UPS feedback)
0
 
LVL 15

Expert Comment

by:deighc
ID: 10722934
> Based on this documentation, is my ASP code correct?

I would say "almost". I guessed that they wanted both XML documents concatenated together into a single string and sent in one post. This is what you're doing. But note this line:

> No CRs or LFs are allowed

This could be your problem. It's very likely that your XML documents will have line breaks in it. This is easy to fix.

In place of this line:

xmlHTTP.Send xmlDOM1.xml & xmlDOM2.xml

Use something like:

xmlHTTP.Send replace(replace(replace(xmlDOM1.xml & xmlDOM2.xml, vbcrlf, ""), vblf, ""), vbcr, "")

This replaces all line breaks with empty space.

But I don't know what this means:

> The message must be XPCI-compliant.

Any ideas??
0
 

Author Comment

by:poshlivin
ID: 10724172
Nope...I still get the error :'(

From what the documentation says, isn't it the header line that has no CR or LF's?
Because, when I sent the files to UPS, they just posted those and got the answer - so I presume that my XML files might be good....

> The message must be XPCI-compliant.
(From the documentation, here is what it means)

XML Package Carrier Interface (XPCI) defines a vocabulary and structure for describing packages, shipments,
and the activity details for package carriers and their customers. XPCI is a set of DTDs that defines the
terminology, transaction enveloping, and XML message definitions. For a client to be XPCI-compliant, the client
must generate a well-formed XML message that validates against the XPCI DTDs.
UPS OnLine Tools demand as a pre-condition that all messages be XPCI-compliant. This means that each
message must validate against its corresponding DTD, however, the XML message itself should not contain a
DOCTYPE. UPS OnLine Tools do not use the XML DOCTYPE reference.
0
 

Author Comment

by:poshlivin
ID: 10724191
>After the necessary headers are added to the request, an empty line must be added to indicate the end of
the header fields and the start of the message body, if there is one.

Does that mean anything else?
0
 

Author Comment

by:poshlivin
ID: 10724205
Since I run this page from a secure server, I get this error:

Error Type:
msxml3.dll (0x80004005)
Unspecified error
/UPSgetRate.asp, line 32

and line 32 is :
 if xmlDOM.loadXML(xmlHTTP.responseText) then

0
 
LVL 15

Expert Comment

by:deighc
ID: 10724278
>After the necessary headers are added to the request, an empty line must
> be added to indicate the end of the header fields and the start of the
> message body, if there is one.

I don't really understand what that means. You'll probably need to contact UPS to clarify things. Try and get an CLEAR and EXACT description of how to format the string that you send them

I have to say that UPS's interface is very weird. You send two documents at once (meaning you're no longer sending well formed XML) and they require you to format it precisely as they specify it. And they ask that your XML validates against their DTD but their tool chokes if you include a DOCTYPE declaration. WTF?!?!?

> Since I run this page from a secure server, I get this error...

Weird. It should work in exactly the same way.
0
 

Author Comment

by:poshlivin
ID: 10724390
This is what they had to suggest when they told me that my xML was good:

>It may be helpful for you to use a "sniffer" application where you can
capture exactly what is being posted by your application---this will confirm
that what you are sending is actually being received.

I am in no-man's land right now!

Bad enough XML was a nightmare....now whatever ASP I had command over seems to be slipping out of my hands too !

I am raising the points here - more for deighc's effort than my own.
0
 
LVL 15

Expert Comment

by:deighc
ID: 10724406
You don't really need a sniffer application. Just Response.Write the XML string that you send them, then view the page source and you'll see the XML string there.
0
 

Author Comment

by:poshlivin
ID: 10726669
My file is ok.

I was just wondering, the documentation says:
The request line comprises the following three elements:
• Method
• Request-URL
• HTTP-version, and ending with carriage-return-line-feed (CRLF) string

Do I need to add
xmlHTTP.setRequestHeader "Request", "POST /Rate HTTP/1.0"
to my code?

And mainly, it says
>Empty Line
After the necessary headers are added to the request, an empty line must be added to indicate the end of
the header fields and the start of the message body, if there is one.

When we do :
*****
xmlHTTP.Open "POST", "https://wwwcie.ups.com/ups.app/XML/Rate" , false
xmlHTTP.setRequestHeader "Request", "POST /Rate HTTP/1.0"
xmlHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
nLength = LenB(xmlDOM.xml) + LenB(xmlDOM2.xml)      
xmlHTTP.setRequestHeader "Content-Length", nLength      
      
' send the xml files in one post command
xmlHTTP.Send replace(replace(replace(xmlDOM.xml & xmlDOM2.xml, vbcrlf, ""), vblf, ""), vbcr, "")
*****

Do we add that empty line?
I am so stressed out by reading the documentation over nad over again that every line seems to be confuding me :(

Thanks so much for the patience and your responses!
0
 

Author Comment

by:poshlivin
ID: 10728182
THE PROBLEM HAS BEEN SOLVED!!!!!!!

I had to remove the line breaks in the actual XML page. Just replace() didn't do the work for me.

I now get the exact result I want.

50 points got to Fritz_the_blank for rsponding to my answer so soon, and partially with the correct answer of course.
The remaining 450 go to deighc for helping me out all the way from nowhere to result-land :)
Truly, the patience, feedback, response (and code of course) is highly appreciated.
0
 

Expert Comment

by:crudmop
ID: 10901128
Posh - any chance you can post up the final result code from all of this?  I am in the midst of doing a similar project, and would really appreciate seeing the end-result to this one, as I am having similar issues (and an xml newb).  thanks !
0
 

Author Comment

by:poshlivin
ID: 10921670
Here's the XML file : (It has to be without any line breaks)
It has certain nodes whose values are fixed, and some are dynamic. So basically, this is a template
**********
<?xml version="1.0"?><RatingServiceSelectionRequest xml:lang="en-US"><Request><TransactionReference><CustomerContext>XYZ Rate Request</CustomerContext><XpciVersion>1.0001</XpciVersion></TransactionReference><RequestAction>Rate</RequestAction><RequestOption>Rate</RequestOption></Request><PickupType><Code>01</Code></PickupType><Shipment><Shipper><Address><PostalCode>12345</PostalCode><CountryCode>US</CountryCode></Address></Shipper><ShipTo><Address><PostalCode>11218</PostalCode><CountryCode>US</CountryCode></Address>UPS ONLINE TOOLS</ShipTo><ShipFrom><Address><PostalCode>12345</PostalCode><CountryCode>US</CountryCode></Address></ShipFrom><ShipmentWeight><UnitOfMeasurement><Code>LBS</Code></UnitOfMeasurement><Weight>400</Weight></ShipmentWeight><Service><Code></Code></Service><Package><PackagingType><Code>02</Code></PackagingType><Dimensions><UnitOfMeasurement><Code>IN</Code></UnitOfMeasurement><Length>20</Length><Width>20</Width><Height>20</Height></Dimensions><PackageWeight><UnitOfMeasurement><Code>LBS</Code></UnitOfMeasurement><Weight
></Weight></PackageWeight></Package></Shipment></RatingServiceSelectionRequest>
************

The ASP code to fill in the empty nodes, make the call and decode the message
************
<%@ Language=VBScript %>
<% Option Explicit %>
<!--#include file="connection.asp" -->

<%
'ALLOW PAGE NOT TO BE CACHED
Response.Clear
Response.CacheControl = "no-store"
Response.AddHeader "Pragma", "no-cache"
Response.Expires = -1
%>

<%
dim xmlDOM, xmlHTTP, xmlDOM2, nLength, nShipCode, strShip

      set xmlDOM = Server.CreateObject("MSXML2.DOMDocument")
      set xmlDOM2 = Server.CreateObject("MSXML2.DOMDocument")

      xmlDOM.async = false
      xmlDOM2.async = false

      if xmlDOM.load(Server.Mappath("UPSLicenseInfo.xml")) AND xmlDOM2.load(Server.Mappath("UPSRateRequest.xml")) then      

            ' set as many node values as you need to....
            xmlDOM2.selectSingleNode("/RatingServiceSelectionRequest/Shipment/Shipper/Address/PostalCode").text = "12345"
            
            ' based on type of mailing selected, assign a ship code
            If strShip = "UPS Standard Overnight" THEN
                  nShipCode = "01"
            ELSEIF strShip = "UPS 3 Day Service" THEN
                  nShipCode = "12"
            ELSE
                  nShipCode = "03"
            END IF
            
            xmlDOM2.selectSingleNode("/RatingServiceSelectionRequest/Shipment/Service/Code").text = nShipCode
                  
            
               set xmlHTTP = Server.CreateObject("MSXML2.XMLHTTP")
            xmlHTTP.Open "POST", "https://www.ups.com/ups.app/xml/Rate" , false      
            ' set the headers
            xmlHTTP.setRequestHeader "Request", "POST /Rate HTTP/1.0"
          xmlHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
            ' set the length
            nLength = LenB(xmlDOM.xml) + LenB(xmlDOM2.xml)      
          xmlHTTP.setRequestHeader "Content-Length", nLength      
            ' send the xml files in one post command
          xmlHTTP.Send xmlDOM.xml & xmlDOM2.xml      
          
              if xmlDOM.loadXML(xmlHTTP.responseText) then
             ' responseText from XMLHTTP loaded OK      
               
             IF xmlDOM.selectSingleNode("/RatingServiceSelectionResponse/Response/ResponseStatusDescription").text = "Success" THEN
                     Response.Write "At " & Now & " Your price is : <br> "
                     Response.Write xmlDOM.selectSingleNode("/RatingServiceSelectionResponse/RatedShipment/RatedPackage/TotalCharges/MonetaryValue").text
                   Response.Write xmlDOM.selectSingleNode("/RatingServiceSelectionResponse/RatedShipment/RatedPackage/TotalCharges/CurrencyCode").text
                  ELSE    
                        'xml request was sent, but resulted in a failure
                        Response.Write xmlDOM.selectSingleNode("/RatingServiceSelectionResponse/Response/ResponseStatusDescription").text       
               END IF
           else
              ' something wrong with UPS XML
                  Response.Write "ERROR with UPS XML"            
           end if
      
          set xmlHTTP = nothing
      else
            Response.Write "Error loading document"
      end if
      set xmlDOM = nothing
      set xmlDom2 = nothing
      
%>
************
0
 

Expert Comment

by:hidebumik
ID: 10926040
Hello,
I am learning XML and ASP and am also want to build a XML Shopping cart.
I would like to see the whole completed code for learning purpose.
If you could post the wholse code, I would really appreciate it.

Thanks,
Hide
0
 

Expert Comment

by:crudmop
ID: 10932040
Posh - thanks for posting that up, I really appreciate it.

It's similar to what I have - very strange, the UPS response is not always 100%, and the trouble I was having seems to have fixed itself lol.

Next question - working off of similar code, I am tying in the tracking XML page into the system.
Working off of similar code to yours, I need to display out the activity status returned in the response.

The demo response is as follows:

<TrackResponse>
      <Shipment>
            <ShipmentIdentificationNumber>1Z12345E1512345676</ShipmentIdentificationNumber>
            <PickupDate>20010219</PickupDate>
            <ScheduledDeliveryDate>20010220</ScheduledDeliveryDate>
            <Package>
                  <TrackingNumber>1Z12345E1512345676</TrackingNumber>
                  <Activity>
                        <ActivityLocation>
                              <Address>
                                    <City>ROSWELL-ROSWELL</City>
                                    <StateProvinceCode>GA</StateProvinceCode>
                                    <CountryCode>US</CountryCode>
                              </Address>
                              <Code>M5</Code>
                              <Description>MAIL ROOM</Description>
                              <SignedForByName>DOE</SignedForByName>
                        </ActivityLocation>
                        <Status>
                              <StatusType>
                                    <Code>D</Code>
                                    <Description>DELIVERED</Description>
                              </StatusType>
                              <StatusCode>
                                    <Code>KB</Code>
                              </StatusCode>
                        </Status>
                        <Date>20010221</Date>
                        <Time>090600</Time>
                  </Activity>
            </package>
      </shipment>
</TrackResponse>

Pulling the individual elemtents such as Sched Delivery Date, etc is simple.  The issue I am having is displaying the nodes in succession for the multiple Activity Nodes (looping through like a recordset)
I am trying display these elements in order, which I can later format.  However, I am getting errors when attempting to edit the code to fit into my existing output.
The important stuff:

if xmlDOM.loadXML(xmlHTTP.responseText) then

XMLNodeList = xmlDOM.getElementsByTagName("Activity")
        iActivities = XMLNodeList.length
        If iActivities > 0 Then
            For iNodeCounter = 0 To iActivities - 1
                XMLNode = XMLNodeList(iNodeCounter).selectSingleNode("Status")
                XMLNode = XMLNode.selectSingleNode("StatusType")
                XMLElement = XMLNode.selectSingleNode("Code")
                CurrentDeliveryStatus.Status = XMLElement.text
                If CurrentDeliveryStatus.Status = "D" Then
                    'if the status code is delivered then get the signed for by name
                    XMLNode = XMLNodeList(iNodeCounter).selectSingleNode("ActivityLocation")
                    XMLElement = XMLNode.selectSingleNode("SignedForByName")
                    On Error Resume Next
                    CurrentDeliveryStatus.SignedForByName = XMLElement.text


                    'if the status code is delivered then get the date and time of the current activity
                    XMLElement = XMLNodeList(iNodeCounter).selectSingleNode("Date")
                    TempDate = XMLElement.text
                    XMLElement = XMLNodeList(iNodeCounter).selectSingleNode("Time")
                    TempTime = XMLElement.text

                    If Len(TempDate) = 8 And Len(TempTime) = 6 Then
                        TempDate = Mid(TempDate, 5, 2) & "/" & Mid(TempDate, 7, 2) & "/" & Mid(TempDate, 1, 4)
                        TempTime = Mid(TempTime, 1, 2) & ":" & Mid(TempTime, 3, 2) & ":" & Mid(TempTime, 5, 2)
                        CurrentDeliveryStatus.DateTime = CDate(TempDate & " " & TempTime).ToString
                    End If


                End If
            Next
        End If
    else
         'We have a problem
    end if



The error I am getting is:  Wrong number of arguments or invalid property assignment: 'XMLNodeList'

Man, it really sucks when you find yourself a totally green newb and can't find any way to fix it on your own :(

Any help would be greatly appreciated
0
 

Expert Comment

by:crudmop
ID: 10932568
Well, I decided to keep playing and I have a better version now, which functions pretty much - however, I get an error at the end which I think is caused by it looping beyond the correct level of nodes.

For what it's worth, this will grab the data necessary for some simple tracking display.  Add nodes as you need.

            set xmldoc = xmlHTTP.responseXML
            set CurrentDeliveryStatus = Nothing
            Dim XMLNodeList
            Dim XMLNode
            Dim XMLElement
                  
            Dim iActivities
        Dim TempDate
        Dim TempTime
        Dim iNodeCounter
         
        'Get Status code
        set XMLNodeList = xmldoc.getElementsByTagName("Activity")

            iActivities = XMLNodeList.length                                                        
        If iActivities > 0 Then        
         
            For iNodeCounter = 0 To iActivities -1
                set XMLNode = XMLNodeList(iNodeCounter).selectSingleNode("Status")
                set XMLNode = XMLNode.selectSingleNode("StatusType")
                set XMLElement = XMLNode.selectSingleNode("Code")
                trackStatus = XMLElement.text
                If trackStatus = "D" Then
                    'if the status code is delivered then get the signed for by name
                    set XMLNode = XMLNodeList(iNodeCounter).selectSingleNode("ActivityLocation")
                    set XMLElement = XMLNode.selectSingleNode("SignedForByName")                
                    trackSignedForByName = XMLElement.text                        
                    'if the status code is delivered then get the date and time of the current activity
                    set XMLElement = XMLNodeList(iNodeCounter).selectSingleNode("Date")
                    TempDate = XMLElement.text
                    set XMLElement = XMLNodeList(iNodeCounter).selectSingleNode("Time")
                    TempTime = XMLElement.text
                    If Len(TempDate) = 8 And Len(TempTime) = 6 Then
                        TempDate = Mid(TempDate, 5, 2) & "/" & Mid(TempDate, 7, 2) & "/" & Mid(TempDate, 1, 4)
                        TempTime = Mid(TempTime, 1, 2) & ":" & Mid(TempTime, 3, 2) & ":" & Mid(TempTime, 5, 2)
                        trackDateTime = (TempDate & " " & TempTime)
                    End If
                        ELSE
                              set XMLNode = XMLNodeList(iNodeCounter).selectSingleNode("ActivityLocation")
                              set XMLNode = XMLNode.selectSingleNode("Address")
                                    Set XMLElement = XMLNode.selectSingleNode("City")
                                          city=XMLElement.text
                                    Set XMLElement = XMLNode.selectSingleNode("StateProvinceCode")
                                          state=XMLElement.text
                                    Set XMLElement = XMLNode.selectSingleNode("CountryCode")
                                          country=XMLElement.text
                              set XMLNode = XMLNodeList(iNodeCounter).selectSingleNode("Status")
                              set XMLNode = XMLNode.selectSingleNode("StatusType")
                              set XMLElement=XMLNode.selectSingleNode("Description")
                                    status=XMLElement.text
                              set XMLElement = XMLNodeList(iNodeCounter).selectSingleNode("Date")
                    TempDate = XMLElement.text
                    set XMLElement = XMLNodeList(iNodeCounter).selectSingleNode("Time")
                    TempTime = XMLElement.text            
                              TempDate = Mid(TempDate, 5, 2) & "/" & Mid(TempDate, 7, 2) & "/" & Mid(TempDate, 1, 4)
                              TempTime = Mid(TempTime, 1, 2) & ":" & Mid(TempTime, 3, 2) & ":" & Mid(TempTime, 5, 2)
                    trackDateTime = (TempDate & " " & TempTime)      
                              
                              'temp display to see the data - change this here for formatting
                              response.write city & ",&nbsp;" & state & " " & country & " : " & status & " : " & trackdatetime & "<BR>"
                End If
            Next
       End If
0
 

Author Comment

by:poshlivin
ID: 10948968
crudmop,

I would seriously suggest you put your issue up as a new question, with the appropriate points.

Being an XML newbie myself, and lots of other work at hand, I might not be able to respond to your questions as quickly as one of the experts would.

Sorry, but that's your best bet.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

I will show you how to create a ASP.NET Captcha control without using any HTTP HANDELRS or what so ever. you can easily plug it into your web pages. For Example a = 2 + 3 (where 2 and 3 are 2 random numbers) Session("Answer") = 5 then we…
What is Node.js? Node.js is a server side scripting language much like PHP or ASP but is used to implement the complete package of HTTP webserver and application framework. The difference is that Node.js’s execution engine is asynchronous and event…
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now