Link to home
Start Free TrialLog in
Avatar of electricd7
electricd7

asked on

Using ServerXMLHTTP to integrate UPS Shipping API with ASP site. Can't parse 2 XML docs concatenated which is required by UPS.

OK this is a very specific and lengthy question, so please bear with me.  I am trying to integrate the UPS shipping API with my website (not the rates one, the shipping one you have to actually register for).  The problem is that in order to use the API, UPS requires you to send 2 separate XML documents concatenated together to thier API which they separate and then send back a response to.  I am unable to do this using ServerXMLHTTP and Msxml2.DOMDocument.  Below is the string which I am sending to UPS:

<?xml version="1.0"?>
  <AccessRequest xml:lang="en-US">
   <AccessLicenseNumber><![CDATA[mylicensenumber]]></AccessLicenseNumber>
   <UserId><![CDATA[myuserid]]></UserId>
   <Password><![CDATA[mypassword]]></Password>
  </AccessRequest>
<?xml version="1.0"?>
<ShipmentConfirmRequest xml:lang="en-US">
<Request>
<TransactionReference>
<CustomerContext>ShipConfirmUS</CustomerContext>
<XpciVersion>1.0001</XpciVersion>
</TransactionReference>
<RequestAction>ShipConfirm</RequestAction>
<RequestOption>nonvalidate</RequestOption>
</Request>
<LabelSpecification>
<LabelPrintMethod>
<Code>EPL</Code>
</LabelPrintMethod>
<LabelStockSize>
<Height>4</Height>
<Width>6</Width>
</LabelStockSize>
</LabelSpecification>
<Shipment>
<Shipper>
<Name>ShipperName</Name>
<AttentionName>ShipperAttnName</AttentionName>
<PhoneNumber>
<StructuredPhoneNumber>
<PhoneDialPlanNumber>222626</PhoneDialPlanNumber>
<PhoneLineNumber>7227</PhoneLineNumber>
<PhoneExtension>929</PhoneExtension>
</StructuredPhoneNumber>
</PhoneNumber>
<ShipperNumber>12345E</ShipperNumber>
<Address>
<AddressLine1>22 USShipperAddr1</AddressLine1>
<AddressLine2>USShipperAddr2</AddressLine2>
<AddressLine3>USShipperAddr3</AddressLine3>
<City>Plano</City>
<StateProvinceCode>TX</StateProvinceCode>
<PostalCode>75093</PostalCode>
<CountryCode>US</CountryCode>
</Address>
</Shipper>
<ShipTo>
<CompanyName>ShipToCompanyName</CompanyName>
<AttentionName>ShipToAttnName</AttentionName>
<PhoneNumber>
<StructuredPhoneNumber>
<PhoneDialPlanNumber>333656</PhoneDialPlanNumber>
<PhoneLineNumber>7337</PhoneLineNumber>
<PhoneExtension>9339</PhoneExtension>
</StructuredPhoneNumber>
</PhoneNumber>
<Address>
<AddressLine1>33 ShipToAddr1</AddressLine1>
<AddressLine2>USShipToAddr2</AddressLine2>
<AddressLine3>USShipToAddr3</AddressLine3>
<City>Atlanta</City>
<StateProvinceCode>GA</StateProvinceCode>
<PostalCode>30346</PostalCode>
<CountryCode>US</CountryCode>
<ResidentialAddress/>
</Address>
</ShipTo>
<ShipFrom>
<CompanyName>ShipFromCompanyName</CompanyName>
<AttentionName>ShipFromAttnName</AttentionName>
<PhoneNumber>
<StructuredPhoneNumber>
<PhoneDialPlanNumber>111616</PhoneDialPlanNumber>
<PhoneLineNumber>7117</PhoneLineNumber>
<PhoneExtension>9119</PhoneExtension>
</StructuredPhoneNumber>
</PhoneNumber>
<Address>
<AddressLine1>22 ShipFromAddr1 St</AddressLine1>
<AddressLine2>USShipFromAddr2</AddressLine2>
<AddressLine3>USShipFromAddr3</AddressLine3>
<City>Athens</City>
<StateProvinceCode>GA</StateProvinceCode>
<PostalCode>30605</PostalCode>
<CountryCode>US</CountryCode>
</Address>
</ShipFrom>
<PaymentInformation>
<Prepaid>
<BillShipper>
<AccountNumber>12345E</AccountNumber>
</BillShipper>
</Prepaid>
</PaymentInformation>
<Service>
<Code>01</Code>
</Service>
<ShipmentServiceOptions>
<Notification>
<EMailMessage>
<EMailAddress>christy@company1.com</EMailAddress>
<Memo>EmailShipNot Memo</Memo>
</EMailMessage>
</Notification>
<Notification>
<EMailMessage>
<EMailAddress>joe@company2.com</EMailAddress>
UPS ONLINE TOOLS
<NotificationCode>6</NotificationCode>
</EMailMessage>
</ShipmentNotification>
</ShipmentServiceOptions>
<Package>
<PackagingType>
<Code>03</Code>
</PackagingType>
<PackageWeight>
<UnitOfMeasurement>
<Code>LBS</Code>
</UnitOfMeasurement>
<Weight>2</Weight>
</PackageWeight>
</Package>
<Package>
<PackagingType>
<Code>02</Code>
</PackagingType>
<ReferenceNumber>
<Code>9V</Code>
<Value>abcdefg</Value>
</ReferenceNumber>
<PackageWeight>
<UnitOfMeasurement>
<Code>LBS</Code>
</UnitOfMeasurement>
<Weight>2</Weight>
</PackageWeight>
<PackageServiceOptions>
<COD>
<CODFundsCode>8</CODFundsCode>
<CODCode>3</CODCode>
<CODAmount>
<CurrencyCode>USD</CurrencyCode>
<MonetaryValue>35000</MonetaryValue>
</CODAmount>
</COD>
<InsuredValue>
<CurrencyCode>USD</CurrencyCode>
<MonetaryValue>500.55</MonetaryValue>
</InsuredValue>
</PackageServiceOptions>
</Package>
</Shipment>
</ShipmentConfirmRequest>

