Bài tập 29: XML Parser trong Android


– Tiếp tục chuỗi xử lý tập tin trong Android, bài tập này Tôi mong muốn các bạn sẽ làm được những công việc sau:

1) Biết cách tạo XML (tất nhiên rất nhiều bạn đã biết nó từ lâu)

2) Biết cách sử dụng XML

3) Biết cách duyệt XML bằng kỹ thuật DOM

4) Biết cách duyệt XML bằng kỹ thuật SAX.

– Dĩ nhiên  bạn phải thực hiện được 2 bài ví dụ bên dưới thì mới có thể nói là hiểu về XML trong Android.

Extensible Markup Language (XML): Các bạn xem chi tiết tại http://www.w3schools.com/xml/default.asp

———————————————————————————————————–

A)Kỹ thuật dùng DOM:

– DOM (Document Object Model ): Cache all – cơ chế của nó là đọc toàn bộ nội dung tập tin XML vào bộ nhớ (do đó nếu XML lớn thì làm chậm chương trình và có thể phung phí bộ nhớ vì không phải lúc nào ta cũng muốn đọc hết nội dung XML).

– DOM cho phép lấy: NodeLists, .getElementsByTagName() , .item(i), .getName() , .getValue() , .getFirstChild() , .getAttributes(),…

Ta lướt qua ví dụ này (cần dùng DOM để đọc XML bên dưới lên EditText):

29_xml_0

– Ta đi vào các bước cụ thể để đọc được tập tin XML bằng DOM như sau:

——————————————————————————————————————–

Bước 1: 

Để có thể sử dụng được kỹ thuật DOM trong Android, chúng ta import các thư viện sau (kể cả những thư viện để bắt lỗi):


import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

– Các bạn chú ý là trong quá trình viết code trong Eclipse, nó sẽ tự import tất cả các thư viện trên giùm ta (Bạn không phải gõ import dòng nào cả).

Bước 2:

Tạo đối tượng DocumentBuilder (builder ) bằng lệnh dưới đây:


DocumentBuilderFactory fac=DocumentBuilderFactory.newInstance();
 DocumentBuilder builder=fac.newDocumentBuilder();

Bước 3:

Tạo FileInputStream từ tập tin XML nguồn (ở đây Tôi để XML nguồn trong SD Card):


String sdcard=Environment.getExternalStorageDirectory().getAbsolutePath();
 String xmlfile=sdcard+"/employee.xml";
 FileInputStream fIn=new FileInputStream(xmlfile);

Bước 4:

Dùng phương thức parse của đối tượng builder ở bước 2 để tạo Document


Document doc=builder.parse(fIn);

Bước 5:

Ta dựa vào đối tược doc được tạo ra ở bước 4 để duyệt từng node trong XML:


Element root= doc.getDocumentElement(); //lấy tag Root ra
 NodeList list= root.getChildNodes();// lấy toàn bộ node con của Root
 String datashow="";//biến để lưu thông tin
 for(int i=0;i	<list.getLength();i++) // duyệt từ node đầu tiên cho tới node cuối cùng
 {
 Node node=list.item(i);// mỗi lần duyệt thì lấy ra 1 node
 if(node instanceof Element) // kiểm tra xem node đó có phải là Element hay không, vì ta dựa vào element để lấy dữ liệu bên trong
 {
 Element employee=(Element) node;// lấy được tag Employee ra
 String id=employee.getAttribute("id");//id là thuộc tính của tag Employee
 String title=employee.getAttribute("title");//title là thuộc tính của tag employee
 NodeList listChild= employee.getElementsByTagName("name");// lấy tag name bên trong của tag Employee
 String name=listChild.item(0).getTextContent();//lấy nội dung của tag name
 listChild=employee.getElementsByTagName("phone");// lấy tag phone bên trong của tag Employee
String phone=listChild.item(0).getTextContent();// lấy nội dung của tag phone</span>
 datashow+=id+"-"+title+"-"+name+"-"+phone+"\n---------\n";//lưu vào biến lưu thông tin
 }
 }
//ta dựa vào datashow để hiển thị lên giao diện

– Bạn có thể tải code mẫu ở đây: http://www.mediafire.com/download/04q4rlg33nmrina/LearnXMLParser_DOM.rar (Tôi có đính kèm employee.xml trong project này, bạn chỉ việc kéo thả nó vào SD Card trong máy của bạn là ok).

——————————————————————————————————————–

B) kỹ thuật dùng SAX:

  Cũng với ví dụ ở mục A, nhưng Ta sẽ viết theo kỹ thuật SAX.

– Simple API for XML , scan the document , Đỡ tốn bộ nhớ , Chạy nhanh , viết phức tạp hơn DOM

– Các tag là element trong SAX có thể dùng các hàm:

.getAttributeCount()

.getAttributeName()

.getAttributeValue()

29_xml_2-Sử dụng XmlPullParser  để scan tài liệu:

29_xml_3

– Bước 1:

– Ta cần import các thư viện sau:


import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

– Ta cũng không phải gõ từng dòng import mà eclipse tự động import giùm.

– Bước 2:

Tạo đối tượng parser từ class XmlPullParser


XmlPullParserFactory fc=XmlPullParserFactory.newInstance();
 XmlPullParser parser= fc.newPullParser();

– Bước 3:

– Tạo FileInputStream từ xml source (XML để trong SD Card)


