Skip to content
Back to Blog
how-to-convert

Cách Chuyển Đổi YAML sang JSON: Những Cạm Bẫy Phổ Biến Cần Tránh

2026-05-17 8 phút đọc

Tại Sao YAML và JSON Không Dễ Hoán Đổi Như Bạn Nghĩ

YAML và JSON trông có vẻ giống nhau, và mối quan hệ của chúng rất gần gũi. YAML 1.2 thậm chí còn là một tập hợp cha của JSON, nên bất kỳ file JSON hợp lệ nào cũng là file YAML hợp lệ. Nghe có vẻ tuyệt vời, phải không? Đúng là vậy, cho đến khi bạn chuyển đổi một file YAML trong thực tế và phát hiện ra dữ liệu của mình bị hỏng một cách âm thầm. Đơn giản là hai định dạng này có mục tiêu thiết kế khác nhau. JSON được xây dựng cho máy móc: nghiêm ngặt, rõ ràng, và không có chỗ cho chú thích. Ngược lại, YAML được xây dựng cho con người. Nó sử dụng thụt đầu dòng để tạo cấu trúc, hỗ trợ chuỗi nhiều dòng, cho phép chú thích nội dòng, và có một hệ thống suy luận kiểu dữ liệu cố gắng đoán ý định của bạn. Chính việc đoán ý hữu ích này lại là nơi các chuyển đổi gặp vấn đề. Một trình phân tích YAML có thể đọc chuỗi 'yes' và hiểu nó là giá trị boolean `true`. Nó có thể thấy '1.0' và tạo ra một số thực, chứ không phải chuỗi bạn đã gõ. Đây không phải là lỗi; đặc tả YAML đang hoạt động đúng như thiết kế. Vấn đề phát sinh vì JSON không có sự mơ hồ như vậy. Một khi giá trị YAML của bạn trở thành boolean trong dữ liệu đã phân tích, đầu ra JSON sẽ ghi là `true`, và chuỗi gốc sẽ mất đi vĩnh viễn. Khi bạn đang chuyển đổi các file cấu hình cho một cụm Kubernetes, một đặc tả OpenAPI, hay một pipeline CI/CD, những thay đổi kiểu dữ liệu âm thầm này có thể phá hỏng mọi thứ ở các bước sau đó mà không có một thông báo lỗi nào. Để chuyển đổi file một cách đáng tin cậy, bạn phải hiểu những khác biệt cơ bản này.

Cách Nhanh Nhất để Chuyển Đổi: Sử dụng CocoConvert

Khi bạn chỉ cần chuyển đổi một file, cách nhanh nhất là sử dụng một công cụ chuyên dụng thay vì chắp vá một đoạn script. [Công cụ chuyển đổi YAML sang JSON](/convert/yaml-to-json) của CocoConvert quản lý tất cả việc phân tích và tuần tự hóa, cho bạn kết quả đầu ra được định dạng đúng chuẩn, mã hóa UTF-8 ngay lập tức. Quá trình này cực kỳ đơn giản: dán YAML của bạn, tải lên một file .yaml hoặc .yml, và nhấp vào Chuyển đổi. JSON của bạn sẽ xuất hiện trong bảng đầu ra, sẵn sàng để sao chép hoặc download. CocoConvert sử dụng các quy tắc phân tích YAML 1.2 hiện đại, vì vậy bạn sẽ không mắc phải "Vấn đề Na Uy" cũ, nơi chuỗi 'NO' bị hiểu nhầm thành giá trị boolean `false`. Nếu file YAML nguồn của bạn có lỗi thụt đầu dòng, bạn sẽ nhận được một lỗi phân tích rõ ràng với số dòng thay vì một đầu ra bị hỏng một cách âm thầm. Nó cũng xử lý chính xác các file YAML nhiều tài liệu (những file có dấu phân cách `---`). Chúng được chuyển đổi thành một mảng JSON, trong đó mỗi tài liệu trở thành một phần tử của mảng. Đây là hành vi tiêu chuẩn, được mong đợi, nhưng bạn nên nhớ điều này nếu thấy một mảng không mong muốn trong đầu ra vì file của bạn bắt đầu bằng `---`. Có một hạn chế: công cụ không hỗ trợ các anchor và alias của YAML tham chiếu đến các node qua lại giữa các tài liệu khác nhau trong cùng một file. Đối với những trường hợp phức tạp liên quan đến anchor liên tài liệu, bạn sẽ cần phải giải quyết chúng trước, bằng tay hoặc bằng một script cục bộ, trước khi tải file lên để chuyển đổi.

