Android Question How can I pass an InputSource object into XMLBuilder.Parse?

Discussion in 'Android Questions' started by BenF, Feb 17, 2015.

  1. BenF

    BenF Member Licensed User

    Hi all,
    Sorry if this is a particularly dense question.... I am trying to find a way of reading a local xml file into my app, and then adding additional elements to it, as additional data is entered by the user.

    Context: The user will need to enter multiple (up to 30) samples with a range of values (date, time, sample type etc, potentially up to ~50/sample). Rather than try to record the values for all samples into an array and build the xml with a single builder, I thought it would be easier to enter the values into the xml as each sample entry is completed, and then enter the next sample with a new builder, parsed from the previous file. The xml layout is predefined, as per the database that I am passing data to.

    I have been able to use the xmlBuilder to build the file in the first place (ie the first sample) , but I am getting stuck with parsing the file back into the xmlBuilder. I believe I need to use xmlBuilder.Parse, as mentioned here:
    http://www.b4x.com/android/forum/threads/anyone-using-xmlbuilder-with-b4a.16277/
    in posts #9 and #10.
    However, the .Parse requires an InputSource object, and I cannot figure out how to get the InputStream from the xml into an InputSource object... - When I tried to use File.OpenInput I got an error during compiling:

    Code:
    Dim x As XMLBuilder
    x=x.parse(
    File.OpenInput(File.DirInternal,"Test1.xml"))
    Code:
    Parsing code.                           0.06
    Compiling code.                         
    0.89
    Compiling layouts code.                 
    0.15
    Generating R 
    file.                      1.19
    Compiling debugger engine code.         
    2.15
    Compiling generated Java code.          Error
    B4A line: 
    354
    x=x.parse(
    File.OpenInput(File.DirInternal,\
    javac 
    1.7.0_71
    src\b4a\example\main.java:
    387: error: inconvertible types
    _x = _x.parse((org.xml.sax.InputSource)(anywheresoftware.b4a.keywords.Common.File.OpenInput(anywheresoftware.b4a.keywords.Common.File.getDirInternal(),
    "Test1.xml").getObject()));
                                           ^
      required: InputSource
      found:    
    InputStream
    1 error

    The only other reference to them that I can find is through the xmlSax library, with .Parse and .Parse2:
    http://www.b4x.com/android/forum/threads/xml-parsing-with-the-xmlsax-library.6866/
    (post #15) mentioned as passing the stream to an InputSource object.

    That made me think of trying:
    Code:
    Dim x As XMLBuilder
        
    Dim Parser As SaxParser

        x=x.parse(Parser.Parse(
    File.OpenInput(File.DirInternal,"Test1.xml"),"Parser"))
    but realised pretty quickly that it's trying to pass a void value. This is where I come up against the limits of fumbling in the dark...

    This is probably a result of my novice coding, but any thoughts as to how I can move forward would be appreciated!

    For reference I have attached a copy of the xml format that was supplied by the target database as a template, and the test program in which I am trying to figure out the xml coding...

    Cheers,
    Ben.
     

    Attached Files:

  2. Erel

    Erel Administrator Staff Member Licensed User

    XMLBuilder wrapper only wraps the XML creation API. The parse method is exposed by mistake. You should use XmlSax or one of the other XML parsers to parse the string.
     
  3. BenF

    BenF Member Licensed User

    Thanks for the quick response Erel, appreciated as always. I think I've managed it using XmlSax to parse the file, and rebuilding the xml in the event subs. I'll try to post the code for reference when I'm in the office tomorrow.

    Cheers,
    Ben.
     
    inakigarm likes this.
  4. BenF

    BenF Member Licensed User

    Hi Erel,
    Here's the code that I've come up with, seems to do the trick. I've cut down the size of the xml for ease of viewing, but retained the most of the general structure.

    Code:
    Sub Globals
        
    Dim x As XMLBuilder
        
    Dim TestPanel As Panel
        
    Dim Parser As SaxParser
        
    Dim In As InputStream
        
    Dim Pnl As Panel
        
    Dim PrevLine As String
    End Sub

    Sub Activity_Create(FirstTime As Boolean)
       
    End Sub

    Sub Activity_Resume

    End Sub

    Sub Activity_Pause (UserClosed As Boolean)

    End Sub

    Sub Button1_Click
        x = x.create(
    "wasp")
            x = x.element(
    "sample_no") _
            .attribute(
    "id","123456") _
                .element(
    "samp_details") _
                    .element(
    "project_code") _
                        .text(
    "GBRI5") _
                    .up() _
                    .element(
    "samp_type") _
                        .text(
    "IS") _
                    .up() _
                    .element(
    "containers") _
                        .text(
    "3") _
                    .up() _
                .up() _
                .element(
    "bottle_details") _
                    .element(
    "bottle_details1") _
                        .element(
    "bottle_type") _
                            .text(
    "A") _
                        .up() _
                        .element(
    "bott_lab_code") _
                            .text(
    "FSS") _
                        .up() _
                        .element(
    "collect_meth") _
                            .text(
    "MA") _
                        .up() _
                        .element(
    "preserv_meth1") _
                            .text(
    "CH") _
                        .up() _
                    .up() _
                .up() _
                .element(
    "test_details") _
                    .element(
    "test_details1") _
                        .element(
    "test_code") _
                            .text(
    "SEQEM1") _
                        .up() _
                        .element(
    "test_lab_code") _
                            .text(
    "FSS") _
                        .up() _
                    .up _
                .up() _
            .up() _
        .up()
       
        
    File.WriteString(File.DirInternal, "Test1.xml", x.asString)
       
        
    Log(x.asString)
       
        
    In = File.OpenInput(File.DirInternal,"Test1.xml")
       
        Parser.Initialize
       
        Parser.Parse(
    In"Parser")
        
    In.Close
       
        
    Log(x.asString)

        x = x.element(
    "sample_no") _
            .attribute(
    "id","123456") _
                .element(
    "samp_details") _
                    .element(
    "project_code") _
                        .text(
    "GBRI5") _
                    .up() _
                    .element(
    "samp_type") _
                        .text(
    "IS") _
                    .up() _
                    .element(
    "containers") _
                        .text(
    "3") _
                    .up() _
                .up() _
                .element(
    "bottle_details") _
                    .element(
    "bottle_details1") _
                        .element(
    "bottle_type") _
                            .text(
    "A") _
                        .up() _
                        .element(
    "bott_lab_code") _
                            .text(
    "FSS") _
                        .up() _
                    .up() _
                .up() _
                .element(
    "test_details") _
                    .element(
    "test_details1") _
                        .element(
    "test_code") _
                            .text(
    "SEQEM1") _
                        .up() _
                        .element(
    "test_lab_code") _
                            .text(
    "FSS") _
                        .up() _
                    .up _
                .up() _
            .up() _
        .up()
       
        
    File.WriteString(File.DirInternal, "Test2.xml", x.asString)
        
        
    Log(x.AsString)
    End Sub   
       
    Sub Parser_StartElement (Uri As String, Name As String, Attribute As Attributes)
        
    If Name = "wasp" Then
            x = x.create(
    "wasp")
        
    Else If Name = "sample_no" Then
            x = x.element(Name)
            x = x.Attribute(
    "id", Attribute.GetValue2("","id"))
        
    Else
            x = x.element(Name)
        
    End If
        PrevLine = 
    "Start"
    End Sub


    Sub Parser_EndElement (Uri As String, Name As String, Text As StringBuilder)
        
    If Name <> "wasp" Then
            
    If PrevLine = "Start" Then
                x = x.Text(Text)
                x = x.up()
            
    Else If PrevLine = "Finish" Then
                x = x.up()
            
    End If
        
    End If
        PrevLine = 
    "Finish"
    End Sub
    Hopefully this will be useful to someone at some point, unless there's an easier way of doing it?

    Cheers,
    Ben
     
    emockler and Erel like this.
  5. Erel

    Erel Administrator Staff Member Licensed User

    Are you using the xml only for your application? If yes then are simpler formats such as json or binary formats that you can choose.
     
  6. BenF

    BenF Member Licensed User

    No, the data is passed to a third party database that has a defined xml structure for inputting data, so I do need the data stored as an xml. I'll run with this for the moment, unless it starts taking too long to rewrite the xml. Time will tell :)
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice