آموزش Parse(تجزیه) Xml از سرور در اندروید

سلام دوستان در این سری از آموزش برنامه نویسی اندروید به آموزش Parse(تجزیه) Xml از سرور در اندروید می پردازیم در آموزش قبلی Parse(تجزیه) xml را از پوشه assets قرار دادیم در این آموزش به Parse(تجزیه) Xml از سرور می پردازیم و نحوه کار به این شکل است که ابتدا داده Xml از سرور دریافت می شود سپس آن را Parse یا تجزیه می کنیم ر ادامه با ما همراه باشید تا نحوه Parse(تجزیه) Xml از سرور در اندروید را یاد گیرید.
 
از لینک زیر می توانید به آموزش قبلی پارس Xml در اندروید استفاده کنید.

آموزش parse (تجزیه) XML در برنامه نویسی اندروید

package ir.programchi.xmlparsing;
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import android.util.Log;
public class XMLParser {
	public XMLParser() {
	}
	public String getXmlFromUrl(String url) {
		String xml = null;
		try {
			DefaultHttpClient httpClient = new DefaultHttpClient();
			HttpPost httpPost = new HttpPost(url);
			HttpResponse httpResponse = httpClient.execute(httpPost);
			HttpEntity httpEntity = httpResponse.getEntity();
			xml = EntityUtils.toString(httpEntity);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		// return XML
		return xml;
	}
	public Document getDomElement(String xml){
		Document doc = null;
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		try {
			DocumentBuilder db = dbf.newDocumentBuilder();
			InputSource is = new InputSource();
		        is.setCharacterStream(new StringReader(xml));
		        doc = db.parse(is);
			} catch (ParserConfigurationException e) {
				Log.e("Error: ", e.getMessage());
				return null;
			} catch (SAXException e) {
				Log.e("Error: ", e.getMessage());
	            return null;
			} catch (IOException e) {
				Log.e("Error: ", e.getMessage());
				return null;
			}
	        return doc;
	}
	 public final String getElementValue( Node elem ) {
	     Node child;
	     if( elem != null){
	         if (elem.hasChildNodes()){
	             for( child = elem.getFirstChild(); child != null; child = child.getNextSibling() ){
	                 if( child.getNodeType() == Node.TEXT_NODE  ){
	                     return child.getNodeValue();
	                 }
	             }
	         }
	     }
	     return "";
	 }
	 public String getValue(Element item, String str) {
			NodeList n = item.getElementsByTagName(str);
			return this.getElementValue(n.item(0));
		}
}

کد بالا کار ما را راحتر خواهد کرد چندین متد مختلف برای گرفتن نودها گرفتن فایل xml از سرور وجود دارد.
ما  دوتا اکتیویتی داریم یک اکتیویتی که List است و آیتم های پارس شده را نشان میدهد و اکتیویتی دوم هم با کلیک بروی هر آیتم اطلاعات مربوط به آن را در اکتیویتی دیگر نمایش داده می شود.
یک فایل به نام list_item.xml در layout ایجاد کنید و کدهای زیر را در آن قرار دهید (شکل آیتم های List را تعیین می کند)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <TextView
            android:id="@+id/name"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textColor="#dc6800"
            android:textSize="16sp"
            android:textStyle="bold"
            android:paddingTop="6dip"
            android:paddingBottom="2dip" />
        <TextView
            android:id="@+id/desciption"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textColor="#acacac"
            android:paddingBottom="2dip">
        </TextView>
        <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#5d5d5d"
            android:gravity="left"
            android:textStyle="bold"
            android:text="Cost: " >
        </TextView>
        <TextView
            android:id="@+id/cost"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#acacac"
            android:textStyle="bold"
            android:gravity="left">
        </TextView>
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

کد بالا شکل ظاهری هر آیتم List را ایجاد می کند.
یک فایل به نام activity_main.xml ایجاد کنید و کدهای زیر را در آن قرار دهید.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">
    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>

این کد layout اصلی است که یک ListView در آن قرار گرفته است.
حالا باید یک اکتیویتی به نام MainActivity.java ایحاد کنید و کدهای زیر را در آن قرار دهید.

package ir.programchi.xmlparsing;
import java.util.ArrayList;
import java.util.HashMap;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
public class MainActivity extends ListActivity {
	static final String URL = "http://orjinakteb.com/api/Xml_data.xml";
	static final String KEY_ITEM = "item";
	static final String KEY_ID = "id";
	static final String KEY_NAME = "name";
	static final String KEY_COST = "cost";
	static final String KEY_DESC = "description";
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();
		XMLParser parser = new XMLParser();
		String xml = parser.getXmlFromUrl(URL);
		Document doc = parser.getDomElement(xml);
		NodeList nl = doc.getElementsByTagName(KEY_ITEM);
		for (int i = 0; i < nl.getLength(); i++) {
			HashMap<String, String> map = new HashMap<String, String>();
			Element e = (Element) nl.item(i);
			map.put(KEY_ID, parser.getValue(e, KEY_ID));
			map.put(KEY_NAME, parser.getValue(e, KEY_NAME));
			map.put(KEY_COST, "Rs." + parser.getValue(e, KEY_COST));
			map.put(KEY_DESC, parser.getValue(e, KEY_DESC));
			menuItems.add(map);
		}
		ListAdapter adapter = new SimpleAdapter(this, menuItems,
				R.layout.list_item,
				new String[] { KEY_NAME, KEY_DESC, KEY_COST }, new int[] {
						R.id.name, R.id.desciption, R.id.cost });
		setListAdapter(adapter);
		ListView lv = getListView();
		lv.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				String name = ((TextView) view.findViewById(R.id.name)).getText().toString();
				String cost = ((TextView) view.findViewById(R.id.cost)).getText().toString();
				String description = ((TextView) view.findViewById(R.id.desciption)).getText().toString();
				Intent in = new Intent(getApplicationContext(), SingleMenuItemActivity.class);
				in.putExtra(KEY_NAME, name);
				in.putExtra(KEY_COST, cost);
				in.putExtra(KEY_DESC, description);
				startActivity(in);
			}
		});
	}
}