Ép Kiểu Dữ Liệu trong YAML: Những Cạm Bẫy Đau Nhất

Ép kiểu dữ liệu là nguyên nhân số một gây mất dữ liệu khi chuyển đổi từ YAML sang JSON. Trước khi bạn chuyển đổi bất kỳ file production nào, bạn tuyệt đối phải kiểm tra các cạm bẫy cụ thể này. **Boolean từ những chuỗi không ngờ tới.** Các trình phân tích YAML 1.1 cũ (như PyYAML trước phiên bản 6.0) sẽ hiểu `yes`, `no`, `on`, và `off` là boolean. YAML 1.2 hiện đại chỉ coi `true` và `false` theo cách này, nhưng nếu file nguồn của bạn được tạo bởi một công cụ cũ hơn, nó có thể chứa 'yes' trong khi thực sự có nghĩa là chuỗi 'yes'. Nếu bạn không biết nguồn gốc của file, bạn cần phải kiểm tra các giá trị này bằng tay. **Số nguyên bát phân (octal).** Đây là một cái bẫy kinh điển. Trong YAML, một giá trị như `0755` được phân tích thành số nguyên bát phân 493. Đây là một cái bẫy khét tiếng trong các manifest Kubernetes để thiết lập quyền truy cập file. Khi được chuyển đổi, JSON của bạn sẽ chứa số `493`, chứ không phải chuỗi `'0755'`. Nếu một quy trình sau đó cố gắng sử dụng con số đó trong một lệnh `chmod`, quyền truy cập sẽ hoàn toàn sai, và bạn sẽ không nhận được lỗi nào. **Các trường hợp đặc biệt của số thực.** YAML hiểu các giá trị số thực đặc biệt như `.inf`, `-.inf`, và `.nan`. JSON thì không. CocoConvert xử lý điều này bằng cách chuyển đổi chúng thành các chuỗi 'Infinity', '-Infinity', và 'NaN'. Đây là một giải pháp hợp lý, nhưng nếu ứng dụng của bạn chỉ mong đợi các con số, nó có thể thất bại với các giá trị chuỗi này, đòi hỏi phải xử lý hậu kỳ. **Biểu diễn null.** YAML linh hoạt với các giá trị null, chấp nhận `null`, `~`, hoặc thậm chí chỉ là một giá trị trống sau một khóa. Tất cả những thứ này sẽ trở thành một `null` tiêu chuẩn trong JSON. Điều này thường không sao, nhưng hãy nhớ rằng một khóa không có gì sau dấu hai chấm sẽ trở thành một JSON `null`, chứ không phải là một chuỗi rỗng `""`.

Xử Lý Chuỗi Nhiều Dòng và Chú Thích

YAML cung cấp hai cú pháp chuỗi nhiều dòng mạnh mẽ mà không có cú pháp tương đương trực tiếp trong JSON: literal block scalar (`|`) và folded block scalar (`>`). Một literal block (`|`) giữ lại mọi ký tự xuống dòng. Một folded block (`>`) biến các lần xuống dòng đơn thành dấu cách nhưng giữ lại các lần xuống dòng kép thành ký tự xuống dòng thực sự. Cả hai cú pháp đều tạo ra một chuỗi JSON duy nhất, nhưng sự khác biệt tinh tế trong việc xử lý xuống dòng là rất quan trọng đối với nội dung nhúng như script shell, truy vấn SQL, hoặc chứng chỉ. Ví dụ, YAML này: ```yaml script: | echo hello echo world ``` trở thành JSON này: ```json {"script": "echo hello\necho world\n"} ``` Lưu ý ký tự xuống dòng ở cuối (`\n`) được giữ lại mặc định với kiểu literal `|`. Để loại bỏ nó, bạn sẽ sử dụng chỉ báo chomping `|-`. Bất cứ ai đã từng gỡ lỗi một CI script bị lỗi do một sự khác biệt nhỏ về khoảng trắng đều hiểu rõ nỗi đau này. Làm sai điều này có thể phá hỏng các script hoặc API nhạy cảm với khoảng trắng. Chú thích là một vấn đề khó khăn hơn nhiều. YAML hỗ trợ chú thích bằng cách sử dụng `#`. JSON thì không. Chấm hết. Điều này có nghĩa là trong quá trình chuyển đổi, mọi chú thích trong file YAML của bạn sẽ bị xóa vĩnh viễn. Tất cả ngữ cảnh quan trọng giải thích *tại sao* một giá trị nhất định được thiết lập—một thực hành phổ biến trong infrastructure-as-code—sẽ biến mất khỏi đầu ra JSON. Không có cách giải quyết nào trong đặc tả JSON. Lời khuyên của tôi rất đơn giản: luôn coi file YAML có chú thích của bạn là nguồn chân lý và file JSON được tạo ra là một sản phẩm build dùng một lần. Một số đội sử dụng JSONC (JSON có Chú thích), nhưng điều đó chỉ đẩy vấn đề tương thích về sau.

