Parsing XML from the Net - Using the SAXParser

Basic Tutorials concerning: GUI, Views, Activites, XML, Layouts, Intents, ...

Postby padde » Tue May 04, 2010 2:08 pm

I know that DaggieBe and totally agree with you.. but my code was intended as a simple example of
how to store multiple elements and be able to handle them afterwards.
For larger amounts of data to store vector is definitely not the right choice.
But give an example that involves DB storing too would put the example for a rather simple question to an
unnecessary level of complexity.

And what i meant with "Large XML Files will always end up with an OOME" was that the android sax parser
itself does not really like large xml files.

If someone needs to handle large XML files i'am willing to give an example for that too.. till then i think
the example fits Buts needs and should be fine.


Greets Padde
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Top

Postby DaggieBe » Tue May 04, 2010 2:44 pm

padde wrote:But give an example that involves DB storing too would put the example for a rather simple question to an unnecessary level of complexity.


I agree, I wasn't trying to 'correct' you. But if I were looking for an example, I would appreciate someone mentioning the solution wasn't fit for certain cases. (eg. large XML files)

padde wrote:And what i meant with "Large XML Files will always end up with an OOME" was that the android sax parser itself does not really like large xml files.


I haven't done 'performance' tests myself with the Android SAX parser, but I know in general that SAX is faster then DOM. First example I googled: http://www.devx.com/xml/Article/16922/1954 . Allow me to repeat, I haven't tested or examined this myself with the Android implementation. I've build an Android application that parses tons of (large) XML-files (over and over again) with SAX and it's fast enough for realtime browsing the result. It did require more effort then other solutions might have required, but for mobile devices, speed is important to avoid the user from searching 'something like it'. I went with a 'store in database'-solution in endElement should someone care.

I hope you don't take my comments as critism, I only wanted to add something to your example.
DaggieBe
Freshman
Freshman
 
Posts: 5
Joined: Tue May 04, 2010 7:46 am

Parsing XML from the Net - Using the SAXParser

Postby hakimapia » Thu May 06, 2010 10:30 am

rigeltrue wrote:
bstubbs wrote:Artur79, did you ever figure out how to solve the missing string?

I'm getting the same results:


ExtractedString =
ExtractedInt = 1337


Anyone else getting this, found a solution? Thanks


Hi
I meet the same proplem.

Chnage the xml file from
Syntax: [ Download ] [ Hide ]
Using xml Syntax Highlighting
  1. <mytag>
  2. anddev.org rulez =)
  3. </mytag>
Parsed in 0.000 seconds, using GeSHi 1.0.8.4


to
Syntax: [ Download ] [ Hide ]
Using xml Syntax Highlighting
  1. <mytag>anddev.org rulez =)</mytag>
Parsed in 0.000 seconds, using GeSHi 1.0.8.4


That works.


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~o0o~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This also worked for me. Thanks.
hakimapia
User avatar
hakimapia
Once Poster
Once Poster
 
Posts: 1
Joined: Thu May 06, 2010 10:21 am
Location: Singapore

Postby Beneesh » Thu May 06, 2010 11:04 am

Hi plusminus,

Can anybody suggest an alternative for these packages in java

javax.xml.transform.*;
javax.xml.namespace.*;

Since this packages are used a lot in xml processing, it is creating a lot of problems when trying to add some libraries to android.So please help.

Thanks in advance
Beneesh
Beneesh
Developer
Developer
 
Posts: 26
Joined: Tue Apr 06, 2010 8:18 am
Location: Kerala,India

Postby MorbidDestiny » Mon May 10, 2010 2:24 pm

Hi.
I followed the tutorial correctly but I haven't the expected result.

What I receive is:
ExtractedString =
ExtractedInt = 0

any ideas?
MorbidDestiny
Junior Developer
Junior Developer
 
Posts: 16
Joined: Fri Mar 26, 2010 4:56 pm

Postby whatthejeff » Tue May 11, 2010 4:55 am

Hello everyone,

I'm frequently receiving this error:

java.net.SocketTimeoutException: The operation timed out
at org.apache.harmony.luni.net.PlainSocketImpl.read(PlainSocketImpl.java:557)
at org.apache.harmony.luni.net.SocketInputStream.read(SocketInputStream.java:87)
at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:103)
at org.apache.http.impl.io.AbstractSessionInputBuffer.read(AbstractSessionInputBuffer.java:134)
at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:174)
at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:159)
at java.io.InputStreamReader.read(InputStreamReader.java:438)
at java.io.BufferedReader.fillbuf(BufferedReader.java:130)
at java.io.BufferedReader.read(BufferedReader.java:316)
at java.io.Reader.read(Reader.java:162)
at org.apache.harmony.xml.ExpatParser.parseFragment(ExpatParser.java:488)
at org.apache.harmony.xml.ExpatParser.parseDocument(ExpatParser.java:477)
at org.apache.harmony.xml.ExpatReader.parse(ExpatReader.java:317)
at org.apache.harmony.xml.ExpatReader.parse(ExpatReader.java:273)