I have confirmed this string to be in the correct format for the API.  The page I am using to send the request, and parse the results is as follows (sxml =  string from above):

<%@ LANGUAGE="VBScript" %>
<!--#INCLUDE FILE="Media/commonfunctions.asp"-->
<!--#INCLUDE FILE="Media/UPSFunctions.asp"-->
<%'Option Explicit
      Response.Buffer = true
      Response.ContentType = "text/xml"
      Response.Charset = "iso-8859-1"
      Response.Expires=0
      Response.AddHeader "pragma", "nocache"

'we make API calls using the ServerXMLHTTP object
Dim oXMLHTTP
'we make the actual request by sending a DOM Document
Dim oXMLDoc
'used in parsing example
Dim sOutput
Dim oNode

'Check call type and get appropriate XML
sXML = UPSRequest

'create the objects
Set oHTTPConn = Server.CreateObject("Msxml2.ServerXMLHTTP.3.0")
'the DOM Document to load the request into and send
Set oXMLDoc = Server.CreateObject("Msxml2.DOMDocument.3.0")

'we are going to do a synchronous call and wait for the response
oHTTPConn.open "POST", Application("ShipConfirmURL"), False
'set the HTTP headers
oHTTPConn.setRequestHeader "Content-Type", "text/xml"

response.write sXML
'load the DOM Document synchronously
oXMLDoc.async = False
If (Not oXMLDoc.loadXML(sXML) Or (oXMLDoc.parseError.errorCode <> 0)) Then
      'sanity check on the request BEFORE the request has been made.
    'see the IXMLDOMParseError Members documentation for parseError
    'properties if you want to capture more information
      Response.write "<?xml version=""1.0"" encoding=""iso-8859-1""?><Error><Code>" & oXMLDoc.parseError.errorCode
      Response.write "</Code><LineNumber>" & oXMLDoc.parseError.line & "</LineNumber>"
      Response.write "<Reason>" & oXMLDoc.parseError.reason & "</Reason></Error>"
Else
      oHTTPConn.send oXMLDoc
      'check for errors
      Set oNode = oHTTPConn.responseXML.selectSingleNode("/Error/ErrorCode")
      If (Not oNode Is Nothing) Then
          'the API returned an error
          'process the list of Error nodes
          'this information can be logged and processed
          'however you wish
            Response.write "I Failed"
      Else
      'at this point you can parse the responseXML DOM however you like
      'for example
      
                  response.write oHTTPConn.responseXML.xml
      End If
End If
Set oHTTPConn = Nothing
Set oXMLDoc = Nothing
Set oNode = Nothing
%>

