Parse XML Data Into Classes And Save To The Sdcard

  • (2 Pages)
  • +
  • 1
  • 2

27 Replies - 2828 Views - Last Post: 03 December 2011 - 08:42 PM

#1 EndLessMind  Icon User is offline

  • These are the droids you're looking for
  • member icon

Reputation: 193
  • View blog
  • Posts: 1,097
  • Joined: 13-March 09

Parse XML Data Into Classes And Save To The Sdcard

Posted 28 November 2011 - 04:07 PM

Hi!

I wish to send some custom item from my c#-server app(PC) to my Android-client.
The items contains 11 properties. But for my purposes i don't need more then 3-4 of them.

So, my question is, how to i handle the data that the client receive and save i to sd?


Thanks in advance :)

Is This A Good Question/Topic? 0
  • +

Replies To: Parse XML Data Into Classes And Save To The Sdcard

#2 H3R3T1C  Icon User is offline

  • Android Expert
  • member icon

Reputation: 276
  • View blog
  • Posts: 757
  • Joined: 30-March 07

Re: Parse XML Data Into Classes And Save To The Sdcard

Posted 28 November 2011 - 04:34 PM

Ok so say this is the class on android that will be holding our data:
/**
 *
 * @author Thomas Otero (H3R3T1C)
 * Email: th3h3r3t1c@gmail.com
 */
public class MyDataClass implements Serializable {

    private int property1;
    private double property2;
    private boolean property3;
    private String property4;
    // you get how it works it can by any primitive type or other classes that also implement serialiable!

    public MyDataClass()
    {

    }
    public int getProperty1() {
        return property1;
    }

    public void setProperty1(int property1) {
        this.property1 = property1;
    }

    public double getProperty2() {
        return property2;
    }

    public void setProperty2(double property2) {
        this.property2 = property2;
    }

    public boolean isProperty3() {
        return property3;
    }

    public void setProperty3(boolean property3) {
        this.property3 = property3;
    }

    public String getProperty4() {
        return property4;
    }

    public void setProperty4(String property4) {
        this.property4 = property4;
    }


}


And then say this the xml code we want to parse that came from our server:
<?xml version="1.0" encoding="UTF-8"?>
<items>
	<Entry property1="100" property2="2.3" property3="false" property4="some string" />
	...
</item>


as you can see the value for each property in the xml matches the data types in our class!

now the easiest way to parse your data would be to use the SAXParser like so:
public void parseData(InputStream is)
    {
        /* Get a SAXParser from the SAXPArserFactory. */
        try{
            SAXParserFactory spf = SAXParserFactory.newInstance();
            SAXParser sp = spf.newSAXParser();
            MyXmlHandler xmlh = new MyXmlHandler();
            sp.parse(is, xmlh);
            List<MyDataClass> data = xmlh.getData();

        }catch(Exception e)
        {
            // print errors to logcat!
        }
    }


As you can see we have a new class called MyXmlHandler. This class handles all the parsing!
import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 *
 * @author Thomas Otero (H3R3T1C)
 * Email: th3h3r3t1c@gmail.com
 */
class MyXmlHandler extends DefaultHandler{

    private List<MyDataClass> data;

    public MyXmlHandler()
    {
        data = new ArrayList<MyDataClass>();
    }
    public List<MyDataClass> getData()
    {
        return data;
    }
    @Override
    public void startElement(String uri, String localName, String qName, Attributes att) throws SAXException {

        if(qName.equalsIgnoreCase("entry"))
        {
            MyDataClass e= new MyDataClass();
            e.setProperty1(Integer.parseInt(att.getValue("property1")));
            e.setProperty2(Double.parseDouble(att.getValue("property2")));
            e.setProperty3(Boolean.valueOf(att.getValue("property3")));
            e.setProperty4(att.getValue("property4"));
            data.add(e);
        }
    }

}




