Thứ Tư, 28 tháng 11, 2012

Java : Xử lý tập tin Xml bằng cách xử lý chuỗi

Trong Java, ngoài việc sử dụng các thư viện, ta cũng có thể đọc và xử lý tập tin Xml bằng cách thao tác trên chuỗi ký tự.
Nội dung tập tin Xml "mobile phone.xml" cần đọc xem tại đây.

Nội dung mã trong tập tin TextManipulationTest.java

package xml.test;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.junit.Test;

public class TextManipulationTest {

 private static Runtime runtime = Runtime.getRuntime();
 private static String MOBILE_PHONE = "<mobile_phone ";

 @Test
 public void readWriteXml() {
  long startTime = System.currentTimeMillis();
  System.out.println("Before charging file : " + (runtime.totalMemory() - runtime.freeMemory()) + " bytes" );

  List<String> listMobile = splitFileToArray("resources/mobile phone.xml", MOBILE_PHONE);
  String firstMobile = listMobile.get(1);
  String regexName = "<name>(.*)</name>";
  Matcher matcher = Pattern.compile(regexName).matcher(firstMobile);
  firstMobile = matcher.replaceAll("<name>Text manipulation test</name>");
  listMobile.set(1, firstMobile);
  
  writeStringArrayToFile("resources/textManifOutputMobile.xml", listMobile);

  long endTime = System.currentTimeMillis();
  System.out.println("Execution time : " +(endTime - startTime) + " mili seconds");
 }
 
 public void writeStringArrayToFile(String fileName, List<String> list) {
   System.out.println("After manipulation text file : " + (runtime.totalMemory() - runtime.freeMemory()) + " bytes" );
  try (FileWriter fw = new FileWriter(fileName);
    BufferedWriter bw = new BufferedWriter(fw);) {
   for (int i = 0; i < list.size(); i++) {
    if (i != list.size() - 1) {
     bw.write(list.get(i) + MOBILE_PHONE);
    } else {
     bw.write(list.get(i));
    }
   }
   System.out.println("After writing to XML file : " + (runtime.totalMemory() - runtime.freeMemory()) + " bytes" );
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
 
 public List<String> splitFileToArray(String fileName, String regex) {
  List<String> array = new ArrayList<String>();
  String line = null;
  StringBuilder sb = new StringBuilder();
  try (FileReader fr = new FileReader(fileName);
    BufferedReader br = new BufferedReader(fr);) {
   while ((line = br.readLine()) != null) {
    if (line.contains(regex)) {
     String[] temp = line.split(regex);
     // if line begins by "<mobile_phone "
     if (line.startsWith(regex)) {
      if (sb != null && sb.length() > 0) {
       array.add(sb.toString());
      }
     } else {
      sb.append(temp[0]);
      array.add(sb.toString());
     }
     sb = new StringBuilder();

     // if there are more than 3 string
     if (temp.length > 2) {
      for (int i = 1; i < temp.length - 1; i++) {
       array.add(temp[i]);
      }
      // the last string
      sb.append(temp[temp.length - 1]);
     } else if (temp.length == 2) {
      sb.append(temp[1]);
     }
    } else {
     sb.append(line);
    }
   }

   // add last string if any
   if (sb != null && sb.length() > 0) {
    array.add(sb.toString());
   }
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
  return array;
 }
}

Giải thích mã:
- Hàm splitFileToArray, như tên gọi của nó có tác dụng đọc tập tin xml và cắt ra thành nhiều đoạn phân cách bởi chuỗi (string) "<mobile_phone " (chú ý là có khoảng trắng phía cuối để tránh lầm với "<mobile_phones" có "s" sau cùng). Hàm này trả về một danh sách (list) các chuỗi sau khi đã bỏ đi phần chuỗi phân cách.
- Tiếp theo ta lấy chuỗi thứ 2 trong danh sách, tức nội dung nốt mobile_phone đầu tiên, để xử lý.
- Ta dùng biểu thức chính quy (Regular Expression hay viết tắt regex) để tìm và thay thế nội dung thẻ name của nốt đầu này.
- Sau đó lưu nội dung đã thay đổi này vào tập tin.

Nhận xét:
- Xử lý tập tin xml bằng thao tác chuỗi phức tạp hơn việc dùng các thư viện xử lý XML có sẵn vì nó đòi hỏi ta phải viết mã để tự đọc tập tin, tự phân tách, tự tìm kiếm và thêm vào cho đúng đồng thời phải đảm bảo cho tập tin lưu lại có hình thức hợp lệ.
- Lợi điểm của phương pháp này là tiết kiệm được rất nhiều thời gian và bộ nhớ khi xử lý tập tin xml so với việc dùng các thư viện có sẵn.

Không có nhận xét nào:

Đăng nhận xét