The code I'm using is very similar to plusminus's original post:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. HttpClient client = new DefaultHttpClient();
  2. client.getParams().setParameter("http.socket.timeout", 10000);
  3. client.getParams().setParameter("http.connection.timeout", 10000);
  4. HttpGet get = new HttpGet(url[0]);
  5. HttpResponse response = client.execute(get);
  6. HttpEntity entity = response.getEntity();
  7.  
  8. if(entity!=null){
  9. stream = entity.getContent();
  10. BufferedReader read = new BufferedReader(new InputStreamReader(stream));
  11.                
  12. SAXParserFactory spf = SAXParserFactory.newInstance();
  13. SAXParser sp = spf.newSAXParser();
  14. XMLReader xr = sp.getXMLReader();
  15. xmlHandler handler = new xmlHandler();
  16. xr.setContentHandler(handler);
  17.                
  18. xr.parse(new InputSource(read));
  19.                
  20. parsed_data = handler.getParsedData();
  21. }
Parsed in 0.031 seconds, using GeSHi 1.0.8.4


The error comes from xr.parse(new InputSource(read));
Any ideas why? Thanks for your time.
whatthejeff
Freshman
Freshman
 
Posts: 3
Joined: Tue May 11, 2010 4:41 am

Top

Postby ggomeze » Thu May 13, 2010 10:07 am

Jeff,

could you try with this instead?. Let me know if it works:

InputStream is = resEntity.getContent();
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
xr.setContentHandler(new CustomizedHandler());
xr.parse(new InputSource(is));
ggomeze
Freshman
Freshman
 
Posts: 2
Joined: Thu May 13, 2010 9:56 am

Postby whatthejeff » Thu May 13, 2010 12:12 pm

ggomeze wrote:Jeff,

could you try with this instead?. Let me know if it works:

InputStream is = resEntity.getContent();
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
xr.setContentHandler(new CustomizedHandler());
xr.parse(new InputSource(is));


Thanks for your suggestion. Unfortunately the resulting behavior is the same. =/
whatthejeff
Freshman
Freshman
 
Posts: 3
Joined: Tue May 11, 2010 4:41 am

Postby padde » Thu May 13, 2010 12:17 pm

For me it sounds like your timeout settings are to restrictive.
Please try to ease them.

To test my theory try:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. client.getParams().setParameter("http.socket.timeout", 100000);
  3.  
  4. client.getParams().setParameter("http.connection.timeout", 100000);
  5.  
  6.  
Parsed in 0.031 seconds, using GeSHi 1.0.8.4
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Postby ggomeze » Thu May 13, 2010 12:44 pm

Yep, it sounds like an issue on the server side. Do you have access to server side?.

Ger
ggomeze
Freshman
Freshman
 
Posts: 2
Joined: Thu May 13, 2010 9:56 am

Postby whatthejeff » Fri May 14, 2010 3:01 am

padde wrote:For me it sounds like your timeout settings are to restrictive.
Please try to ease them.

To test my theory try:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. client.getParams().setParameter("http.socket.timeout", 100000);
  2. client.getParams().setParameter("http.connection.timeout", 100000);
  3.  
Parsed in 0.052 seconds, using GeSHi 1.0.8.4

The issues occur even with default settings. I believe default value is zero, which translates to an infinite timeout.

ggomeze wrote:Yep, it sounds like an issue on the server side. Do you have access to server side?.

Ger

Unfortunately I don't have server side access. I'm beginning to believe it's a server side + mobile connection issue. From that I added an HttpRequestRetryHandler and as a wide safety net, an option to Retry the connection if the RetryHandler fails.

Question: Is it normal practice to add mechanisms like an HttpRequestRetryHandler when using URLConnection/HttpClient?
whatthejeff
Freshman
Freshman
 
Posts: 3
Joined: Tue May 11, 2010 4:41 am

Postby padde » Fri May 14, 2010 6:11 am

Definitely not.
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Re: Parsing XML from the Net - Using the SAXParser

Postby svebee » Mon May 17, 2010 7:10 pm

hmmmm...I went trough tutorial and everything works just fine but I want something little more complicated (I think?).

I have XML file with something like

Syntax: [ Download ] [ Hide ]
Using xml Syntax Highlighting
  1. <Database>
  2.  <Row>
  3.   <id>1</id>
  4.   <column1>some text</column1>
  5.   <column2>some text</column2>
  6.   </Row>
  7.  
  8.  <Row>
  9.   <id>2</id>
  10.   <column1>some text</column1>
  11.   <column2>some text</column2>
  12.   </Row>
  13.   </Database>
Parsed in 0.002 seconds, using GeSHi 1.0.8.4


and when I parse it I just want to "forward" it to my local database and INSERT new rows in SomeTable with id = id tag in XML, column1 would be column1 in XML file and so on...

In short, multiple values in XML, parse them and forward into database where they are inserted as new rows.

I tried something with

Code: Select all
SQLiteDatabase myDB = null;
myDB = openOrCreateDatabase("ZET", MODE_PRIVATE, null);