When this code is run, I get an error "Only one top level element is allowed in an XML document." and the pointer is at the next "<?xml version="1.0"?>".  I need someone who has worked with the UPS Shipping API to let me know what I should do I guess.  Thanks in advance!

ED7
Avatar of Sleepyhead_NO
Sleepyhead_NO

The XML you are sending does not validate as XML. You need to format the XML document so it can validate as XML. Try to open the XML document you are sending in IE - it will give you an error.

If you NEED to send it as formatted above then don't use Server.CreateObject("Msxml2.DOMDocument.3.0") do load the document - because it requires the XML to be valid. If it is a local document the use the File System Object (FSO) to read the file and pass it to XMLHTTP object as a string.
Avatar of electricd7

ASKER

Sorry, i dont follow.  The XML I referenced above was copied directly from the UPS Shipping API PDF file and is exactly what they have specified to pass.  There is a blurb in there I don't quite understand and it is as follows:

-Shipping Programming Information Shipping Guidelines-
Each input request 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.

Does that help at all?
Avatar of Anthony Perkins
>>Sorry, i dont follow. <<
What Sleepyhead_NO is referring to is that your XML document (actually the second one) is not well-formed.  He/she refered to it being invalid, but in order to validate it, it requires a DTD or XML Schema, which it does not have and therefore is a separate issue.
Oh well, I copied that xml doc verbatim from the UPS PDF file as thier example.  The spacing and TABs didnt translate, but it is exactly the same as thier example.

ED7
>>Oh well, I copied that xml doc verbatim from the UPS PDF file as thier example. << 
Than all I can say is that someone at UPS does not know XML from a hole in the wall.  

Do yourself a favor and do the following:
1 .Copy and paste the second XML document into your favorite text editor (NotePad ?).  
2. Save it as something.xml
3. Run it in IE (as was previously suggested) and you will get the following error message:

End tag 'ShipmentNotification' does not match the start tag 'Notification'. Error processing resource 'file:///C:/Temp/Temp1.xml'. Line 106, Position 3

</ShipmentNotification>
--^

4. Change in your text editor:
</ShipmentNotification>
To:
</Notification>