For more detailed info on how to use the SAXParser check out this tutorial: http://www.anddev.or...arser-t353.html

Now that we have our xml data parsed and in a list we can use ObjectStreams to save and load our data.
I already posted a snippet on how to save and load object in android: http://www.dreaminco...snippet5845.htm

If any of this is too confusing please reply back and I will explain it in greater detail :D.
Was This Post Helpful? 1
  • +
  • -

#3 EndLessMind  Icon User is offline

  • These are the droids you're looking for
  • member icon

Reputation: 193
  • View blog
  • Posts: 1,097
  • Joined: 13-March 09

Re: Parse XML Data Into Classes And Save To The Sdcard

Posted 28 November 2011 - 05:14 PM

Hm.. so i can use
Dim strm as New Stream
 Public Sub Make_XML_Settings(ByVal s As String)
        'this is an xml literal - I like the way it looks.
        Dim sXml = <?xml version="1.0" encoding="utf-8"?>
                   <items>
                      <Entry/>
                   </items>
        Dim xl As New XmlDocument
        xl.LoadXml(sXml.ToString)
        
        xl.Save(strm)
        xl = Nothing 'disposes xml cached memory.
    End Sub


and then use something like
 Make_XML_Settings(s)
        Dim xl As New XmlDocument
        xl.Load(strm )
        For Each l As myGrid.LabelValues In myLabels
            Dim elem As XmlNode = xl.CreateElement("Entry")
            Dim property1 As XmlAttribute = xl.CreateAttribute("property1")
            atrTag.Value = "A Value"
            Dim property2 As XmlAttribute = xl.CreateAttribute("property1")
            atrColor.Value = "A value"
            elem.Attributes.Append(property1)
            elem.Attributes.Append(property2)
            xl.SelectSingleNode("//items").AppendChild(elem)
        Next
xl.Save(strm)



and then send that stream?

And use the code you provided and handle the data when it arrives? :)

This post has been edited by EndLessMind: 28 November 2011 - 05:15 PM

Was This Post Helpful? 0
  • +
  • -

#4 EndLessMind  Icon User is offline

  • These are the droids you're looking for
  • member icon

Reputation: 193
  • View blog
  • Posts: 1,097
  • Joined: 13-March 09

Re: Parse XML Data Into Classes And Save To The Sdcard

Posted 28 November 2011 - 09:41 PM

Okey, i've tried it for some hours now, but i only get 2 results
1. The app stop responding, or
2. Nothing happen and the socket closes.

I tried just saving the XML-document to a MemoryStream and then send it, and i tried saving it to a StingWriter and then send it. But got the same result on both.

Here is my code for the Android client that listens for incoming data
public class ClientThread implements Runnable {
			public void run() {
				try {

					Log.d("ClientActivity", "Tråd startad");
					connected = true;
					while (socket.isConnected()) {
						Log.i("ClientActivity", "Väntar på meddelande från servern");
						//final String in = new BufferedReader(new InputStreamReader( _InPut)).readLine();
						try {
					    	parseData(_InPut);
					    	} catch (Exception e) {
					    		Log.e("ClientActivity" , e.getMessage().toString());
					    	}
						

						try {
						//Log.d("ClientActivity","" + in);						
						Log.i("ClientActivity", "Har mottaigt ett meddelande från servern: " );
						//Log.d("ClientActivity", "Kör!");
					} catch (Exception e) {
								Log.e("ClientActivity", "S: Error " + e.getMessage(),e);
						}
					}
					socket.close();
				} catch (Exception e) {
					Log.e("ClientActivity", "C: Error " + e.getMessage(), e);
				
				}
			}
		}
		


