Parsing XML from the Net - Using the SAXParser

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

Postby Chri » Wed Sep 23, 2009 6:49 pm

do you write it into a string?

mfg Chri
Chri
Experienced Developer
Experienced Developer
 
Posts: 51
Joined: Mon Aug 31, 2009 12:08 pm

Top

Postby Fluckysan » Wed Sep 23, 2009 6:56 pm

Thx for your response

I write it into a string as the tuto :
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. String coord = new String(ch, start, length);
Parsed in 0.029 seconds, using GeSHi 1.0.8.4


EDIT : hum it's very random, I just got "43.6" >_<
Fluckysan
Junior Developer
Junior Developer
 
Posts: 17
Joined: Wed Jul 01, 2009 7:57 am

Postby Chri » Wed Sep 23, 2009 9:29 pm

Did you ever try to write it with a buffer?
Like the example above?
Chri
Experienced Developer
Experienced Developer
 
Posts: 51
Joined: Mon Aug 31, 2009 12:08 pm

Postby Fluckysan » Fri Sep 25, 2009 2:56 pm

Yeah I tried it :/
It doesn't solve the bug :o
Fluckysan
Junior Developer
Junior Developer
 
Posts: 17
Joined: Wed Jul 01, 2009 7:57 am

Postby padde » Fri Sep 25, 2009 5:20 pm

XmlContentHandler
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. package de.padde.xmldemo;
  2.  
  3. import org.xml.sax.Attributes;
  4. import org.xml.sax.SAXException;
  5. import org.xml.sax.helpers.DefaultHandler;
  6.  
  7. import android.util.Log;
  8.  
  9. public class XmlContentHandler extends DefaultHandler {
  10.     enum XML_TAGS { text }
  11.     boolean in_TextTag = false;
  12.    
  13.     public void startDocument() throws SAXException { }
  14.     public void endDocument() throws SAXException { }
  15.  
  16.     public void startElement(String ns, String ln, String qn, Attributes at) throws SAXException {
  17.         switch(XML_TAGS.valueOf(ln)) {
  18.             case text: in_TextTag = true; break;
  19.         }
  20.     }
  21.  
  22.     public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
  23.         switch(XML_TAGS.valueOf(localName)) {
  24.             case text: in_TextTag = false; break;
  25.         }
  26.     }
  27.      
  28.     public void characters(char ch[], int start, int length) {
  29.         if(in_TextTag) {
  30.             String readin = new String(ch, start, length);
  31.             String[] geoloc = readin.split(",");
  32.             double longitude = Double.parseDouble(geoloc[0]);
  33.             double latitude  = Double.parseDouble(geoloc[1]);
  34.            
  35.             Log.v("Long", String.valueOf(longitude));
  36.             Log.v("Lat", String.valueOf(latitude));
  37.         }
  38.     }
  39. }
  40.  
Parsed in 0.037 seconds, using GeSHi 1.0.8.4


XmlReader
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. package de.padde.xmldemo;
  2.  
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5.  
  6. import javax.xml.parsers.ParserConfigurationException;
  7. import javax.xml.parsers.SAXParser;
  8. import javax.xml.parsers.SAXParserFactory;
  9.  
  10. import org.xml.sax.InputSource;
  11. import org.xml.sax.SAXException;
  12. import org.xml.sax.XMLReader;
  13.  
  14. public class XmlReader {
  15.     public static void read(InputStream in) {
  16.         SAXParserFactory spf = SAXParserFactory.newInstance();
  17.         SAXParser sp;
  18.         try {
  19.             sp = spf.newSAXParser();
  20.             XMLReader xr = sp.getXMLReader();
  21.             XmlContentHandler ach = new XmlContentHandler();
  22.             xr.setContentHandler(ach);
  23.             xr.parse(new InputSource(in));
  24.         } catch (ParserConfigurationException e) {
  25.         } catch (SAXException e) {
  26.         } catch (IOException e) {}
  27.     }
  28. }
  29.  