5. Save it.
6. Re-run it in IE and it will display something like this:
<?xml version="1.0"?>
<ShipmentConfirmRequest xml:lang="en-US">
      <Request>
            <TransactionReference>
                  <CustomerContext>ShipConfirmUS</CustomerContext>
                  <XpciVersion>1.0001</XpciVersion>
            </TransactionReference>
            <RequestAction>ShipConfirm</RequestAction>
            <RequestOption>nonvalidate</RequestOption>
      </Request>
      <LabelSpecification>
            <LabelPrintMethod>
                  <Code>EPL</Code>
            </LabelPrintMethod>
            <LabelStockSize>
                  <Height>4</Height>
                  <Width>6</Width>
            </LabelStockSize>
      </LabelSpecification>
      <Shipment>
            <Shipper>
                  <Name>ShipperName</Name>
                  <AttentionName>ShipperAttnName</AttentionName>
                  <PhoneNumber>
                        <StructuredPhoneNumber>
                              <PhoneDialPlanNumber>222626</PhoneDialPlanNumber>
                              <PhoneLineNumber>7227</PhoneLineNumber>
                              <PhoneExtension>929</PhoneExtension>
                        </StructuredPhoneNumber>
                  </PhoneNumber>
                  <ShipperNumber>12345E</ShipperNumber>
                  <Address>
                        <AddressLine1>22 USShipperAddr1</AddressLine1>
                        <AddressLine2>USShipperAddr2</AddressLine2>
                        <AddressLine3>USShipperAddr3</AddressLine3>
                        <City>Plano</City>
                        <StateProvinceCode>TX</StateProvinceCode>
                        <PostalCode>75093</PostalCode>
                        <CountryCode>US</CountryCode>
                  </Address>
            </Shipper>
            <ShipTo>
                  <CompanyName>ShipToCompanyName</CompanyName>
                  <AttentionName>ShipToAttnName</AttentionName>
                  <PhoneNumber>
                        <StructuredPhoneNumber>
                              <PhoneDialPlanNumber>333656</PhoneDialPlanNumber>
                              <PhoneLineNumber>7337</PhoneLineNumber>
                              <PhoneExtension>9339</PhoneExtension>
                        </StructuredPhoneNumber>
                  </PhoneNumber>
                  <Address>
                        <AddressLine1>33 ShipToAddr1</AddressLine1>
                        <AddressLine2>USShipToAddr2</AddressLine2>
                        <AddressLine3>USShipToAddr3</AddressLine3>
                        <City>Atlanta</City>
                        <StateProvinceCode>GA</StateProvinceCode>
                        <PostalCode>30346</PostalCode>
                        <CountryCode>US</CountryCode>
                        <ResidentialAddress/>
                  </Address>
            </ShipTo>
            <ShipFrom>
                  <CompanyName>ShipFromCompanyName</CompanyName>
                  <AttentionName>ShipFromAttnName</AttentionName>
                  <PhoneNumber>
                        <StructuredPhoneNumber>
                              <PhoneDialPlanNumber>111616</PhoneDialPlanNumber>
                              <PhoneLineNumber>7117</PhoneLineNumber>
                              <PhoneExtension>9119</PhoneExtension>
                        </StructuredPhoneNumber>
                  </PhoneNumber>
                  <Address>
                        <AddressLine1>22 ShipFromAddr1 St</AddressLine1>
                        <AddressLine2>USShipFromAddr2</AddressLine2>
                        <AddressLine3>USShipFromAddr3</AddressLine3>
                        <City>Athens</City>
                        <StateProvinceCode>GA</StateProvinceCode>
                        <PostalCode>30605</PostalCode>
                        <CountryCode>US</CountryCode>
                  </Address>
            </ShipFrom>
            <PaymentInformation>
                  <Prepaid>
                        <BillShipper>
                              <AccountNumber>12345E</AccountNumber>
                        </BillShipper>
                  </Prepaid>
            </PaymentInformation>
            <Service>
                  <Code>01</Code>
            </Service>
            <ShipmentServiceOptions>
                  <Notification>
                        <EMailMessage>
                              <EMailAddress>christy@company1.com</EMailAddress>
                              <Memo>EmailShipNot Memo</Memo>
                        </EMailMessage>
                  </Notification>
                  <Notification>
                        <EMailMessage>
                              <EMailAddress>joe@company2.com</EMailAddress>
                              UPS ONLINE TOOLS
                              <NotificationCode>6</NotificationCode>
                        </EMailMessage>
                  </Notification>
            </ShipmentServiceOptions>
            <Package>
                  <PackagingType>
                        <Code>03</Code>
                  </PackagingType>
                  <PackageWeight>
                        <UnitOfMeasurement>
                              <Code>LBS</Code>
                        </UnitOfMeasurement>
                        <Weight>2</Weight>
                  </PackageWeight>
            </Package>
            <Package>
                  <PackagingType>
                        <Code>02</Code>
                  </PackagingType>
                  <ReferenceNumber>
                        <Code>9V</Code>
                        <Value>abcdefg</Value>
                  </ReferenceNumber>
                  <PackageWeight>
                        <UnitOfMeasurement>
                              <Code>LBS</Code>
                        </UnitOfMeasurement>
                        <Weight>2</Weight>
                  </PackageWeight>
                  <PackageServiceOptions>
                        <COD>
                              <CODFundsCode>8</CODFundsCode>
                              <CODCode>3</CODCode>
                              <CODAmount>
                                    <CurrencyCode>USD</CurrencyCode>
                                    <MonetaryValue>35000</MonetaryValue>
                              </CODAmount>
                        </COD>
                        <InsuredValue>
                              <CurrencyCode>USD</CurrencyCode>
                              <MonetaryValue>500.55</MonetaryValue>
                        </InsuredValue>
                  </PackageServiceOptions>
            </Package>
      </Shipment>
</ShipmentConfirmRequest>

This tells you it is now a well-formed XML document, which you can open with MSXML
ASKER CERTIFIED SOLUTION
Avatar of Anthony Perkins
Anthony Perkins
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Yes you are right...typo on my part.  But even when it is well formed, I still need help with my original question.  Thanks.
Also, regarding these two old open questions:

