Đọc file XML trong ứng dụng React

Trong thời gian vừa rồi team mình có xây dựng một dự án đọc và bóc tách dữ liệu hoá đơn điện tử từ file XML. Tìm hiểu trên mạng thì chưa thấy có bài hướng dẫn cụ thể nào về việc đọc file từ client-side mà chủ yếu đều từ server-side như NodeJS. Vì vậy, hôm nay mình sẽ viết bài hướng dẫn cụ thể cách các bạn có thể đọc file XML từ React và biến data thành dạng key-value pair trong JSON.

Đọc file XML từ local sau khi người dùng upload

Giả sử người dùng có nhu cầu upload file trực tiếp từ máy tính của họ lên browser. Chúng ta sẽ xây dựng một form đơn giản với input dạng "file" và cho phép người dùng upload file "application/xml" hay "text/xml":

<form className="ReadLocalXML-Form" onSubmit={submitHandler}>
   <h4>Chọn file XML để upload</h4>

   <input
      id="upload"
      type="file"
      accept="text/xml, application/xml"
      onChange={changeHandler}
    />

    <button type="submit">Đọc file</button>
 </form>

Để cập nhật những thay đổi và lưu file vào state sau khi người dùng đã chọn file, mình sẽ dùng function changeHandler như sau:

const [file, setFile] = useState();

const changeHandler = e => {
    setFile(e.target.files[0]);
  };

Tuy nhiên, nếu như bạn để ý khi chúng ta console.log(e.target.files[0]) sẽ trả về một đối tượng dạng File với thuộc tính "name". Chúng ta hoàn toàn không đọc được nội dung bên trong nó. Để đọc được nội dung của file, chúng ta có thể sử dụng Web APIs FileReader:

const reader = new FileReader();

reader.readAsText(file);
reader.onloadend = evt => {
  const readerData = evt.target.result;
}

Sau khi đọc file, mình lưu kết quả đã đọc được vào một biến mới với tên là "readerData". Tuy nhiên, kể cả khi bạn console.log(readerData), kết quả trả về lúc này sẽ có dạng:

ZBj27qqpp5ZlCQZuIhO9whXfBdXKPdfnOyBoJ3CAQXygwsEx4hEbNYDy8XR3Xaq+UeIUrU6H/fp606w6+UQExU8+4k6nQu1t0yItbQIDAQABo4IBsDCCAawwgbUGCCsGAQUFBwEBBIGoMIGlMDcGCCsGAQUFBzAChitodHRwOi8vcHVibGljLnJvb3RjYS5nb3Yudm4vY3J0L21pY25yY2EuY3J0MEAGCCsGAQUFBzAChjRodHRwOi8vd3d3LnNhZmVjZXJ0LmNvbS52bi93d3cvY2VydC9TQUZFLUN

Lí do cho việc này đó chính là File object có khả năng được "serialize" - có thể hiểu là: để file được truyền đi thông qua HTTP, file đó phải có thể được mã hóa thành giá trị chuỗi.

Nếu như các bạn đã từng sử dụng JSON.stringify() và JSON.parse() thì nguyên lí hoạt động cũng tương tự như trong trường hợp này. Chúng ta cần "deserialize" file XML được lưu ở state. Một library có thể giúp chúng ta làm được điều này đó chính là xml2js

Để cài đặt xml2js:

npm i xml2js

Sau đó, bạn import xml2js và sử dụng như sau:

import xml2js from "xml2js";
const parser = xml2js.parseString;
const [content, setContent] = useState();

reader.readAsText(file);
reader.onloadend = evt => {
  const readerData = evt.target.result

 // Parse giá trị chuỗi sau khi đọc thành dạng object
  parser(readerData, (err, result) => {
    setContent(result);
  });

}

Vậy là sau khi bạn console.log(content), chúng ta sẽ nhận được kết quả trả về là một object với nội dung của file XML. Bạn có thể theo dõi toàn bộ sourcecode ở đây:

Edit friendly-mirzakhani-7i38h


All Rights Reserved