Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

XML Must Contain a Top Level Element using VBA

Posted on 2010-11-12
5
Medium Priority
?
1,228 Views
Last Modified: 2012-05-10
I have no idea what I'm doing with this XML.  I've found examples and I'm trying to figure it out as I go.  However, I'm getting an error that the xml must contain a top level element.

Private Sub SupplierOrderNumber_DblClick(Cancel As Integer)
If Me.Supplier = "Green" Then
    GoToWebSite ("https://www.dealerease.net/catalog/myaccount/orders-view.asp?ret_id=140067&orderid=" & SupplierOrderNumber)
ElseIf Me.Supplier = "BNF" Then
        Dim wRequest As String
       Dim wResult As String
       Dim strpage As String
   
   'wRequest = "<Username>" & TEST_USERID & "</Username>" & _
               "<Password>" & TEST_PSWORD & "</Password>" & _
               "<Email>info@domain.be</Email>" & _
               "<UserPassword>Password2</UserPassword>" & _
               "<NewPassword></NewPassword>" & _
               "<ExternalID></ExternalID>" & _
               "<Name>Mastercar</Name>" & _
               "<Address>2313 Some st</Address>" & _
               "<Zipcode>3500</Zipcode>" & _
               "<City>Someplace</City>" & _
               "<Country>be</Country>" & _
               "<Language>nl</Language>" & _
               "<Phone>011/xx.xx.xx</Phone>" & _
               "<Homepage>http://www.domain.be</Homepage>" & _
               "<RemoteAddress></RemoteAddress>" & _
               "<AgreeConditions>1</AgreeConditions>"
        strpage = "https://www.bnfusa.com/xml_xchange/inv/post.lasso/"
         wRequest = "<StatusXML>" & _
           "<AccessRequest> " & _
              "<XMLlickey>E3QH45XS58M845E5</XMLlickey>" & _
              "<UserId>admin@thehousewaresstore.com</UserId>" & _
              "<Password>PZ34JCZCP</Password>" & _
              "<version>1.1</version>" & _
           "</AccessRequest>" & _
           "<Status>" & _
              "<user_po>" & Me.YahooOrderNumber & "</user_po>" & _
              "<web_id></web_id>" & _
              "<order_id>" & IIf(Me.SupplierOrderNumber <> "", SupplierOrderNumber, "") & "</order_id>" & _
           "</Status>" & _
        "</StatusXML> "
        'DEBUG.PRINT wRequest
           If Not TransferDataSOAP(wRequest, wResult) Then
              MsgBox "Error during the transfer."
           Else
              ProcessResult wResult
           End If
           

End If
End Sub

Public Function TransferDataSOAP(pRequest As String, _
                                  ByRef pResult As String) As Boolean
'This is the adapted TransferDataSoap from above.  It packaged the request, send it to the web service and wait for the reply:


   Dim oWeb As MSXML2.XMLHTTP30  'Object from Microsoft XML v 5.0
   Dim bStatus As Boolean
   Dim wMsg As String
   Dim wResult As String
   Dim wPosi As Integer
   Dim wMaxWait As Integer
   Dim wError As String
   
   On Error GoTo Proc_ERROR
   
   bStatus = False
     
   'Finish building the XML message
   wMsg = "<?xml version=""1.1"" encoding=""utf-8""?>"
   wMsg = wMsg & vbCrLf & "<env:Envelope xmlns:env=""http://schemas.xmlsoap.org/soap/envelope/"">"
   wMsg = wMsg & vbCrLf & "  <env:Body>"
   wMsg = wMsg & vbCrLf & "    <" & WEB_SERVICE_ACTION & ">"
  ' wMsg = wMsg & vbCrLf & "<doc>"
   wMsg = wMsg & vbCrLf & pRequest
   'wMsg = wMsg & vbCrLf & "</doc>"
   wMsg = wMsg & vbCrLf & "</" & WEB_SERVICE_ACTION & ">"
   wMsg = wMsg & vbCrLf & "</env:Body>"
   wMsg = wMsg & vbCrLf & "</env:Envelope>"


   'Set up to post to our localhost server
   Set oWeb = New MSXML2.XMLHTTP30
   oWeb.Open "post", WEB_SERVICE_URL

   'Set a standard SOAP/ XML header for the content-type
   oWeb.setRequestHeader "Content-Type", "text/xml"
   oWeb.setRequestHeader "Content-length", Len(wResult)
   
   'Set a header for the method to be called
   oWeb.setRequestHeader "SOAPAction", WEB_SERVICE_ACTION
   
   'Make the SOAP call
   oWeb.sEnd wMsg

   'Get the return value, allow the user to stop if taking too long
   wPosi = 0
   wMaxWait = 120
   Do While oWeb.ReadyState < 4 And wPosi < wMaxWait
      'Response not available, wait a little more
      Wait 1
     
      wPosi = wPosi + 1
      If wPosi >= wMaxWait Then
         'We waited for a long time, what does the user wants ?
         If vbYes = MsgBox("This transactions is taking longer to process than expected." & vbCrLf & vbCrLf & "Do you wish to continue waiting ? ", vbQuestion + vbYesNo) Then
            wPosi = 1
         End If
      End If
   Loop

   If wPosi >= wMaxWait Then
      'waited too long, user wants to stop
      bStatus = False
   Else
   
      wResult = oWeb.responseText
   
      'Do we got an error
      If Left(wResult, 6) = "<html>" Then
         'this is an error HTML page
         wPosi = InStr(1, wResult, "<TITLE>")
         If wPosi > 0 Then
            wError = Mid(wResult, wPosi + 7, InStr(wPosi, wResult, "</title>") - (wPosi + 8))
         Else
            wError = "Unspecified error"
         End If
         MsgBox "There was an error in the attempt to connect to the server " & vbCrLf & "  --> " & wError
               
         bStatus = False
      Else
         
         'Return the result for further processing
         pResult = wResult
         bStatus = True
      End If
         
   End If
   