Parsed in 0.038 seconds, using GeSHi 1.0.8.4


XmlDemo
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. package de.padde.xmldemo;
  2.  
  3. import android.app.Activity;
  4. import android.os.Bundle;
  5.  
  6. public class XmlDemo extends Activity {
  7.     public void onCreate(Bundle savedInstanceState) {
  8.         super.onCreate(savedInstanceState);
  9.         setContentView(R.layout.main);
  10.        
  11.         XmlReader.read(this.getResources().openRawResource(R.raw.test));
  12.     }
  13. }
  14.  
Parsed in 0.037 seconds, using GeSHi 1.0.8.4


test.xml in res/raw
Syntax: [ Download ] [ Hide ]
Using xml Syntax Highlighting
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <text>43.691987,7.245054</text>
  3.  
Parsed in 0.001 seconds, using GeSHi 1.0.8.4


The above example works fine for me.. tested under 1.5 and 1.6.
Attachments
XmlDemo.rar
Complete Project (Eclipse Galileo) for convenience.
(30.14 KiB) Downloaded 183 times
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Postby Fluckysan » Sat Sep 26, 2009 6:11 pm

Yep I know it's working but my bug is very random :/
It happen just sometimes and the file is online
The problem may come from the online part, how can I copy the file localy and parse from this local file ?

Thx for your help
Fluckysan
Junior Developer
Junior Developer
 
Posts: 17
Joined: Wed Jul 01, 2009 7:57 am

Top

Postby padde » Sat Sep 26, 2009 9:22 pm

I will extract some code from a project of mine where i used to store the xml files on a remote DB.
The Android client then calls a php script on the server which first encrypt the xml content (because of
some security risk potential in my case) and then encode it to base64.
With that approach i had never even random bugs and i used to transmit far more complex xml content
so it should work for you too ;)

Let me know if the code for this kind of approach would help you or which specific part you need.


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

Postby Fluckysan » Sat Sep 26, 2009 10:06 pm

Ho thx your solution seems great :o
But I don't want to do it in a server side
I want the client parse the XML himself

So this is the idea :
  • Get the remote and create a local copy ===> I already do that, I copy the file on a Document object (XML)
  • Use this local XML file on my SAXParser ===> I don't know how to do this part :s
How can I use the Document to create a InputSource (or an InputStream) ?

Regards
Fluckysan
Junior Developer
Junior Developer
 
Posts: 17
Joined: Wed Jul 01, 2009 7:57 am

Postby padde » Sat Sep 26, 2009 10:58 pm

Okay so you have a remote xml file like http://www.mywebsite/parseme.xml
and want to parse this file in android right?!

I dont realy get it what you plan to do.. and why you want a local copy on the device.


-- edit ---
okay i googled a few minutes and i think i know now where the problem is..
what you need is a way to convert a DOM document as input for the SAX parser.
Unfortunately this isnt a trivial task and involves a lot of work and isnt good for performance
at all. You should stick with SAX from the beginning.
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Postby Fluckysan » Sun Sep 27, 2009 1:22 pm

padde wrote:Okay so you have a remote xml file like http://www.mywebsite/parseme.xml
and want to parse this file in android right?!

I dont realy get it what you plan to do.. and why you want a local copy on the device.

Yep just as the example :)
I just want to parse this file on my application to use it
It works fine but sometimes there is this bug :/
I tried to put the XML file on differents servers but it doesn't change anything

The strange thing is my code is the same as the example
I have a "refresh" button which parse again the file on my application, the bug comes sometimes when I "refresh"

I don't know how the URL.openStream works but I think the bug is here because the file isn't enterely loaded (Here you catch my idea to copy the file localy)
Tell me if I'm wrong :o

Thx for your interest !
Fluckysan
Junior Developer
Junior Developer
 
Posts: 17
Joined: Wed Jul 01, 2009 7:57 am

