XMLSax read sublist

SpaceCow

Member
Licensed User
Longtime User
Hi,

I was wondering how i can read this XML with XMLSax:

B4X:
<data>
   <day>
      <name>Monday</name>
      <activities>
         <activity>
            <name>Wash car</name>
            <timeFrom>12:00</timeFrom>
            <timeTo>12:30</timeTo>
         </activity>
         <activity>
            <name>Sleep</name>
            <timeFrom>14:00</timeFrom>
            <timeTo>15:00</timeTo>
         </activity>
      </activities>
   <day>
   <day>
      <name>Wednesday</name>
      <activities>
         <activity>
            <name>Eat</name>
            <timeFrom>12:00</timeFrom>
            <timeTo>12:30</timeTo>
         </activity>
         <activity>
            <name>Sleep</name>
            <timeFrom>14:00</timeFrom>
            <timeTo>15:00</timeTo>
         </activity>
      </activities>
   <day>
</data>

I've tried all kind of methods but nothing seems to work. Can someone give me a hint?

The basics:
B4X:
Sub SchemaParser_EndElement (Uri As String, Name As String, Text As StringBuilder)
    If Parser.Parents.IndexOf("data") > -1 Then
        If Name = "day" Then
         
      End If
   End If
End Sub

Thanks!
 

SpaceCow

Member
Licensed User
Longtime User
Please, can someone give me some advise how to read the activities from the days? Still i can't figure out how to parse the full XML.

Thanks!
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
You should define a custom type that represents an activity.
Declare a global "activity" variable and a list.

In StartElement if the Name is activity then you should redim the activity variable and add it to the list.

In EndElement you should set the activity variable fields.

There are several similar examples in this thread:
http://www.b4x.com/forum/basic4andr...866-xml-parsing-xmlsax-library.html#post39737
 
Upvote 0

SpaceCow

Member
Licensed User
Longtime User
Pfff, i still don't get it.

This is what i have in my Process_Globals:
B4X:
Sub Process_Globals
   Dim Parser As SaxParser
    Type Day(name As String, Activities As List)
    Dim myDays As List
End Sub
First i made the "Type" for the days, i thought that i should make a "List" for the activities in the days.

Now i parse the xml (i tested it with my previous script, it reads correct).
B4X:
Sub ParseXML
   Dim in As InputStream
   
   Parser.Initialize
   myDays.Initialize
   
   in = File.OpenInput(File.DirInternal, "scheme0.dat")
   Parser.Parse(in, "SchemaParser2")
   in.Close
   
End Sub

Then i have my SchemaParser2 and here is where it goes wrong. With this simple piece of code i keep getting an error on: "d = myDays.Get(myDays.Size - 1)"
B4X:
Sub SchemaParser2_StartElement (Uri As String, Name As String, Attributes As Attributes)
   If Name = "day" Then
      Dim d As Day
      d.Initialize
      myDays.Add(d)
   End If
End Sub

Sub SchemaParser2_EndElement (Uri As String, Name As String, Text As StringBuilder)
    Dim d As Day
    d = myDays.Get(myDays.Size - 1)
    Select Name
        Case "name"
           d.name = Text
    End Select
End Sub

After this i still have to read all the activities from that day... can someone maybe make a simple example please? I want to understand it but i think it's really hard :(.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Here:
B4X:
Sub Process_Globals
   Type Day(name As String, Activities As List)
   Type Act(name As String, timeFrom As String, timeTo As String)
   Dim parser As SaxParser
   Dim MyDays As List
   Dim tempDay As Day
   Dim tempAct As Act
End Sub

Sub Globals
End Sub
Sub Activity_Create(FirstTime As Boolean)
   parser.Initialize
   MyDays.Initialize
   Dim in As InputStream
   in = File.OpenInput(File.DirAssets, "1.xml")
   parser.Parse(in, "parser")
   in.Close
   Log(MyDays)
End Sub
Sub Parser_StartElement (Uri As String, Name As String, Attributes As Attributes)
   If Name = "day" Then
      Dim tempDay As Day 'this creates a new Day object
      tempDay.Initialize
      tempDay.Activities.Initialize
      MyDays.Add(tempDay)
   Else If Name = "activity" Then
      Dim tempAct As Act
      tempDay.Activities.Add(tempAct)
   End If
End Sub
Sub Parser_EndElement (Uri As String, Name As String, Text As StringBuilder)
   Select Name
      Case "name"
         If parser.Parents.IndexOf("activity") = -1 Then
            'this is the day name
            tempDay.name = Text.ToString
         Else
            tempAct.name = Text.ToString
         End If
      Case "timeFrom"
         tempAct.timeFrom = Text.ToString
      'complete other attributes
   End Select
End Sub

Note that the XML is not correct. It is missing the header and the closing day nodes are not correct.
 
Upvote 0

SpaceCow

Member
Licensed User
Longtime User
Thank you! Thank you so much!!!!

I used this to read it out and it works!:

B4X:
   Dim LV_Test As ListView
   For i = 0 To MyDays.Size - 1
    Dim d As Day
    d = MyDays.Get(i)
    LV_Test.AddTwoLines(d.name, "-")
       For l = 0 To d.Activities.Size - 1
          Dim a As Act
          a = d.Activities.Get(l)
         LV_Test.AddTwoLines(a.timeFrom, "-")
      Next
   Next

Thanks again!!!
 
Upvote 0
Top