and here is the parseData void, that i added some lines for code to display something when the data has been processed, so i know that is has arrived
public void parseData(InputStream is) {
	
	try{
		SAXParserFactory spf = SAXParserFactory.newInstance();
		SAXParser sp = spf.newSAXParser();
		MyXmlHandler xmlh = new MyXmlHandler();
		sp.parse(is, xmlh);
		final List<Movies> data = xmlh.getData();
		MovieList = data;
		Log.d("ClientActivity", "" + data.size());
		for(int i = 0; i < data.size() -1; i++) {
			final int i2 = i;
			handler.post(new Runnable() {
			    public void run() {
			    	
			        Toast.makeText(StartServer.this, data.get(i2).getprop4(), Toast.LENGTH_SHORT).show();
			       // stringlist.add(data.get(i2).getprop4());
			        //stringAdapter = new CustomAdapter(StartServer.this, R.layout.list_item, stringlist);
			    	//listview.setAdapter(stringAdapter);
			    }
			});
		}
	} catch (Exception e) {
		Log.e("ClientActivity",e.getMessage().toString());
	}
}


The LogCat do not give me any error.
And i only tried to send 10 items, just for testing.

EDIT:

This is the code the server currently uses to send the data
public void Save()
        {
            // Make_XML_Settings()
            XDocument sXml = new XDocument(new XDeclaration("1.0", "utf-8", "yes"), new XElement("items", new XElement("entry")));
            XmlDocument xl = new XmlDocument();
            xl.LoadXml(sXml.ToString());
            for (int i = 0; i < 9; i++)
            {
                XmlNode elem = xl.CreateElement("entry");
                XmlAttribute prop1 = xl.CreateAttribute("prop1");
                prop1.Value = i.ToString();
                XmlAttribute prop2 = xl.CreateAttribute("prop2");
                prop2.Value = i.ToString();
                XmlAttribute prop3 = xl.CreateAttribute("prop3");
                prop3.Value = true.ToString();
                XmlAttribute prop4 = xl.CreateAttribute("prop4");
                prop4.Value = "Namn " + i.ToString();
                elem.Attributes.Append(prop1);
                elem.Attributes.Append(prop2);
                elem.Attributes.Append(prop3);
                elem.Attributes.Append(prop4);
                xl.SelectSingleNode("//items").AppendChild(elem);
                Console.WriteLine(i);
            }
          
            //yaz = new StreamWriter(ag);
            var wr = new StringWriter();
            xl.Save(wr); //Application.StartupPath + "\\du.xml");
          //  yaz.Flush();
            yaz = new StreamWriter(ag);
            yaz.Write(wr.GetStringBuilder().ToString());
            yaz.Flush();

        }


ag is a NetworkStream and yaz is a StreamWriter

This post has been edited by EndLessMind: 28 November 2011 - 09:44 PM

Was This Post Helpful? 0
  • +
  • -

#5 H3R3T1C  Icon User is offline

  • Android Expert
  • member icon

Reputation: 276
  • View blog
  • Posts: 757
  • Joined: 30-March 07

Re: Parse XML Data Into Classes And Save To The Sdcard

Posted 28 November 2011 - 09:54 PM

First you say MovieList = data; but on the line above it you say final List<Movies> data = xmlh.getData();. Does the MovieList class extend List<Movies> ?
Also when you did this: final String in = new BufferedReader(new InputStreamReader( _InPut)).readLine(); were you getting any string data? if so what was it?
Was This Post Helpful? 0
  • +
  • -

#6 EndLessMind  Icon User is offline

  • These are the droids you're looking for
  • member icon

Reputation: 193
  • View blog
  • Posts: 1,097
  • Joined: 13-March 09

Re: Parse XML Data Into Classes And Save To The Sdcard

Posted 28 November 2011 - 10:04 PM

MovieList was only a variable (private List<Movies> MovieList;)
I removed that but no change.

about:
final String in = new BufferedReader(new InputStreamReader( _InPut)).readLine();

it only gives me <?xml version="1.0" encoding="utf-8"?>
So, that a problem.
But if i write the same string out in the console one the server, just before i send it, then i contains all the correct data. hm..