Postby padde » Sun Sep 27, 2009 4:26 pm

Aaaah thats what you meant with local copy.. sorry that i just get it now.. but for me this isnt realy a
local copy.

I have no idea why URL.openStream should fail here but personally i prefer DefaultHttpClient.
Dont know exactly why to be honest.. maybe its the first method i tried that worked for me and now
i reuse it all the time :)

Where is the difference anyway between HttpClient and UrlConnection?! As far as i know you can do anything
with both.. more or less comfortable.

Never mind... please try this modified onCreate in the demo project from me.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2.     public void onCreate(Bundle savedInstanceState) {
  3.  
  4.         super.onCreate(savedInstanceState);
  5.  
  6.         setContentView(R.layout.main);
  7.  
  8.  
  9.  
  10.         DefaultHttpClient httpclient;  
  11.  
  12.         HttpResponse response;
  13.  
  14.         HttpEntity entity;
  15.  
  16.         HttpGet get;
  17.  
  18.          
  19.  
  20.         try {
  21.  
  22.             httpclient = new DefaultHttpClient();    
  23.  
  24.             get = new HttpGet("http://padde.sytes.net/test.xml");
  25.  
  26.             response = httpclient.execute(get);
  27.  
  28.             entity = response.getEntity();
  29.  
  30.                      
  31.  
  32.             InputStream is = entity.getContent();
  33.  
  34.             XmlReader.read(is);
  35.  
  36.             is.close();
  37.  
  38.                
  39.  
  40.             if (entity != null) entity.consumeContent();
  41.  
  42.         } catch (ClientProtocolException e) { e.printStackTrace();
  43.  
  44.         } catch (IOException e) { e.printStackTrace(); }
  45.  
  46.     }
  47.  
  48.  
Parsed in 0.038 seconds, using GeSHi 1.0.8.4


Dont forget to replace the URL with yours ;)
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Postby Fluckysan » Sun Sep 27, 2009 5:06 pm

Hum interesting solution in there !