String sdcard=Environment.
 getExternalStorageDirectory().getAbsolutePath();
 String xmlfile=sdcard+"/employee.xml";
 FileInputStream fIn=new FileInputStream(xmlfile);

– Bước 4:

– Tiến hành duyệt


parser.setInput(fIn, "UTF-8");

int eventType=-1;
 String nodeName;
 String datashow="";
 while(eventType!=XmlPullParser.END_DOCUMENT)//chưa kết thúc tài liệu
 {
 eventType=parser.next();// bắt đầu duyệt để
 switch(eventType)
 {
 case XmlPullParser.START_DOCUMENT:
 break;
 case XmlPullParser.END_DOCUMENT:
 break;
 case XmlPullParser.START_TAG://là tag mở
 nodeName=parser.getName();
 if(nodeName.equals("employee")){// kiểm tra đúng tag mình muốn hay không
 datashow+=parser.getAttributeValue(0)+"-";//lấy giá trị của thuộc tính
 datashow+=parser.getAttributeValue(1)+"-";
 }
 else if(nodeName.equals("name")){
 datashow+=parser.nextText()+"-";//lấy nội dung tag element
 }
 else if(nodeName.equals("phone")){
 datashow+=parser.nextText()+"-";
 }
 break;
 case XmlPullParser.END_TAG://là tag đóng
 nodeName=parser.getName();
 if(nodeName.equals("employee")){
 datashow+="\n----------------\n";
 }
 break;
 }
 }

//dựa vào datashow để hiển thị lên giao diện

– Bạn có thể tải code mẫu ở đây : http://www.mediafire.com/download/fh22pkib490n7lf/LearnXMLParser_SAX.rar

———————————————————————————————————————-

-Bài tập dành cho độc giả:

– Duyệt XML bằng DOM và SAX

– Title của các tag XML ta đưa vào Spinner (chú ý không đưa trùng lắp)

– Các thông tin khác đưa vào ListView

– Mỗi lần chọn Title trong Spinner thì chỉ hiển thị những employee theo Title này trong XML mà thôi

29_xml_1

– Chúc các bạn thành công.

17 responses

  1. E chào thầy. thầy có thể làm 1 bài hướng dẫn bọn e về json va sqlite đc k ạ. e xin cám ơn ạ

  2. thầy cho em hỏi down source về rồi phải cấu hình sau để test được ạh ? phiên bản của máy ảo nữa ? em cám ơn thầy 🙂 !.

    1. Ứng dụng vẫn chạy nhưng click Button thì không có phản ứng gì mặc dù file xml đã đặt đúng chỗ 😦

    2. Bài code của thầy chưa set permission, chắc thầy cố tình 🙂

  3. Trong bài thầy đã dạy cách lấy dữ liệu từ một fiel XML bằng DOM hoặc SAX. Vậy nếu mình muốn ghi, chỉnh sửa, xóa dữ liệu trong file XML mình phải làm như thế nào? Cám ơn thầy!

  4. Mong Thầy viết thêm 1 bài về Json parser cho đủ bộ !
    Cảm ơn Thầy

  5. Cho mình hỏi tại sao khi duyệt bằng SAX thì dùng theo xml mà thầy cung cấp lại bão lỗi ở dòng này datashow+=parser.getAttributeValue(0)+”-“;

  6. Dang Huy Hoang | Reply

    Thầy ơi, Thầy có thể hướng dẫn kỹ hơn về cách thức show danh sách nhân viên theo Title chọn ở spinner ko ạ. Hoặc thầy có thể share cho em cái code bài này ko ạ. Em cảm ơn.

    1. bài mình code đây bạn 😀
      https://www.dropbox.com/s/spi174srd82xbv1/LearnXMLParser.rar
      bạn đổi tên file thầy = data.xml nhé

    2. mình làm cách là tạo 3 cái ArrayList cho arch,teacher,engineer. trong lúc duyệt xml thì kiểm tra xem title nào rồi add các thông tin vào 3 arraylist cho hợp lý. cho tất cả title vào 1 arraylist rồi kiểm tra để ko cho trùng lặp. Spinner thì kiểm tra xem select cái gì thì cho listview show arraylist của cái đó. ko biết làm thế này có bị chửi “vô học” ko T_T

    3. Mình có làm đc rồi, ý tưởng của mình sẽ là như này: đầu tiên duyệt 1 lần file XML để lấy ra toàn bộ các title,lưu vào 1 ArrayList, xử lí tránh trùng lặp,sau đó cho hiển thị lên Spinner, tiếp mỗi lần mình chọn trong spinner thì mình sẽ lấy được 1 title,rồi mình sẽ duyệt file xml lần 2, lần này mình lấy title duyệt so sánh với title được chọn trong spinner, nếu giống nhau thì cho hiển thị thông tin lên ListView.Ý của mình là vậy, bạn nào có ý tưởng tốt hơn thì chỉ mình với 😀

  7. Thưa thầy cái SD card đấy nằm ở đâu ạ ?

  8. Thầy ơi thầy làm 1 bài về DefaultHandler được không ạ 😦

  9. Trong bài thầy đã dạy cách lấy dữ liệu từ một fiel XML bằng DOM hoặc SAX. Vậy nếu mình muốn ghi, chỉnh sửa, xóa dữ liệu trong file XML mình phải làm như thế nào? Cám ơn thầy!

  10. […] Bài tập 29: XML Parser trong Android […]

  11. Có bạn nào làm ra bài dành cho đọc giả chưa. cho mình xin source với.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.