در بالا ما یکسری متغیر تعریف کردیم که node های ما در xml دریافت شده خواهند ما باید بر اساس هر node بیایم داده ها را parse کنیم ابتدا با استفاده از متد getXmlFromUrl که خودمان نوشتیم فایل را از سرور می خوانیم بعد از این کار میایم آرایه از Hashmap ایجاد می کنیم سپس یک آداپتور از نوع List درست می کنیم و به ListView می دهیم.
در بالا ممکن است SingleMenuItemActivity خطا دهد چون هنوز این اکتیویتی را ایجاد نکرده اید.
یک layout به نام single_list_item.xml ایجاد کنید و کدهای زیر را در آن قرار دهید.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="match_parent"
  android:layout_height="match_parent">
  <TextView android:id="@+id/name_label"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textSize="25dip"
            android:textStyle="bold"
            android:paddingTop="10dip"
            android:paddingBottom="10dip"
            android:textColor="#dc6800"/>
  <TextView android:id="@+id/description_label"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textColor="#acacac"/>
  <TextView android:id="@+id/cost_label"
      		android:layout_width="fill_parent"
      		android:layout_height="wrap_content"
      		android:textStyle="bold"/>
</LinearLayout>

بعد از انتخاب هر آیتم از Listview اطلاعات از آن اکتیویتی به این اکتیویتی فرستاده می شود.
و در آخر کد مربوط به اکتیویتی آن همانند زیر خواهد بود یک اکتیویتی به نام SingleMenuItemActivity.java ایجاد کنید و کدهای زیر را در آن قرار دهید.

package ir.programchi.xmlparsing;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
public class SingleMenuItemActivity  extends Activity {
	static final String KEY_NAME = "name";
	static final String KEY_COST = "cost";
	static final String KEY_DESC = "description";
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.single_list_item);
        Intent in = getIntent();
        String name = in.getStringExtra(KEY_NAME);
        String cost = in.getStringExtra(KEY_COST);
        String description = in.getStringExtra(KEY_DESC);
        TextView lblName = (TextView) findViewById(R.id.name_label);
        TextView lblCost = (TextView) findViewById(R.id.cost_label);
        TextView lblDesc = (TextView) findViewById(R.id.description_label);
        lblName.setText(name);
        lblCost.setText(cost);
        lblDesc.setText(description);
    }
}

در اینجا اطلاعات فرستاده از اکتیویتی قبل را گرفته و نمایش میدهیم.
 
این آموزش هم به پایان رسید.
موفق باشید.
 

مطالعه بیشتر