Results 1 to 10 of 10

Thread: [RESOLVED] Extracting specific values from XML Results

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Mar 2010
    Location
    Southeast Michigan
    Posts
    155

    Resolved [RESOLVED] Extracting specific values from XML Results

    I have received data from a SOAP call and put it into an MSXML2.DOMDocument using the loadXML function. The data returned looks something like this:

    Code:
    <ResultSets>
    	<ResultSet>
    		<RowCount>1</RowCount>
    			<Rows>
    				<Row>
    					<Columns>
    						<Column>
    							<Value>George Davis</Value>
    							<Name>Employee</Name>
    						</Column>
    						<Column>
    							<Value>3/7/2019 10:04:52 AM</Value>
    							<Name>Begin_Time</Name>
    						</Column>
    						<Column>
    							<Value>3829927</Value>
    							<Name>Clockin_Key</Name>
    						</Column>
    						<Column>
    							<Value>Production</Value>
    							<Name>Cost_Sub_Type</Name>
    						</Column>
    						<Column>
    							<Value>cst.GeorgeD</Value>
    							<Name>User_ID</Name>
    						</Column>
    						<Column>
    							<Value>Davis</Value>
    							<Name>Last_Name</Name>
    						</Column>
    						<Column>
    							<Value>0</Value>
    							<Name>Contract_Worker</Name>
    						</Column>
    					</Columns>
    				</Row>
    			</Rows>
    	</ResultSet>
    </ResultSets>
    I would like to look for specific values in the data returned. For example, just get the value of User_ID.

    Is there a way, with the DOMDocument to easily find these specific values?

    Thanks in advance for your help.
    Dave

    Helpful information I've found here so far : The Definitive "Passing Data Between Forms" : Restrict TextBox to only certain characters, numeric or symbolic :
    .NET Regex Syntax (scripting) : .NET Regex Language Element : .NET Regex Class : Regular-Expressions.info
    Stuff I've learned here so far : Bing and Google are your friend. Trying to help others solve their problems is a great learning experience

  2. #2
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    6,192

    Re: Extracting specific values from XML Results

    Check out inline comments for some XPath Queries 101 crash course
    thinBasic Code:
    1. Option Explicit
    2.  
    3. Private Const STR_SOAP_RESPONSE1 As String = _
    4. "<ResultSets>" & vbCrLf & _
    5. "    <ResultSet>" & vbCrLf & _
    6. "        <RowCount>1</RowCount>" & vbCrLf & _
    7. "            <Rows>" & vbCrLf & _
    8. "                <Row>" & vbCrLf & _
    9. "                    <Columns>" & vbCrLf & _
    10. "                        <Column>" & vbCrLf & _
    11. "                            <Value>George Davis</Value>" & vbCrLf & _
    12. "                            <Name>Employee</Name>" & vbCrLf & _
    13. "                        </Column>" & vbCrLf & _
    14. "                        <Column>" & vbCrLf & _
    15. "                            <Value>3/7/2019 10:04:52 AM</Value>" & vbCrLf & _
    16. "                            <Name>Begin_Time</Name>" & vbCrLf & _
    17. "                        </Column>" & vbCrLf & _
    18. "                        <Column>" & vbCrLf & _
    19. "                            <Value>3829927</Value>" & vbCrLf & _
    20. "                            <Name>Clockin_Key</Name>" & vbCrLf & _
    21. "                        </Column>" & vbCrLf & _
    22. "                        <Column>" & vbCrLf
    23. Private Const STR_SOAP_RESPONSE2 As String = _
    24. "                            <Value>Production</Value>" & vbCrLf & _
    25. "                            <Name>Cost_Sub_Type</Name>" & vbCrLf & _
    26. "                        </Column>" & vbCrLf & _
    27. "                        <Column>" & vbCrLf & _
    28. "                            <Value>cst.GeorgeD</Value>" & vbCrLf & _
    29. "                            <Name>User_ID</Name>" & vbCrLf & _
    30. "                        </Column>" & vbCrLf & _
    31. "                        <Column>" & vbCrLf & _
    32. "                            <Value>Davis</Value>" & vbCrLf & _
    33. "                            <Name>Last_Name</Name>" & vbCrLf & _
    34. "                        </Column>" & vbCrLf & _
    35. "                        <Column>" & vbCrLf & _
    36. "                            <Value>0</Value>" & vbCrLf & _
    37. "                            <Name>Contract_Worker</Name>" & vbCrLf & _
    38. "                        </Column>" & vbCrLf & _
    39. "                    </Columns>" & vbCrLf & _
    40. "                </Row>" & vbCrLf & _
    41. "            </Rows>" & vbCrLf & _
    42. "    </ResultSet>" & vbCrLf & _
    43. "</ResultSets>"
    44.  
    45. Private Sub Form_Load()
    46.     Dim oDoc            As Object
    47.     Dim oNode           As Object
    48.    
    49.     With CreateObject("MSXML2.DOMDocument")
    50.         .LoadXml STR_SOAP_RESPONSE1 & STR_SOAP_RESPONSE2
    51.         Set oDoc = .documentElement
    52.     End With
    53.    
    54.     '--- first <Column>
    55.     Set oNode = oDoc.selectSingleNode("/ResultSets/ResultSet/Rows/Row/Columns/Column")
    56.     Debug.Print oNode.Xml, Timer
    57.     '--- the same
    58.     Set oNode = oDoc.selectSingleNode("//Column")
    59.     Debug.Print oNode.Xml, Timer
    60.     '--- the <Column> with User_ID in <Name> child
    61.     Set oNode = oDoc.selectSingleNode("//Column[Name='User_ID']")
    62.     Debug.Print oNode.Xml, Timer
    63.     '--- the <Value> under <Column> with 'User_ID' in <Name> child
    64.     Set oNode = oDoc.selectSingleNode("//Column[Name='User_ID']/Value")
    65.     Debug.Print oNode.Xml, Timer
    66.     '--- only <Value>'s text
    67.     Debug.Print oNode.Text, Timer
    68. End Sub
    cheers,
    </wqw>

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Mar 2010
    Location
    Southeast Michigan
    Posts
    155

    Re: Extracting specific values from XML Results

    So far I'm able to get data using the following code. However, it seems a like there would be an easier/better way to do it.

    Code:
    Sub ParseXmlDocument()
       Dim doc As New MSXML2.DOMDocument
       Dim x As Object
       Dim NodeIndex As Integer
        
       Dim success As Boolean
    
       NodeIndex = 0
       success = doc.loadXML(txtResponse.Text)
       
       For Each x In doc.getElementsByTagName("Name")
        If x.nodeTypedValue = "User_ID" Then
            Exit For
        End If
        NodeIndex = NodeIndex + 1
       Next
    
       MsgBox "User located at node " & NodeIndex & " = " & doc.getElementsByTagName("Value").Item(NodeIndex).childNodes(0).nodeValue
    End Sub
    Dave

    Helpful information I've found here so far : The Definitive "Passing Data Between Forms" : Restrict TextBox to only certain characters, numeric or symbolic :
    .NET Regex Syntax (scripting) : .NET Regex Language Element : .NET Regex Class : Regular-Expressions.info
    Stuff I've learned here so far : Bing and Google are your friend. Trying to help others solve their problems is a great learning experience

  4. #4

    Thread Starter
    Addicted Member
    Join Date
    Mar 2010
    Location
    Southeast Michigan
    Posts
    155

    Re: Extracting specific values from XML Results

    Thanks wqweto. I'll try this.
    Dave

    Helpful information I've found here so far : The Definitive "Passing Data Between Forms" : Restrict TextBox to only certain characters, numeric or symbolic :
    .NET Regex Syntax (scripting) : .NET Regex Language Element : .NET Regex Class : Regular-Expressions.info
    Stuff I've learned here so far : Bing and Google are your friend. Trying to help others solve their problems is a great learning experience

  5. #5

    Thread Starter
    Addicted Member
    Join Date
    Mar 2010
    Location
    Southeast Michigan
    Posts
    155

    Re: Extracting specific values from XML Results

    Exactly the information I was looking for! Thank you again.
    Dave

    Helpful information I've found here so far : The Definitive "Passing Data Between Forms" : Restrict TextBox to only certain characters, numeric or symbolic :
    .NET Regex Syntax (scripting) : .NET Regex Language Element : .NET Regex Class : Regular-Expressions.info
    Stuff I've learned here so far : Bing and Google are your friend. Trying to help others solve their problems is a great learning experience

  6. #6
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: [RESOLVED] Extracting specific values from XML Results

    Quote Originally Posted by dlscott56 View Post
    For example, just get the value of User_ID.

    Is there a way, with the DOMDocument to easily find these specific values?
    Aside from the several XML-DOM-Object-Helpers -
    there's of course always the VB6-String-Functions (for simple formats like the one you've posted):
    Code:
    Option Explicit
    
    Private Sub Form_Load()
      Const XML$ = "...<Column><Value>cst.GeorgeD</Value><Name>User_ID</Name></Column>..."
      Debug.Print GetPrecedingNodeValue(XML, "User_ID")
    End Sub
    
    Function GetPrecedingNodeValue(XML$, ValueName$, Optional PrecTag$ = "<Value>")
      Dim P As Long
          P = InStr(1, XML, ">" & ValueName & "</", 1)
       If P Then P = InStrRev(XML, PrecTag, P, 1)
       If P Then GetPrecedingNodeValue = Mid$(XML, P + Len(PrecTag), InStr(P, XML, "</") - P - Len(PrecTag))
    End Function
    Olaf

  7. #7

    Thread Starter
    Addicted Member
    Join Date
    Mar 2010
    Location
    Southeast Michigan
    Posts
    155

    Re: [RESOLVED] Extracting specific values from XML Results

    Thank you Olaf.
    Dave

    Helpful information I've found here so far : The Definitive "Passing Data Between Forms" : Restrict TextBox to only certain characters, numeric or symbolic :
    .NET Regex Syntax (scripting) : .NET Regex Language Element : .NET Regex Class : Regular-Expressions.info
    Stuff I've learned here so far : Bing and Google are your friend. Trying to help others solve their problems is a great learning experience

  8. #8
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: [RESOLVED] Extracting specific values from XML Results

    You can also do this using brute force techniques if your XML is simple and regular enough. If nothing ever changes this might be adequate, but in the real world even a small format change may require reworking finicky code.

    Code:
    Option Explicit
    
    'This code assumes a lot of things, such as:
    '
    '   o The first row contains every field that any row contains.  it uses
    '     that to create an ADO Recordset.
    '
    '   o The Name and Value nodes don't contain any whitespece to be
    '     trimmed.
    '
    
    Private Sub Form_Load()
        Dim F As Integer
        Dim XML As String
        Dim XMLRows() As String
        Dim I As Long
        Dim XMLColumns() As String
        Dim J As Long
        Dim Names() As Variant
        Dim Values() As Variant
        Dim Records As ADODB.Recordset
    
        'For simplicity, just grab the sample XML from a file:
        F = FreeFile(0)
        Open "xml.txt" For Input As #F
        XML = Input$(LOF(F), #F)
        Close #F
    
        'Extract the body of <Rows/> by brute force:
        XML = Split(Split(XML, _
                          "<Rows>", _
                          2, _
                          vbBinaryCompare)(1), _
                    "</Rows>", _
                    2, _
                    vbBinaryCompare)(0)
    
        'Extract the bodies of each <Row/>:
        XMLRows = Split(XML, "</Row>", , vbBinaryCompare)
        XML = vbNullString 'Discard, no longer needed.
        ReDim Preserve XMLRows(UBound(XMLRows) - 1)
        For I = 0 To UBound(XMLRows)
            XMLRows(I) = Split(XMLRows(I), "<Row>", 2, vbBinaryCompare)(1)
        Next
    
        'Extract into a Recordset.
    
        'Extract the bodies of each <Column/>:
        For I = 0 To UBound(XMLRows)
            XMLColumns = Split(XMLRows(I), "</Column>", , vbBinaryCompare)
            ReDim Preserve XMLColumns(UBound(XMLColumns) - 1)
            ReDim Preserve Names(UBound(XMLColumns))
            ReDim Preserve Values(UBound(XMLColumns))
            For J = 0 To UBound(XMLColumns)
                XMLColumns(J) = Split(XMLColumns(J), "<Column>", 2, vbBinaryCompare)(1)
    
                'Extract each <Name/> and <Value/>:
                Names(J) = Split(Split(XMLColumns(J), _
                                       "<Name>", _
                                       2, _
                                       vbBinaryCompare)(1), _
                                 "</Name>", _
                                 2, _
                                 vbBinaryCompare)(0)
                Values(J) = Split(Split(XMLColumns(J), _
                                        "<Value>", _
                                        2, _
                                        vbBinaryCompare)(1), _
                                  "</Value>", _
                                  2, _
                                  vbBinaryCompare)(0)
            Next
            Erase XMLColumns 'No longer needed.
    
            If I = 0 Then
                'Create the Recordset:
                Set Records = New ADODB.Recordset
                With Records
                    With .Fields
                        For J = 0 To UBound(Names)
                            .Append Names(J), adVarWChar, 255
                        Next
                    End With
                    .Open
                End With
            End If
    
            'Add the data for this Row:
            Records.AddNew Names, Values
        Next
        Erase Values, Names, XMLColumns, XMLRows 'No longer needed.
    
        Set MSHFlexGrid1.DataSource = Records
        Records.Close
    End Sub
    
    Private Sub Form_Resize()
        If WindowState <> vbMinimized Then
            MSHFlexGrid1.Move 0, 0, ScaleWidth, ScaleHeight
        End If
    End Sub
    Name:  sshot.png
Views: 185
Size:  3.5 KB

    Here I added a second Row to the XML sample for generality.
    Attached Files Attached Files

  9. #9
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: [RESOLVED] Extracting specific values from XML Results

    Some "traps for young players" include issues like varying whitespace even within tags and "entity encoded" characters. You also have other potential issues to cope with such as attributes, CDATA sections, and more.

    So I don't really advocate manually parsing XML. MSXML has both SAX2 and the DOM which wraps SAX2 parsing, so there isn't much excuse for rolling your own.

  10. #10

    Thread Starter
    Addicted Member
    Join Date
    Mar 2010
    Location
    Southeast Michigan
    Posts
    155

    Re: [RESOLVED] Extracting specific values from XML Results

    Thanks dilettante. I appreciate it.
    Dave

    Helpful information I've found here so far : The Definitive "Passing Data Between Forms" : Restrict TextBox to only certain characters, numeric or symbolic :
    .NET Regex Syntax (scripting) : .NET Regex Language Element : .NET Regex Class : Regular-Expressions.info
    Stuff I've learned here so far : Bing and Google are your friend. Trying to help others solve their problems is a great learning experience

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width