Bài viết
Chuyển đổi giữa CSV, XML, JSON và YAML: hướng dẫn thực tế
CSV, JSON, XML và YAML là bốn định dạng mà lập trình viên gặp nhiều nhất trong các pipeline dữ liệu, tệp cấu hình và API. Việc chuyển đổi giữa chúng rất đơn giản khi các mô hình dữ liệu khớp nhau, và mất mát một cách bất ngờ khi chúng không khớp. Hướng dẫn này nói về điều mỗi định dạng có thể và không thể biểu diễn, nơi thông tin biến mất trong quá trình chuyển đổi, và những cạm bẫy mã hóa gây hỏng dữ liệu một cách âm thầm. Công cụ data-converter trên trang này xử lý ba trong bốn định dạng (CSV, JSON và YAML) hoàn toàn trong trình duyệt; các phần về XML trong bài này là kiến thức nền cho khi bạn di chuyển dữ liệu bằng tay hoặc với một công cụ riêng.
Bốn định dạng và mô hình dữ liệu của chúng
CSV tổ chức dữ liệu thành một lưới phẳng gồm các hàng và cột. Hàng đầu tiên thường đặt tên cho các cột; mỗi hàng tiếp theo là một bản ghi. Không có lồng nhau, không có thông tin kiểu, và không có chuẩn nào cho bất cứ thứ gì ngoài văn bản thuần trong các ô. Mọi giá trị đều là chuỗi trừ khi ứng dụng đọc nó áp đặt một kiểu. JSON mô hình hóa dữ liệu thành một cây gồm các đối tượng (ánh xạ khóa-giá trị) và mảng. Giá trị có thể là chuỗi, số, boolean, null, đối tượng lồng nhau, hoặc mảng ở độ sâu bất kỳ. Điều này cho phép một tài liệu JSON duy nhất biểu diễn một bản ghi khách hàng với các đối tượng địa chỉ nhúng, các mảng dòng hàng, và tổng số dạng số có kiểu. XML mô hình hóa dữ liệu thành một cây gồm các phần tử. Mỗi phần tử có thể mang các thuộc tính được đặt tên và chứa phần tử con hoặc nội dung văn bản. Không có kiểu số hay boolean dựng sẵn; mọi thứ đều là văn bản. Các schema như XSD có thể bắt buộc kiểu khi xác thực, nhưng định dạng truyền đi luôn là dữ liệu ký tự. YAML dùng thụt lề để diễn đạt cùng mô hình đối tượng-và-mảng như JSON, với cú pháp dễ đọc hơn cho con người. YAML là một tập cha của JSON: bất kỳ tài liệu JSON hợp lệ nào cũng là YAML hợp lệ. Nó thêm chuỗi nhiều dòng, chú thích, và tham chiếu anchor-alias cho các khối lặp lại. YAML phổ biến trong tệp cấu hình; JSON phổ biến trong phản hồi API.