Edit:
The "readLine();" only displays the first line...

This post has been edited by EndLessMind: 28 November 2011 - 10:06 PM

Was This Post Helpful? 0
  • +
  • -

#7 H3R3T1C  Icon User is offline

  • Android Expert
  • member icon

Reputation: 276
  • View blog
  • Posts: 757
  • Joined: 30-March 07

Re: Parse XML Data Into Classes And Save To The Sdcard

Posted 28 November 2011 - 10:12 PM

Ok MovieList threw me off because only classes should start with a capital letter where variable start with a lowercase letter and every new word in the variable is capitalized so it should be movieList but it makes no difference on how the code works its just how you 'properly' name your variables ;)

what does the xml look like on the server when you print it to the console? Also whats your code for the MyXmlHandler class.
Was This Post Helpful? 0
  • +
  • -

#8 EndLessMind  Icon User is offline

  • These are the droids you're looking for
  • member icon

Reputation: 193
  • View blog
  • Posts: 1,097
  • Joined: 13-March 09

Re: Parse XML Data Into Classes And Save To The Sdcard

Posted 28 November 2011 - 10:48 PM

Hehe :P

Well, i found what made i hang.
the xml looked like this
<?xml version="1.0" encoding="utf-16"?>
<items>
  <entry />
  <entry prop1="0" prop2="0" prop3="True" prop4="Namn 0" />
  <entry prop1="1" prop2="1" prop3="True" prop4="Namn 1" />
  <entry prop1="2" prop2="2" prop3="True" prop4="Namn 2" />
  <entry prop1="3" prop2="3" prop3="True" prop4="Namn 3" />
  <entry prop1="4" prop2="4" prop3="True" prop4="Namn 4" />
  <entry prop1="5" prop2="5" prop3="True" prop4="Namn 5" />
  <entry prop1="6" prop2="6" prop3="True" prop4="Namn 6" />
  <entry prop1="7" prop2="7" prop3="True" prop4="Namn 7" />
  <entry prop1="8" prop2="8" prop3="True" prop4="Namn 8" />
</items>


so i removed the first item and not it looks like
<?xml version="1.0" encoding="utf-16"?>
<items>
  <entry prop1="0" prop2="0" prop3="True" prop4="Namn 0" />
  <entry prop1="1" prop2="1" prop3="True" prop4="Namn 1" />
  <entry prop1="2" prop2="2" prop3="True" prop4="Namn 2" />
  <entry prop1="3" prop2="3" prop3="True" prop4="Namn 3" />
  <entry prop1="4" prop2="4" prop3="True" prop4="Namn 4" />
  <entry prop1="5" prop2="5" prop3="True" prop4="Namn 5" />
  <entry prop1="6" prop2="6" prop3="True" prop4="Namn 6" />
  <entry prop1="7" prop2="7" prop3="True" prop4="Namn 7" />
  <entry prop1="8" prop2="8" prop3="True" prop4="Namn 8" />
</items>



My MyXmlHandler class looks like this,

package com.pontus.MovieHandler;

import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import android.util.Log;

public class MyXmlHandler extends DefaultHandler {

	private List<Movies> data;
	
	public MyXmlHandler() 
	{
		data = new ArrayList<Movies>();
	}
	
	public List<Movies> getData()
	{
		return data;
	}
	
	@Override
	public void startElement(String uri, String localName,String qName,
			Attributes att) throws SAXException {
		if(qName.equalsIgnoreCase("entry"))
		{
			Log.d("MyXmlHandler", "Processing data!");
			Movies e = new Movies();
			e.setprop1(Integer.parseInt(att.getValue("prop1")));
			e.setprop2(Double.parseDouble(att.getValue("prop2")));
			e.setprop3(Boolean.parseBoolean(att.getValue("prop3")));
			e.setprop4(att.getValue("prop4"));
			data.add(e);
			Log.d("MyXmlHandler", "" + data.size());
		}
	}
}




