Solved

XML Must Contain a Top Level Element using VBA

Posted on 2010-11-12
5
1,189 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
  • 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 500 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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Overview: This article:       (a) explains one principle method to cross-reference invoice items in Quickbooks®       (b) explores the reasons one might need to cross-reference invoice items       (c) provides a sample process for creating a M…
I see at least one EE question a week that pertains to using temporary tables in MS Access.  But surprisingly, I was unable to find a single article devoted solely to this topic. I don’t intend to describe all of the uses of temporary tables in t…
Familiarize people with the process of retrieving data from SQL Server using an Access pass-thru query. Microsoft Access is a very powerful client/server development tool. One of the ways that you can retrieve data from a SQL Server is by using a pa…
Basics of query design. Shows you how to construct a simple query by adding tables, perform joins, defining output columns, perform sorting, and apply criteria.

920 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

11 Experts available now in Live!

Get 1:1 Help Now