Chuyển đổi mất mát: làm phẳng và sự mơ hồ của XML
Phép chuyển đổi mất mát phổ biến nhất là làm phẳng JSON hoặc XML lồng nhau thành CSV. Một đối tượng JSON có trường địa chỉ lồng nhau không thể ánh xạ gọn gàng sang một hàng CSV. Cách giải quyết thường gặp là tên cột theo ký pháp chấm: customer.address.city trở thành một cột riêng. Cách này hiệu quả với một cấp lồng nhau, nhưng hỏng hoàn toàn khi xuất hiện một mảng. Một khách hàng có ba số điện thoại đòi hỏi hoặc ba cột riêng (cố định cứng số lượng tối đa), tách thành tệp CSV thứ hai, hoặc mã hóa mảng thành một chuỗi có dấu phân tách bên trong một ô duy nhất. Không lựa chọn nào trong số đó quay vòng lại được JSON gốc mà không cần siêu dữ liệu bổ sung. XML đưa ra một sự mơ hồ riêng: lựa chọn giữa thuộc tính và phần tử con. Giá trị Paris có thể được lưu dưới dạng thuộc tính (<city name="Paris">) hoặc dưới dạng phần tử con (<city><name>Paris</name></city>). Khi một bộ chuyển đổi đọc XML và tạo JSON, nó phải quyết định cách ánh xạ các thuộc tính. Các quy ước thường gặp gồm thêm tiền tố @ vào khóa thuộc tính hoặc đặt chúng dưới một khóa "_attributes". Lựa chọn này không được chuẩn hóa, nghĩa là hai bộ chuyển đổi đọc cùng một XML có thể tạo ra JSON khác nhau về cấu trúc. Nếu bạn định quay vòng dữ liệu qua XML và JSON, hãy cố định một quy ước trước khi bắt đầu.
Cạm bẫy của CSV: dấu phân tách, dấu nháy và mã hóa
CSV không có một chuẩn chính thức duy nhất, chỉ có RFC 4180 như một tài liệu tham chiếu được trích dẫn rộng rãi. Dấu phân tách phổ biến nhất là dấu phẩy, nhưng dấu chấm phẩy (thường gặp ở các locale châu Âu nơi dấu phẩy đóng vai trò dấu thập phân), tab (TSV), và dấu gạch đứng đều xuất hiện trong thực tế. Một tệp tên .csv có thể dùng bất kỳ dấu nào trong số này mà không báo hiệu đang dùng dấu nào. Khi một giá trị trường chứa chính dấu phân tách, RFC 4180 yêu cầu bọc trường đó trong dấu nháy kép: "San Francisco, CA". Một dấu nháy kép bên trong trường đã bọc phải được thoát bằng cách nhân đôi nó: "He said ""hello""". Một trường chứa ký tự xuống dòng cũng phải được bọc. Bộ phân tích bỏ qua bước này sẽ tạo ra lỗi đếm hàng khó truy vết. Mã hóa là một cái bẫy riêng. Tệp CSV từ các công cụ Windows thường mang một UTF-8 BOM (byte order mark: ba byte EF BB BF ở đầu tệp). BOM giúp Excel nhận diện mã hóa, nhưng nhiều bộ phân tích của ngôn ngữ lập trình lại coi BOM là một phần của tên cột đầu tiên, tạo ra một cột tên "id" thay vì "id". Điều này phá vỡ mọi đoạn mã phía sau tra cứu cột theo tên. Khi đọc tệp CSV bằng chương trình, hãy loại bỏ BOM trước khi phân tích, hoặc dùng một thư viện xử lý nó một cách tường minh.