Proc_EXIT:
   Set oWeb = Nothing
   
   TransferDataSOAP = bStatus
   
   Exit Function
   
Proc_ERROR:

   MsgBox "Unhandled Error: " & Err.description
   Stop
   Resume


End Function
Public Sub ProcessResult(pResult As String)
'This sub process the result string using an XML DOM document.
'When I run, I get a valid response but the result code is 0.
'You will need to add the logic for when the result code is 1 as I don't know what you want to do with.

   Dim oDom As New MSXML2.DOMDocument
   Dim oResponseNode As MSXML2.IXMLDOMNode
   Dim oNode As MSXML2.IXMLDOMNode
   
   With oDom
      'load the xml string and valide its structure
      .LoadXML pResult
      If .parseError <> 0 Then
         'Something is wrong...
          MsgBox "Line: " & .parseError.Line & vbCrLf & "Char: " & .parseError.linepos & vbCrLf & _
                "Text: ...'" & Mid(.parseError.srcText, 57, 20) & "...'" & vbCrLf & "Reason: " & .parseError.reason
          Exit Sub
      End If
   End With
   
   'Search for the response node using xpath query
   Set oResponseNode = oDom.DocumentElement.SelectSingleNode("/soapenv:Envelope/soapenv:Body/SubscribeResponse/SubscribeReturn")
   If oResponseNode Is Nothing Then
      MsgBox "Wrong format???"
      Exit Sub
   End If
   
   'Look for the result code.
   Set oNode = GetValueFor(oResponseNode, "Result")
   If oNode Is Nothing Then
      MsgBox "No result!"
      Exit Sub
   End If
   
   If oNode.nodeTypedValue = 0 Then
      Set oNode = GetValueFor(oResponseNode, "returnText")
      If oNode Is Nothing Then
         MsgBox "Return 0 but result text not found"
      Else
         MsgBox "Return 0 with text " & vbCrLf & oNode.Text
      End If
   Else
   
      'Do your processing here
      
   End If

End Sub

Open in new window

0
Comment
Question by:dleads
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
5 Comments
 
LVL 19

Expert Comment

by:Bardobrave
ID: 34119947
An XML file is a tree-node structure that MUST have a top level element. This means that every XML file should has one tag that encloses all it's content:

<?xml version="1.1" encoding="utf-8"?>
<IAMTHETOPELEMENT>

....whatever....

</IAMTHETOPELEMENT>

So if you are getting such an error, it points at your XML file hasn't a top element. Maybe you are not creating a top element, he's not correctly closed or there is some code added after it's closing. You should review your xml creation and seek for clues under this issue.
0
 

Author Comment

by:dleads
ID: 34120155
What should the top element be?
I do not see any tags that havent been closed.
0
 
LVL 19

Expert Comment

by:Bardobrave
ID: 34120302
By default top element could be any tag that starts and ends the document.

However, several XML purposes (as SOAP data interchange for example) expects for a determinate set of top level elements.

Could you print your result xml and post it here?
0
 

Author Comment

by:dleads
ID: 34120321
I do not get a result.  I only get an error that it must contain a top level element.
what I post is the following:

<?xml version="1.1" encoding="utf-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
  <env:Body>
    <Subscribe>
  <StatusXML>
  <AccessRequest> 
    <XMLlickey>E3QH45XS58M845E5</XMLlickey>
    <UserId>admin@thehousewaresstore.com</UserId>
    <Password>PZ34JCZCP</Password>
    <version>1.1</version>
  </AccessRequest>
  <Status>
    <user_po>4256</user_po>
    <web_id></web_id>
    <order_id>321349</order_id>
   </Status>
  </StatusXML> 
    </Subscribe>
   </env:Body>
</env:Envelope>

Open in new window

0
 
LVL 19

Accepted Solution

by:
Bardobrave earned 2000 total points
ID: 34121872
Try to change your <?xml version="1.1" encoding="utf-8"?> to <?xml version="1.0" encoding="utf-8"?>, I get an error when trying to show the file with version 1.1
0

Featured Post

Use Case: Protecting a Hybrid Cloud Infrastructure

Microsoft Azure is rapidly becoming the norm in dynamic IT environments. This document describes the challenges that organizations face when protecting data in a hybrid cloud IT environment and presents a use case to demonstrate how Acronis Backup protects all data.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

It’s the first day of March, the weather is starting to warm up and the excitement of the upcoming St. Patrick’s Day holiday can be felt throughout the world.
Microsoft Access is a place to store data within tables and represent this stored data using multiple database objects such as in form of macros, forms, reports, etc. After a MS Access database is created there is need to improve the performance and…
With Microsoft Access, learn how to start a database in different ways and produce different start-up actions allowing you to use a single database to perform multiple tasks. Specify a start-up form through options: Specify an Autoexec macro: Us…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…

688 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