Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Reading data from an XML document through pure VB code

Status
Not open for further replies.

espositophp

Programmer
Sep 30, 2003
31
Hello, I would like to be able to read from an XML file using pure VB5/VB6 code without making any reference to any external objects.

Now, I have managed to retrieve the data relating to the first occurrence of a single field in the XML document by using the following code:

Code:
Private Function InString(SourceLine As String, StartSource As String, EndSource As String)

    Dim i As Long
    Dim j As Long
    Dim TempStr As String
    
    i = Len(StartSource) + InStr(SourceLine, StartSource)
        If i > Len(StartSource) Then
         j = InStr(i + 1, SourceLine, EndSource)
         If j Then
              TempStr = Mid$(SourceLine, i + 1, j - i - 1)                                                         
               InString = TempStr
         End If
    End If

End Function

Private Sub Command1_Click()

	Dim StrXML As String

	Dim ff As Long
	ff = FreeFile

	Open App.Path & "\MyXML.txt" For Input As #ff

	StrXML = Input$(LOF(1), 1)
	Close #ff

	StrXML = InString(StrXML, "<myfield", "</myfield>")

	If Len(StrXML) < 3 Then
    		MsgBox "Invalid data in the field."
    		Exit Sub
	End If

	If Len(StrXML) = 0 Then MsgBox "Invalid data in the field."

	Text1.Text = StrXML

End Sub

What I can't do is move on to the second occurrence of the same field in the XML document.

Please note that I'd like to be able to read from a very simple XML file, of which I know the structure. I'm not interested in reading DTDs, schema etc. I don't want to allow the user to modify the XML document. He must only be able to click on a button and move on to the next record.

So, it would be enough to treat it as any other text file, the problem is I got stuck when I tried to implement a recursive search function.

To simplify, my XML document could look like the following:

Code:
<?xml version='1.0' encoding='ISO8859-1' ?>

<mydatabase>

<myrecord>
<myfield>This is the first occurrence</myfield>
</myrecord>

<myrecord>
<myfield>This is the second occurrence</myfield>
</myrecord>

</mydatabase>

Can anybody modify the the VB code in Command1_Click in such a way that when I click on it a second time I get the data relating to the second occurrence of <myfield>?

Thanks in advance.
 
Something like this.
Not good code but I thinks what you are trying to do is a bit dubious.
Just call it with the entry seq you want to find

Private Function InString(SourceLine As String, StartSource As String, EndSource As String, seq as int)

Dim i As Long
Dim j As Long
Dim TempStr As String
dim z as int

i = 1
for z = seq to 0 step -1
i = Len(StartSource) + InStr(i, SourceLine, StartSource)
If i <> 0 Then
j = InStr(i + 1, SourceLine, EndSource)
If j <> 0 and z = 1 Then
TempStr = Mid$(SourceLine, i + 1, j - i - 1)
InString = TempStr
End If
else
exit function
End If
next
End Function


======================================
Cursors are useful if you don't know sql.
DTS can be used in a similar way.
Beer is not cold and it isn't fizzy.
 
Why can't you reference any external objects?
Writing your own XML parser is (in almost all cases) a waste of time and money.

Chip H.


____________________________________________________________________
If you want to get the best response to a question, please read FAQ222-2244 first
 
I have created a Label to keep track of the field number. So, now all the code runs as follows:

Code:
Private Function InString(SourceLine As String, StartSource As String, EndSource As String, Seq As Integer)

    Dim i As Long
    Dim j As Long
    Dim TempStr As String
    Dim z As Integer
    
    i = 1
    For z = Seq To 0 Step -1
    i = Len(StartSource) + InStr(i, SourceLine, StartSource)
        If i <> 0 Then
         j = InStr(i + 1, SourceLine, EndSource)
         If j <> 0 And z = 1 Then
              TempStr = Mid$(SourceLine, i + 1, j - i - 1)
               InString = TempStr
         End If
    Else
       Exit Function
    End If
    Next
    
End Function

Private Sub Command1_Click()

Dim StrXML As String

Dim ff As Long
ff = FreeFile

Open App.Path & "\MyXML.txt" For Input As #ff

Do While Not EOF(ff)

StrXML = Input$(LOF(1), 1)

Dim myOccurrence As Integer
myOccurrence = lblOccurrence.Caption

StrXML = InString(StrXML, "<myfield", "</myfield>", myOccurrence)
Text1.Text StrXML

Loop

Close #ff

lblOccurrence.Caption = lblOccurrence.Caption + 1

End Sub
The only problem I have is that I can't stop the counter after I have got to the last occurrence of myfield, since it starts showing the records again from scratch.