1 02/09/2004 125 What determines the order of a querystri...  Open Active Server Pages (ASP)
2 03/04/2004 250 Problem with displaying XML on server? (...  Open XML

Please see this:
Request a refund because you answered your own question (Refund/PAQ) https://www.experts-exchange.com/help.jsp#hi70
Request a refund because no one answered your question (Delete) https://www.experts-exchange.com/help.jsp#hi71
"But even when it is well formed, I still need help with my original question.  Thanks."

What is your question? Do you still get the same error?
Sleepyhead_NO,

I think my message and the questioner's crossed.  I had already answered regarding how to concatenate two XML documents.
I guess I just dont understand how I am supposed to submit a concatenated xml doc to UPS?  Can anyone give me specific code for doing this using my 2 xml docs as an example?  I thought I could concatenate it by just doing an xml = doc1 & doc2 and just use DomDocument to submit that string to UPS, but that doesnt work.  I just need an example I guess.  Thanks.

ED7
Let's try that once again (since you have now resolved the second XML document):

oHTTPConn.send oXMLDoc1.xml & oXMLDoc2.xml
So that this is crystal clear:

You never submit (under any circumstance) an XML document using the Send method (oHTTPConn.send oXMLDoc), you instead submit a string representation of an XML document (oHTTPConn.send oXMLDoc.xml)
sorry acperkins, I must have replied at the same time you were posting your answer.  Let me try your example and see what I come up with.  Thanks.

ED7
OK I changed my oHTTPConn.send to send (oXMLDoc.xml & oXMLDoc2.xml) after loading both variables with the correct string, and now I get the following message:

XML document must have a top level element. Error processing resource

When I send the second one individually, I get a UPS specific error, so I know it is working correctly.  When I send just the AccessRequest one individually, I get the same error as when I send them both togther.  The string I am loading into oXMLDoc is as follows:

  <?xml version="1.0" ?>
    <AccessRequest xml:lang="en-US">
       <AccessLicenseNumber><![CDATA[ mylicense]]></AccessLicenseNumber>
      <UserId><![CDATA[ myuserid]]></UserId>
      <Password><![CDATA[ mypassword]]></Password>
    </AccessRequest>

Which seems correct to me, but I am a newbie to XML.  Thanks again in advance.

ED7
I suspect this is your problem:
Response.ContentType = "text/xml"

You are indicating you are sending xml when in fact you are not.
ACperkins, you are the mack..it now works, but it returns the xml in one giant string...how do I get it so it displays as an XML document on my screen?  This is the source of the page, but it is just one continuous string on the screen, and I want it to display as an xml page so each node can be compacted or expanded:

<?xml version="1.0"?>
<ShipmentConfirmResponse><Response><TransactionReference><CustomerContext>ShipConfirmUS</CustomerContext><XpciVersion>1.0001</XpciVersion></TransactionReference><ResponseStatusCode>1</ResponseStatusCode><ResponseStatusDescription>Success</ResponseStatusDescription></Response><ShipmentCharges><TransportationCharges><CurrencyCode>USD</CurrencyCode><MonetaryValue>3.92</MonetaryValue></TransportationCharges><ServiceOptionsCharges><CurrencyCode>USD</CurrencyCode><MonetaryValue>0.00</MonetaryValue></ServiceOptionsCharges><TotalCharges><CurrencyCode>USD</CurrencyCode><MonetaryValue>3.92</MonetaryValue></TotalCharges></ShipmentCharges><BillingWeight><UnitOfMeasurement><Code>LBS</Code></UnitOfMeasurement><Weight>5.0</Weight></BillingWeight><ShipmentIdentificationNumber>1ZRW18250392418869</ShipmentIdentificationNumber><ShipmentDigest>VERY LARGE STRING</ShipmentDigest></ShipmentConfirmResponse>

Thanks and I will be awarding you the pts!

Ed7
>>how do I get it so it displays as an XML document on my screen?<<
You can, but why would you want to.  It makes more sense, to grab the individual pieces of information that you are looking for using XPath and
present it in a readable format.  However if you insist, use this code:

Dim XmlResponse
Dim XslResponse
Set XmlResponse = oHTTPConn.responseXML
Set XslResponse = Server.CreateObject("MSXML2.DOMDocument")
If XslResponse.Load("res://msxml3.dll/defaultss.xsl") Then
         Response.Write XmlResponse.transformNode(DefaultXSL)
Else
      Response.Write "XSL: " & XslResponse.parseError.Reason
End If
Set XslResponse = Nothing
Set XmlResponse = Nothing

This will present it as if you had saved the response in an XML file and opened it in IE
Yes you are right, that makes much more sense....the points are yours!  Thanks

ED7
We are also trying to integrate the UPS API using ASP classic into our website and was wondering what you eventually worked out? I tried to follow the thread but can't seem to get it working.
Wow, it has been years since we did this, but we eventually got it working and used it for years. I will look for the old code.
>>Wow, it has been years since we did this<<
5 years to be precise. :)