but MODE_PRIVATE is always (expected) undefinied for String...any solution? Thank you :wink:

EDIT: I get it to work with just one row..how to get multiple rows (return values)?

Code: Select all
   public String toString(){
      return this.extractedString;
   }


Code: Select all
/* Our ExampleHandler now provides the parsed data to us. */
         ParsedExampleDataSet parsedExampleDataSet = myExampleHandler.getParsedData();

         String result= parsedExampleDataSet.toString();
         String[] array = result.split(",");
                  
         int id= Integer.parseInt(array[0]);
         String name = array[1];
         
           SQLiteDatabase myDB= null;
           myDB = openOrCreateDatabase("SomeDatabaseName", MODE_PRIVATE, null);
           myDB.execSQL("INSERT INTO SomeTable (id, name) VALUES (" + id+ ", '" + name + "');");
           if (myDB != null)
              myDB.close(); // Zatvori databazu


So if I have this in my XML file

Code: Select all
<?xml version="1.0"?>
<outertag>
   <innertag sampleattribute="innertagAttribute">
      <mytag>666,Test</mytag>
      <mytag>667,Test2</mytag>
      <tagwithnumber thenumber="1337"/>
   </innertag>
</outertag>


I get only last row inserted - 667, Test2 :roll:
svebee
Junior Developer
Junior Developer
 
Posts: 21
Joined: Wed Apr 21, 2010 10:19 pm

Re: Parsing XML from the Net - Using the SAXParser

Postby svebee » Mon May 17, 2010 9:56 pm

Alright, I got it...but only local :mrgreen: How to "transform" this code so it can regularly "take" the XML from some URL (like in the first post)? I'm confused :?

Update
Code: Select all
package com.svebee.prijevoz;

import java.util.Vector;

import android.app.Activity;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.widget.TextView;

public class Update extends Activity {
    private Vector<Person> friends;
   
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.update);
       
        friends = PersonParser.parse(getResources().openRawResource(R.raw.test));
       
        TextView tv = (TextView) findViewById(R.id.output);
        for(Person p : friends) {
           
           String rezultat = p.toString();
         String[] array = rezultat.split(",");
                  
         int id= Integer.parseInt(array[0]);
         String name= array[1];
         
           SQLiteDatabase myDB= null;
           myDB = openOrCreateDatabase("SomeDatabaseName", MODE_PRIVATE, null);
           myDB.execSQL("INSERT INTO SomeTable (id, name) VALUES (" + id+ ", '" + name+ "');");
           if (myDB != null)
              myDB.close();

           
           tv.append(p.toString());
        }
    }
}


Pearson
Code: Select all
package com.svebee.prijevoz;

import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

public class Person {
    private String name;
   
    public void setName(String n) { this.name = n; }
    public String getName() { return this.name; }
   
    public String toString() {
        return this.name;
    }
}

class PersonParser {
    public static Vector<Person> parse(InputStream in) {
        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser sp;
        try {
            sp = spf.newSAXParser();
            XMLReader xr = sp.getXMLReader();
            PersonHandler ch = new PersonHandler();
            xr.setContentHandler(ch);
            xr.parse(new InputSource(in));
            return ch.getParsedPersons();               
        } catch (ParserConfigurationException e) {
        } catch (SAXException e) {
        } catch (IOException e) {}
        return null;
    }
}

class PersonHandler extends DefaultHandler {
    private enum TAGS { friends, person, name}   
    private StringBuffer tempString;
    private Person tempPerson;
    private Vector<Person> friends;
   
    public PersonHandler() {
        super();
        this.friends = new Vector<Person>();
        this.tempString = new StringBuffer();
    }
   
    public Vector<Person> getParsedPersons() { return friends; }

    public void startDocument() { }
    public void endDocument() { }
   
    public void characters(char ch[], int start, int length) {
       tempString.append(ch,start,length);
    }
   
    public void startElement(String n, String l, String q, Attributes a) {
        switch(TAGS.valueOf(l)) {
            case person: tempPerson = new Person(); break;   
            default: tempString.setLength(0); break;
        }
    }
     
    public void endElement(String n, String l, String q) {
        switch(TAGS.valueOf(l)) {
            case name: tempPerson.setName(tempString.toString()); break;     
            case person: friends.add(tempPerson); break;
            default: break;
        }   
    }
}


test.xml
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<friends>
    <person><name>610,Test1</name></person>
    <person><name>611,Test2</name></person>
</friends>
svebee
Junior Developer
Junior Developer
 
Posts: 21
Joined: Wed Apr 21, 2010 10:19 pm

Re: Parsing XML from the Net - Using the SAXParser

Postby Leona » Tue May 25, 2010 4:32 am

Hi, i have to send a data and later parse the return XML file.
how to i add the data in to post to the web service
Leona
Once Poster
Once Poster
 
Posts: 1
Joined: Tue May 25, 2010 4:12 am

Top
PreviousNext

Return to Novice Tutorials

Who is online

Users browsing this forum: No registered users and 5 guests