Anchor, Alias và Merge Key

Anchor và alias của YAML là một tính năng tuyệt vời để giữ cho file của bạn DRY (Don't Repeat Yourself - Đừng Lặp Lại Chính Mình), nhưng chúng lại tạo ra sự phức tạp trong quá trình chuyển đổi sang JSON. Bạn định nghĩa một anchor với `&anchor-name` và sau đó tham chiếu đến nó bằng `*anchor-name`. Một trình phân tích YAML sẽ mở rộng các alias này khi nó đọc file, xây dựng cấu trúc dữ liệu cuối cùng trong bộ nhớ. Do đó, đầu ra JSON chứa nội dung đã được mở rộng hoàn toàn, bị trùng lặp, không còn dấu vết của các anchor ban đầu. Hãy xem xét mẫu phổ biến này: ```yaml defaults: &defaults timeout: 30 retries: 3 production: <<: *defaults host: prod.example.com staging: <<: *defaults host: staging.example.com ``` Cú pháp `<<` là một merge key của YAML. JSON kết quả sẽ là: ```json { "defaults": {"timeout": 30, "retries": 3}, "production": {"timeout": 30, "retries": 3, "host": "prod.example.com"}, "staging": {"timeout": 30, "retries": 3, "host": "staging.example.com"} } ``` Việc mở rộng là chính xác, nhưng sự ngắn gọn của file YAML gốc đã biến mất. Nếu 50 dịch vụ kế thừa từ anchor defaults đó, file JSON sẽ chứa 50 bản sao của dữ liệu đó. Đối với máy móc, điều này hoàn toàn ổn. Đối với một người cố gắng đọc file, hoặc đối với các hệ thống mà kích thước file là một vấn đề, đó là một nhược điểm đáng kể. Hãy lưu ý rằng hỗ trợ merge key (`<<`) về mặt kỹ thuật là một phần mở rộng của YAML, không phải là một phần của đặc tả cốt lõi, vì vậy một số trình phân tích nghiêm ngặt sẽ từ chối nó. CocoConvert xử lý merge key mà không gặp vấn đề gì. Nếu bạn đang viết script chuyển đổi bằng PyYAML của Python, bạn phải sử dụng `yaml.full_load()` hoặc `yaml.safe_load()`. Tránh dùng `yaml.load()` cũ mà không có đối số `Loader`, vì nó đã bị phản đối từ PyYAML 5.1 do các rủi ro bảo mật lớn.

Chuyển Đổi YAML sang JSON bằng Lập Trình

Đối với các chuyển đổi hàng loạt, tích hợp vào pipeline build, hoặc bất kỳ loại xử lý tự động nào, bạn sẽ cần một giải pháp dòng lệnh hoặc script. Một công cụ web rất tuyệt cho các công việc đơn lẻ, nhưng tự động hóa đòi hỏi code. Đây là những cách đáng tin cậy nhất để thực hiện. **Python (lựa chọn linh động nhất):** ```python import yaml, json, sys with open(sys.argv[1], 'r') as f: data = yaml.safe_load(f) print(json.dumps(data, indent=2, ensure_ascii=False)) ``` Luôn sử dụng `yaml.safe_load()`. Hàm `yaml.load()` cũ là một cơn ác mộng bảo mật có thể thực thi mã tùy ý từ một file YAML độc hại. Đối số `ensure_ascii=False` cũng là một thói quen tốt, vì nó giữ lại các ký tự Unicode thay vì thoát chúng. **Node.js:** ```javascript const yaml = require('js-yaml'); const fs = require('fs'); const data = yaml.load(fs.readFileSync(process.argv[2], 'utf8')); console.log(JSON.stringify(data, null, 2)); ``` Thư viện `js-yaml` sử dụng các quy tắc YAML 1.2 hiện đại theo mặc định (từ v4.0). Nếu bạn đang làm việc trong một dự án cũ hơn, hãy kiểm tra lại `package.json` của bạn. Các phiên bản trước 4.0 sử dụng các quy tắc YAML 1.1 và sẽ ép kiểu sai các chuỗi như 'yes' và 'no' thành boolean. **yq (công cụ dòng lệnh):** ```bash yq -o=json eval '.' input.yaml > output.json ``` Thành thật mà nói, `yq` là công cụ tốt nhất cho công việc này trên dòng lệnh. Nó là một bộ xử lý YAML được xây dựng chuyên dụng, xử lý mọi thứ một cách chính xác—file nhiều tài liệu, anchor, merge key—với một cờ đơn giản để xuất ra JSON. Cài đặt nó bằng Homebrew trên macOS (`brew install yq`) hoặc lấy file nhị phân từ GitHub cho Linux/Windows. Tất nhiên, để chuyển đổi nhanh mà không cần cài đặt bất cứ thứ gì, [công cụ YAML sang JSON của CocoConvert](/convert/yaml-to-json) vẫn là cách nhanh nhất để hoàn thành công việc.

Kiểm Tra Kết Quả Đầu Ra Trước Khi Sử Dụng

Chuyển đổi một file mà không kiểm tra nó là công thức để đưa các lỗi tinh vi vào môi trường production. Một file JSON có thể hoàn toàn hợp lệ về mặt cú pháp nhưng chứa dữ liệu sai về mặt ngữ nghĩa, như các trường hợp ép kiểu mà chúng ta đã thảo luận. Đây là một danh sách kiểm tra thực tế để giúp bạn tránh khỏi những cơn đau đầu trong tương lai. **Kiểm tra cú pháp.** Tối thiểu, hãy chạy đầu ra qua một trình linter JSON. Trình soạn thảo code của bạn (như VS Code hoặc một IDE của JetBrains) có thể đã làm điều này tự động. Từ dòng lệnh, công cụ `json.tool` tích hợp sẵn của Python là một công cụ đáng tin cậy: `python3 -m json.tool output.json > /dev/null`. Nó sẽ thoát với mã 0 nếu JSON hợp lệ và cho bạn biết chính xác nơi nó bị hỏng nếu có lỗi. **Kiểm tra schema.** Đối với các file quan trọng, hãy sử dụng schema. Nếu định dạng mục tiêu của bạn có một JSON Schema (phổ biến cho các đặc tả OpenAPI, AWS CloudFormation, và Kubernetes CRD), hãy kiểm tra với nó. Một công cụ như `ajv-cli` (`ajv validate -s schema.json -d output.json`) sẽ phát hiện các lỗi không khớp kiểu dữ liệu mà một trình kiểm tra cú pháp đơn giản không thể thấy. **So sánh với một phiên bản đã biết là đúng.** Khi bạn có một file JSON tham chiếu, việc so sánh là cần thiết. Nhưng trước tiên, hãy chuẩn hóa thứ tự các khóa để tránh những khác biệt nhiễu, vô nghĩa. Công cụ `jq` có thể sắp xếp các khóa một cách xác định: `jq --sort-keys . output.json > normalized.json`. Hãy nhớ, thứ tự khóa trong JSON không quan trọng, nhưng nó sẽ khiến bạn phát điên khi cố gắng so sánh các file. **Kiểm tra nhanh các kiểu dữ liệu bị ép.** Nếu bạn nghi ngờ file YAML của mình có các giá trị như '1.0' hoặc '0755', hãy kiểm tra trực tiếp đầu ra JSON. Một lệnh `grep -n "0755" output.json` nhanh chóng sẽ cho bạn biết ngay lập tức liệu chuỗi bát phân của bạn có tồn tại sau khi chuyển đổi hay đã bị biến thành một số nguyên vô dụng. Nghiêm túc mà nói, dành năm phút để kiểm tra đầu ra của bạn trước khi commit hoặc deploy luôn nhanh hơn việc gỡ lỗi một sự cố production gây ra bởi một giá trị boolean đáng lẽ phải là một chuỗi.

Ready to convert?

Try it now — fast, secure, and private.

Convert Now →
Cách Chuyển Đổi YAML sang JSON: Những Cạm Bẫy Phổ Biến Cần Tránh | CocoConvert Blog