Chọn định dạng: cấu hình, trao đổi và bảng tính
Việc chọn định dạng thường do bối cảnh quyết định, không phải sở thích. JSON là mặc định cho REST API và trao đổi giữa trình duyệt với máy chủ. Nó gọn, được phân tích sẵn trong mọi ngôn ngữ lập trình, và mang thông tin kiểu cho số và boolean. Điểm yếu của nó là thiếu chú thích, khiến nó không phù hợp cho các tệp mà lập trình viên đọc và sửa bằng tay. YAML được ưa chuộng cho tệp cấu hình (manifest Kubernetes, định nghĩa pipeline CI, playbook Ansible) vì nó cho phép chú thích nội dòng và dễ đọc hơn JSON khi có nhiều cấp thụt lề. Rủi ro chính là lỗi thụt lề diễn ra âm thầm: một khóa bị thụt sai sẽ chuyển sang một phạm vi khác mà không gây lỗi phân tích. XML vẫn là chuẩn trong các hệ thống doanh nghiệp cũ, dịch vụ web SOAP, các định dạng tài liệu (DOCX, SVG, RSS), và những bối cảnh cần xác thực schema hoặc phân định không gian tên. Nó dài dòng, nhưng công cụ XPath và XSLT đã trưởng thành. CSV là lựa chọn đúng khi dữ liệu thực sự phẳng và bên tiêu thụ là một ứng dụng bảng tính hoặc một nhà phân tích dữ liệu. Nó không phù hợp cho cấu hình hay trao đổi API vì không có hệ thống kiểu và không có lồng nhau.
Làm cục bộ với data-converter
Công cụ data-converter trên trang này phân tích và chuyển đổi giữa CSV, JSON và YAML hoàn toàn bên trong trình duyệt; công cụ này không đọc hoặc ghi XML. Không có dữ liệu nào được truyền tới máy chủ tại bất kỳ thời điểm nào. Việc chuyển đổi chạy trong môi trường JavaScript cục bộ của bạn, và kết quả có sẵn để tải xuống hoặc sao chép mà không có gì rời khỏi thiết bị của bạn. Điều này quan trọng với dữ liệu không phải của bạn để chia sẻ: phản hồi API chứa thông tin cá nhân, tệp cấu hình có tên máy chủ nội bộ, hoặc bản xuất CSV từ cơ sở dữ liệu nội bộ. Dán dữ liệu đó vào một bộ chuyển đổi trên web chạy trên máy chủ nghĩa là nội dung được gửi qua mạng và xử lý trên phần cứng bạn không kiểm soát. Với data-converter, tab trình duyệt chính là môi trường xử lý. Công cụ áp dụng quy tắc bọc dấu nháy RFC 4180 khi đọc hoặc ghi CSV, và kỳ vọng một mảng phẳng các đối tượng khi chuyển JSON hoặc YAML sang CSV: một giá trị đối tượng hoặc mảng lồng nhau dưới một khóa sẽ không được tự động làm phẳng theo ký pháp chấm, vì vậy hãy tự làm phẳng các trường đó trước khi chuyển đổi nếu bạn cần chúng thành các cột riêng. Nếu bạn cần di chuyển dữ liệu đến hoặc từ XML, hãy chuyển nó sang JSON hoặc YAML bằng một công cụ XML chuyên dụng trước, rồi đưa kết quả vào đây.
Công cụ trong bài viết này
Câu hỏi thường gặp
Tôi có thể quay vòng JSON qua CSV rồi lấy lại bản gốc không?
Chỉ khi JSON là một mảng phẳng các đối tượng không có trường lồng nhau và không có mảng làm giá trị. Ngay khi bạn có một đối tượng lồng nhau hoặc một giá trị mảng, biểu diễn CSV đòi hỏi một quyết định về cấu trúc (cột theo ký pháp chấm, nhiều hàng, hoặc chuỗi đã mã hóa) mà không thể tự động đảo ngược. Nếu dữ liệu của bạn có lồng nhau, JSON, XML hoặc YAML sẽ quay vòng gọn gàng; CSV thì không.
Vì sao CSV của tôi hiển thị sai trong Excel sau khi xuất từ một ứng dụng châu Âu?
Các locale châu Âu thường dùng dấu chấm phẩy làm dấu phân tách CSV vì dấu phẩy được dành cho ký pháp thập phân. Excel ở locale châu Âu mong đợi dấu chấm phẩy. Nếu tệp dùng dấu phẩy, Excel coi cả hàng là một cột duy nhất. Cách khắc phục là đổi dấu phân tách trong thiết lập xuất, hoặc dùng trình Data Import của Excel để chỉ định dấu phân tách thủ công. Vấn đề UTF-8 BOM thì riêng: nếu không có BOM, Excel cũng có thể đọc sai các ký tự có dấu thành văn bản lỗi.
Khác biệt thực tế giữa YAML và JSON là gì?
Cả hai biểu diễn cùng một mô hình dữ liệu nền: đối tượng, mảng, chuỗi, số, boolean và null. YAML thêm chú thích (dòng bắt đầu bằng #), chuỗi nhiều dòng, và tham chiếu anchor cho các khối lặp lại. JSON đúng là một tập con của YAML hợp lệ, nhưng bộ phân tích JSON không đọc được YAML. Quy tắc thực tế: dùng JSON cho payload API và lưu trữ dữ liệu; dùng YAML cho tệp cấu hình mà con người chỉnh sửa và hưởng lợi từ chú thích nội dòng.