I'm trying it and it seems to work !
No more bug for the moment (Well kind of, another one but it's not related) :D
The URLConnection and the DefaultHttp may be differents :o

Thx very much Padde and sorry for my mistell about the "local" file :p
Fluckysan
Junior Developer
Junior Developer
 
Posts: 17
Joined: Wed Jul 01, 2009 7:57 am

Postby padde » Mon Sep 28, 2009 3:49 am

Nice to hear that this seems to solve the problem.. even though neither one of us can really
explain why :D
padde
Master Developer
Master Developer
 
Posts: 443
Joined: Wed Apr 08, 2009 4:52 pm

Thank you

Postby DavidLau » Tue Oct 13, 2009 8:42 am

Thank you!the tutorial is helpfull ...


padde wrote:This sample code parse...
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. package de.XMLparser;
  2.  
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.util.Vector;
  6.  
  7. import javax.xml.parsers.ParserConfigurationException;
  8. import javax.xml.parsers.SAXParser;
  9. import javax.xml.parsers.SAXParserFactory;
  10.  
  11. import org.xml.sax.Attributes;
  12. import org.xml.sax.InputSource;
  13. import org.xml.sax.SAXException;
  14. import org.xml.sax.XMLReader;
  15. import org.xml.sax.helpers.DefaultHandler;
  16.  
  17. import android.app.Activity;
  18. import android.os.Bundle;
  19. import android.widget.TextView;
  20.  
  21. class ParsedExampleDataSet {
  22.     private String schoolname;
  23.     private String studentname;
  24.     private String studentage;
  25.     private String studentaddress;
  26.     private String schooladdress;
  27.  
  28.     public String toString() {
  29.         return "Student's Name: " + studentname + "n" + "Student's Address: "
  30.                 + studentaddress + "n" + "Student's Age: " + studentage
  31.                 + "nn" + "School's Name: " + schoolname + "n"
  32.                 + "School's Address: " + schooladdress;
  33.     }
  34.    
  35.     public String getSchoolName() { return schoolname; }
  36.     public void setSchoolName(String schoolname) { this.schoolname = schoolname; }
  37.     public String getStudentName() { return studentname; }
  38.     public void setStudentName(String studentname) { this.studentname = studentname; }
  39.     public String getStudentAge() { return studentage; }
  40.     public void setStudentAge(String studentage) { this.studentage = studentage; }
  41.     public String getStudentAddress() { return studentaddress; }
  42.     public String getSchoolAddress() { return schooladdress; }
  43.     public void setStudentAddress(String studentaddress) {
  44.         this.studentaddress = studentaddress;
  45.     }
  46.     public void setSchoolAddress(String schooladress) {
  47.         this.schooladdress = schooladress;
  48.     }
  49. }
  50.  
  51. class ContentHandler extends DefaultHandler {
  52.     private enum Tags {
  53.         Test, Name, Age, School, Student, Address, Entry
  54.     }
  55.    
  56.     private boolean in_schoolTag = false;
  57.     private boolean in_studentTag = false;
  58.    
  59.     private ParsedExampleDataSet DataSet;
  60.     private Vector<ParsedExampleDataSet> MyParsedExampleDataSets;
  61.    
  62.    
  63.     public ContentHandler() {
  64.         super();
  65.         this.MyParsedExampleDataSets = new Vector<ParsedExampleDataSet>();
  66.     }
  67.  
  68.     public Vector<ParsedExampleDataSet> getParsedExampleDataSets() {
  69.         return this.MyParsedExampleDataSets;
  70.     }
  71.    
  72.     public void startDocument() throws SAXException { }
  73.     public void endDocument() throws SAXException { }
  74.  
  75.     public void startElement(String n, String l, String q, Attributes a) {
  76.          switch(Tags.valueOf(l)) {
  77.              case School:
  78.                  in_schoolTag = true;
  79.                  break;
  80.              case Student:
  81.                  in_studentTag = true;
  82.                  break;
  83.              case Address:
  84.                  if(in_studentTag)
  85.                      DataSet.setStudentAddress(a.getValue("displayname"));
  86.                  if(in_schoolTag)
  87.                      DataSet.setSchoolAddress(a.getValue("displayname"));
  88.                  break;
  89.              case Age:
  90.                  DataSet.setStudentAge(a.getValue("value"));
  91.                  break;
  92.              case Name:
  93.                  if(in_studentTag)
  94.                      DataSet.setStudentName(a.getValue("displayname"));
  95.                  if(in_schoolTag)
  96.                      DataSet.setSchoolName(a.getValue("displayname"));
  97.                  break;
  98.              case Entry:
  99.                  DataSet = new ParsedExampleDataSet();
  100.                  break;
  101.          }
  102.     }
  103.      
  104.     public void endElement(String n, String l, String q) {
  105.         switch(Tags.valueOf(l)) {
  106.             case School:
  107.                 in_schoolTag = false;
  108.                 break;
  109.             case Student:
  110.                 in_studentTag = false;
  111.                 break;
  112.             case Entry:
  113.                 MyParsedExampleDataSets.add(DataSet);
  114.                 break;
  115.         }
  116.     }
  117.      
  118.     public void characters(char ch[], int start, int length) { }
  119. }
  120.  
  121. public class XMLparserSample extends Activity {
  122.     private TextView myTextView;
  123.    
  124.     public void onCreate(Bundle savedInstanceState) {
  125.         super.onCreate(savedInstanceState);
  126.        
  127.         setContentView(R.layout.main);
  128.        
  129.         Vector<ParsedExampleDataSet> test = read(getResources().openRawResource(R.raw.sample));
  130.        
  131.         String text = "";
  132.         for(int i=0; i < test.size(); i++)
  133.             text += test.get(i).toString()+"n-------------------------n";
  134.        
  135.         myTextView = (TextView) findViewById(R.id.textview);        
  136.         myTextView.setText(text);
  137.     }
  138.    
  139.     public Vector<ParsedExampleDataSet> read(InputStream in) {
  140.         SAXParserFactory spf = SAXParserFactory.newInstance();
  141.         SAXParser sp;
  142.         try {
  143.             sp = spf.newSAXParser();
  144.             XMLReader xr = sp.getXMLReader();
  145.             ContentHandler ch = new ContentHandler();
  146.             xr.setContentHandler(ch);
  147.             xr.parse(new InputSource(in));
  148.             return ch.getParsedExampleDataSets();                
  149.         } catch (ParserConfigurationException e) {
  150.         } catch (SAXException e) {
  151.         } catch (IOException e) {}
  152.         return null;
  153.     }    
  154. }
  155.  
Parsed in 0.060 seconds, using GeSHi 1.0.8.4


...this sample.xml in the res/raw folder...
Syntax: [ Download ] [ Hide ]
Using xml Syntax Highlighting
  1. <?xml version="1.0"?>
  2. <Test>
  3.     <Entry>
  4.         <Student>
  5.             <Name displayname = "Jane"/>
  6.             <Address displayname = "ABC"/>
  7.             <Age value = "20"/>
  8.         </Student>
  9.         <School>
  10.             <Name displayname = "NTUST"/>
  11.             <Address displayname = "123"/>
  12.         </School>
  13.     </Entry>
  14.     <Entry>
  15.         <Student>
  16.             <Name displayname = "Jane2"/>
  17.             <Address displayname = "ABCD"/>
  18.             <Age value = "21"/>
  19.         </Student>
  20.         <School>
  21.             <Name displayname = "NTUST2"/>
  22.             <Address displayname = "1234"/>
  23.         </School>
  24.     </Entry>
  25. </Test>
  26.  
Parsed in 0.004 seconds, using GeSHi 1.0.8.4


... and shows the results in the TextView of this main.xml in res/layout
Syntax: [ Download ] [ Hide ]
Using xml Syntax Highlighting
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.    android:orientation="vertical"
  4.    android:layout_width="fill_parent"
  5.    android:layout_height="fill_parent"
  6. >
  7. <TextView  
  8.    android:id="@+id/textview"
  9.    android:layout_width="fill_parent"
  10.    android:layout_height="wrap_content"
  11. />
  12. </LinearLayout>
  13.  
Parsed in 0.002 seconds, using GeSHi 1.0.8.4


Greets
Padde
A chinese man
DavidLau
Freshman
Freshman
 
Posts: 3
Joined: Fri Aug 14, 2009 9:31 am

getting information before whole xml file has been read

Postby steven_d » Wed Oct 14, 2009 11:22 am

Hello,

i have a big xml file and i want to use the SaxParser because i've read, that this is faster than DOM and XmlPullParser.
But now I want to get some information, before the parser has read the whole xml-file.

<?xml version="1.0" encoding="utf-8"?>
<gpx...>
<wpt lat="yyy" lon="yyy">
<desc value="a street "/>
</wpt>
OTHER WAYPOINTS
...
...
<trk>
<name>HUHU</name>
<trkseg>
<trkpt lat="xxx" lon="yyyy"></trkpt>
VERY MUCH TRACKPOINTS!!!
</trkseg>
</trk>
<gpx>

If all waypoints has been read, i want to work with that data.
And can I told the SaxParser, that i want to read the trackpoints step by step (for example the first 20 trackpoints will be returned and then the next 20 points and so on)?

Thanks,
Stefan

PS: I have the same classes like +- (with my xml tags of course)
steven_d
Junior Developer
Junior Developer
 
Posts: 12
Joined: Mon Jul 20, 2009 1:15 pm
Location: Germany

Top
PreviousNext

Return to Novice Tutorials

Who is online

Users browsing this forum: No registered users and 4 guests