Like you posted but with some Log.d

Now i got i new problem.
As you can see, the Log.d in the MyXmlHandler class displays a "Processing data" and a count of the Arrays size.
When i send the data, i can see that it counts from 0 to 9, that's correct.
But in the parseData void, i put a "Log.d("ClientActivity", "" + data.size());" so i can see when the data is processed. But it never writes that in the log.
Actually is never gets past the "sp.parse(is, xmlh);" in that void.

Sorry for any bad english, but i hope that you understand my problem :)
Was This Post Helpful? 0
  • +
  • -

#9 H3R3T1C  Icon User is offline

  • Android Expert
  • member icon

Reputation: 276
  • View blog
  • Posts: 757
  • Joined: 30-March 07

Re: Parse XML Data Into Classes And Save To The Sdcard

Posted 28 November 2011 - 11:23 PM

So are you getting anything in your logcat from the app?
Was This Post Helpful? 0
  • +
  • -

#10 EndLessMind  Icon User is offline

  • These are the droids you're looking for
  • member icon

Reputation: 193
  • View blog
  • Posts: 1,097
  • Joined: 13-March 09

Re: Parse XML Data Into Classes And Save To The Sdcard

Posted 28 November 2011 - 11:25 PM

Yes, but only
Processing data!
1
Processing data!
2
Processing data!
3
Processing data!
4
Processing data!
5
Processing data!
6
Processing data!
7
Processing data!
8
Processing data!
9


Was This Post Helpful? 0
  • +
  • -

#11 H3R3T1C  Icon User is offline

  • Android Expert
  • member icon

Reputation: 276
  • View blog
  • Posts: 757
  • Joined: 30-March 07

Re: Parse XML Data Into Classes And Save To The Sdcard

Posted 28 November 2011 - 11:27 PM

Ok it may be expecting more data from your server. Do you flush / close the connection on your server end after you have sent over the data?
Was This Post Helpful? 0
  • +
  • -

#12 EndLessMind  Icon User is offline

  • These are the droids you're looking for
  • member icon

Reputation: 193
  • View blog
  • Posts: 1,097
  • Joined: 13-March 09

Re: Parse XML Data Into Classes And Save To The Sdcard

Posted 28 November 2011 - 11:31 PM

Hm.. well, i use flush on the server

            var wr = new StringWriter();
            xl.Save(wr); //Application.StartupPath + "\\du.xml");
            Console.WriteLine(wr.GetStringBuilder().ToString());
            yaz = new StreamWriter(ag);
            wr.Flush();
            yaz.Write(wr.GetStringBuilder().ToString());
            yaz.Flush();


Was This Post Helpful? 0
  • +
  • -

#13 H3R3T1C  Icon User is offline

  • Android Expert
  • member icon

Reputation: 276
  • View blog
  • Posts: 757
  • Joined: 30-March 07

Re: Parse XML Data Into Classes And Save To The Sdcard

Posted 28 November 2011 - 11:32 PM

Try closing the connection to see if that fixes the problem.
Was This Post Helpful? 0
  • +
  • -

#14 EndLessMind  Icon User is offline

  • These are the droids you're looking for
  • member icon

Reputation: 193
  • View blog
  • Posts: 1,097
  • Joined: 13-March 09

Re: Parse XML Data Into Classes And Save To The Sdcard

Posted 28 November 2011 - 11:37 PM

No. The logcat just prints out "Connection reset by peer" and then "socket closed"
Was This Post Helpful? 0
  • +
  • -

#15 EndLessMind  Icon User is offline

  • These are the droids you're looking for
  • member icon

Reputation: 193
  • View blog
  • Posts: 1,097
  • Joined: 13-March 09

Re: Parse XML Data Into Classes And Save To The Sdcard

Posted 29 November 2011 - 10:07 AM

Will try to change so each item only contains one value.
Maybe we can localize the problem then.
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2