0
Tải bản đầy đủ (.pdf) (169 trang)

Webservice với dữ liệu XML

Một phần của tài liệu BÀI GIẢNG PHÁT TRIỂN ỨNG DỤNG CHO THIẾT BỊ DI ĐỘNG HỒ THỊ THẢO TRANG (Trang 148 -148 )

Trong phần trên ta đã tiến hành lấy dữ liệu văn bản từ web service thông qua thức HTTP, tuy nhiên trong ví dụ trước ta cũng thấy dữ liệu trả về có dạng XML. Đây là định dạng tương đối phổ biến của các web service hiện nay (bên cạnh JSON), và để có thể sử dụng được dữ liệu này trong ứng dụng, ta cần phân tích cú pháp (parsing) của dữ liệu XML này. Trong phần này ta sẽ xem xét cách thức ta phân tích tài liệu XML trong Android.

Trong ví dụ này, ta sẽ thực hiện tra nghĩa của một từ tiếng anh qua web service tra từ điển trực tuyến của aonaware. Để thực hiện tra từ, ta gọi API như sau:

http://services.aonaware.com/DictService/DictService.asmx/Define?word={từ-cần-tra} ví dụ để tra nghĩa của từ “apple”, ta cần gọi API như sau:

http://services.aonaware.com/DictService/DictService.asmx/Define?word=apple

Nếu bạn mở link này vào trình duyệt web, ta sẽ thấy nội dung web service này trả về dưới dạng XML như sau:

Nhiệm vụ của chúng ra là viết code phân tích tài liệu XML trên để lấy ra phần nghĩa của từ (trong thẻ WordDefinition) và hiển thị lên màn hình.

Để thực hiện việc này, ta cũng cần khai báo một AsyncTask để tránh khóa cứng UI thread:

private String WordDefinition(String word) {

InputStream in = null; String strDefinition = ""; try { in = OpenHttpConnection("http://services.aonaware.com/DictService/DictService.asmx /Define?word=" + word); Document doc = null;

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db; try { db = dbf.newDocumentBuilder(); doc = db.parse(in);

Phát triển ứng dụng cho thiết bị di động Hồ Thị Thảo Trang

150 // TODO Auto-generated catch block

e.printStackTrace(); }

doc.getDocumentElement().normalize();

// ---retrieve all the <Definition> elements--- NodeList definitionElements = doc

.getElementsByTagName("Definition"); // ---iterate through each <Definition> elements---

for (int i = 0; i < definitionElements.getLength(); i++) {

Node itemNode = definitionElements.item(i);

if (itemNode.getNodeType() == Node.ELEMENT_NODE) {

// ---convert the Definition node into an Element--- Element definitionElement = (Element) itemNode; // ---get all the <WordDefinition> elements under // the <Definition> element---

NodeList wordDefinitionElements = (definitionElement) .getElementsByTagName("WordDefinition"); strDefinition = "";

// ---iterate through each <WordDefinition> elements- --

for (int j = 0; j <

wordDefinitionElements.getLength(); j++) {

// ---convert a <WordDefinition> node into an Element---

Element wordDefinitionElement = (Element) wordDefinitionElements

.item(j);

// ---get all the child nodes under the // <WordDefinition> element---

NodeList textNodes = ((Node) wordDefinitionElement)

.getChildNodes();

strDefinition += ((Node) textNodes.item(0)) .getNodeValue() + ". \n";

} }

}

} catch (IOException e1) {

Log.d("NetworkingActivity", e1.getLocalizedMessage()); }

// ---return the definitions of the word---

return strDefinition;

}

private class AccessWebServiceTask extends AsyncTask<String, Void, String> { protected String doInBackground(String... urls) {

return WordDefinition(urls[0]);

}

protected void onPostExecute(String result) {

Toast.makeText(getBaseContext(), result, Toast.LENGTH_LONG).show();

} }

Trong đó hàm WordDefinition sẽ tải nội dung của webservice và tiến hành phân tích cú pháp tài liệu XML trả về. Công việc này tốn thời gian nên ta cần làm trong thread riêng, do đó ta cần viết thêm lớp AccessWebServiceTask như ở trên.

Việc cuối cùng là gọi AsyncTask này trong hàm onCreate của Activity: /** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

setContentView(R.layout.main);

// ---access a Web Service using GET---

new AccessWebServiceTask().execute("apple");

}

Ứng dụng khi chạy sẽ có dạng như minh họa trong hình bên dưới.

Ta sẽ đi chi tiết hơn một chút về hàm WordDefinition ở trên. Trước hết ta vẫn sử dụng hàm OpenHttpConnection đã viết ở trên để lấy thông tin từ mạng và đưa vào luồng nhập liệu: in =

OpenHttpConnection(http://services.aonaware.com/DictService/DictService.asmx/ Define?word= + word);

Phát triển ứng dụng cho thiết bị di động Hồ Thị Thảo Trang 152 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db; db = dbf.newDocumentBuilder(); doc = db.parse(in); doc.getDocumentElement().normalize();

Lưu ý: trong đoạn code trên ta bỏ qua phần bắt ngoại lệ try-catch cho dễ quan sát.

Sau khi parsing như trên, ta thu được một cây đối tượng trong trường “doc” (đối tượng của lớp org.w3c.dom.Document). Ta có thể duyệt cây tài liệu này để lấy ra các trường mong muốn, cụ thể:

Để lấy danh sách các node “Definitions”:

NodeList definitionElements = doc.getElementsByTagName("Definition"); Sau đó duyệt từng phần tử trong danh sách node trên để lấy ra WordDefinition của từng node:

NodeList wordDefinitionElements =

(definitionElement).getElementsByTagName("WordDefinition");

Việc duyệt cây DOM để trích xuất ra dữ liệu cần thiết là công việc khá điển hình và phổ biến, bạn đọc quan tâm có thể tham khảo chi tiết hơn tại các tài liệu khác.

Một phần của tài liệu BÀI GIẢNG PHÁT TRIỂN ỨNG DỤNG CHO THIẾT BỊ DI ĐỘNG HỒ THỊ THẢO TRANG (Trang 148 -148 )

×