Do you know how to prevent Command1_Click from going back to the start of the file once all the records have been shown?

TIA

P.S. The reason why I can't reference any external objects is that my app must be used in a local area network, without installation. For the same reason, I have to program my app in VB5, instead of VB6, since the former does not require a setup procedure to make an executable run. (provided that you don't use any OCX's or references to external objects...)
 
Do you know how to prevent Command1_Click from going back to the start of the file once all the records have been shown?
Assuming you never want it to run again, since the file name is hard-coded and will always be the same, just disable it right before exiting the command click sub. In fact, you might want to disable it immediately, as the user could keep clicking on it while it's doing the processing.

...in VB5, instead of VB6, since the former does not require a setup procedure to make an executable run...
That's not the case for VB6 - I do it all the time. All you need is the VB runtime available - it can be on the network in the same directory as the exe file. And there are ways to register dll and ocx files directly from the program, so you shouldn't let that interfere with your design.

"I think we're all Bozos on this bus!" - Firesign Theatre [jester]
 
Could you please translate into code the following statement:

Assuming you never want it to run again, since the file name is hard-coded and will always be the same, just disable it right before exiting the command click sub. In fact, you might want to disable it immediately, as the user could keep clicking on it while it's doing the processing.

VB6 executables need OLEAUT32.DLL to be updated in Windows 95 and 98, otherwise they won't run. To update it, you need to launch a setup procedure.
 
Using your example:

Code:
Private Sub Command1_Click()

Dim StrXML As String

Dim ff As Long
[green]
'  Disable command at start of routine
Command1.enable = false[/green]

ff = FreeFile

Open App.Path & "\MyXML.txt" For Input As #ff

Do While Not EOF(ff)

StrXML = Input$(LOF(1), 1)

Dim myOccurrence As Integer
myOccurrence = lblOccurrence.Caption

StrXML = InString(StrXML, "<myfield", "</myfield>", myOccurrence)
Text1.Text StrXML

Loop

Close #ff

lblOccurrence.Caption = lblOccurrence.Caption + 1
[green]
'  Or disable command at end of routine
Command1.enable = false[/green]

End Sub

VB6 executables need OLEAUT32.DLL to be updated in Windows 95 and 98
Haven't used either of these systems for a loooooooooong time, so I didn't realize this - doh! At any rate, there are ways to register dlls on the user's machine without an install - assuming the user has privileges to do it...


"I think we're all Bozos on this bus!" - Firesign Theatre [jester]
 
I'm afraid I was not clear.

I would like the user to be able to browse all the records in the XML document. When the last record shows, I'd like my app to notify the user instead of starting to show the records again from scratch.

To make things easier to explain and understand, let's put it this way: is it possible to know how many occurrences of a field there are in an XML document?

TIA
 
Hello, I have another problem. I have added a second field to my XML document (<myfield2>) and I have tried to read data from both the first and this second field.

The only alteration I have made to the previous code is in Command1_Click. So the entire code now runs as follows:

Code:
Private Function InString(SourceLine As String, StartSource As String, EndSource As String, Seq As Integer)

    Dim i As Long
    Dim j As Long
    Dim TempStr As String
    Dim z As Integer
    
    i = 1
    For z = Seq To 0 Step -1
    i = Len(StartSource) + InStr(i, SourceLine, StartSource)
        If i <> 0 Then
         j = InStr(i + 1, SourceLine, EndSource)
         If j <> 0 And z = 1 Then
              TempStr = Mid$(SourceLine, i + 1, j - i - 1)
               InString = TempStr
         End If
    Else
       Exit Function
    End If
    Next
    
End Function

Private Sub Command1_Click()

   Dim StrXML As String

   Dim ff As Long
   ff = FreeFile

   Open App.Path & "\MyXML.txt" For Input As #ff

   Do While Not EOF(ff)

     StrXML = Input$(LOF(1), 1)

     Dim myOccurrence As Integer
     myOccurrence = lblOccurrence.Caption

     StrXML = InString(StrXML, "<myfield", "</myfield>", myOccurrence)
     Text1.Text StrXML

     'The following is the new code that should read data from <myfield2>
     'but it doesn't.
     StrXML = InString(StrXML, "<myfield2", "</myfield2>", myOccurrence)
     Text2.Text StrXML

   Loop

   Close #ff

   lblOccurrence.Caption = lblOccurrence.Caption + 1

End Sub

Unfortunately, the code above does not work. When I click on the button I only get the data relating to first field, whereas Text2 remains blank.

Any help?

TIA
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top