YAML, JSON, CSV and XML: converting data and config files safely
Developers move data between formats constantly: a CSV export becomes JSON for an API, a JSON config becomes YAML for Kubernetes, a SOAP response becomes something readable. Each conversion is one line of code — and each has a trap that changes your data without an error.
This guide covers what each format is good at, the specific gotchas, and how to check the config files that most often break deployments. Every step has a free in-browser tool: CSV to JSON/SQL, YAML ↔ JSON, the XML formatter, the Docker Compose validator and the .env diff.
Which format for which job
- JSON — the default for APIs and machine-to-machine data. Strict, unambiguous, no comments. Validate and pretty-print it with the JSON formatter.
- YAML — configuration humans edit: Docker Compose, Kubernetes, GitHub Actions, Ansible. Comments, anchors and less punctuation, at the cost of whitespace-sensitive syntax and type guessing.
- CSV — tables: spreadsheet exports, bulk imports, analytics. Compact and universal, but no types and no nesting.
- XML — documents and older enterprise systems: SOAP, RSS, sitemaps, Office files, Android layouts. Verbose, but has attributes, namespaces and mature schema validation.
CSV to JSON and SQL: quoting and types
“Split each line on commas” breaks on the first real file. RFC 4180 CSV allows commas, quotes and even newlines inside a field when it is wrapped in double quotes, with a literal quote written as "":
id,name,notes
1,"Lee, Jordan","Said ""hi""
on two lines"
Watch for three more traps:
- Delimiters. European Excel exports use semicolons because the comma is the decimal separator; database dumps often use tabs.
- Leading zeros. Postcodes and product codes like
007become7if every numeric-looking value is cast to a number. Keep them as strings. - Big integers. IDs above 253 lose precision as JavaScript numbers. Keep them as strings too.
The CSV converter detects the delimiter, follows the quoting rules, keeps codes and huge numbers as strings, and can emit CREATE TABLE plus batched INSERT statements with column types inferred from the data — handy for loading a spreadsheet into a database in one paste.
YAML ↔ JSON: the Norway problem and friends
JSON is a subset of YAML 1.2, so JSON → YAML is safe. The other way round, YAML’s implicit typing decides what a plain value means:
country: NO # YAML 1.1: false — YAML 1.2: "NO"
version: 1.10 # a float: 1.1
port_map: 22:22 # YAML 1.1: 1342 (base 60)
id: 0123 # YAML 1.1: octal 83
Many tools still parse YAML 1.1 (PyYAML, older Go and Ruby libraries), so the safe habit is to quote anything that is not obviously a number or boolean: country codes, versions, port mappings, IDs with leading zeros.
Anchors (&base), aliases (*base) and merge keys (<<: *base) remove repetition in YAML but have no JSON equivalent — a converter must expand them. Paste a file into the YAML ↔ JSON converter to see exactly what a YAML 1.2 parser makes of it, with the line of any syntax error; multi-document files separated by --- become a JSON array.
XML: well-formed is not the same as valid
A well-formed XML document follows the syntax rules: one root element, every tag closed and correctly nested, attribute values quoted, and & and < escaped in text. A valid document is well-formed and matches a schema (XSD or DTD). Most “invalid XML” errors are really well-formedness errors — an unescaped ampersand in a product name is the classic.
Converting XML to JSON needs conventions because XML has things JSON lacks: attributes become keys prefixed with @, repeated child elements become arrays, and text alongside child elements goes under #text. The XML formatter checks well-formedness with the line and column of the first error, pretty-prints or minifies, and converts to JSON using these conventions.
Validating docker-compose.yml before you deploy
Compose files fail at the worst time — during a deploy — and often silently: an unknown key such as enviroment is a typo that YAML accepts and older Compose versions ignored. Check these before every merge:
- Every service has an
imageor abuild. - Port mappings are quoted strings:
"8080:80", or"127.0.0.1:5432:5432"to keep a database off the public interface. - Named volumes and custom networks are declared at the top level.
depends_onpoints at real services, has no cycles, andcondition: service_healthytargets a service with a healthcheck.- The top-level
version:key is gone — the Compose Specification ignores it. - No
privileged: true,network_mode: hostor Docker socket mounts unless you really mean it.
The Docker Compose validator runs all of these with line numbers and did-you-mean suggestions, without Docker installed. Run docker compose config on the server as the final check — it also resolves variables from your .env.
.env files: catching the missing variable
The most common config outage is a variable that exists in development and not in production. Keep a committed .env.example with every key and no secret values, and compare it with each environment’s real .env before deploying:
# .env.example # .env (production)
DATABASE_URL= DATABASE_URL=postgres://…
STRIPE_SECRET_KEY= STRIPE_SECRET_KEY=sk_live_…
SENTRY_DSN= (missing!)
Dotenv syntax has quirks of its own: export prefixes, quoted multi-line values such as private keys, # starting a comment only after whitespace in unquoted values, and duplicate keys where the later one wins. The .env diff tool parses both files with these rules, lists missing, extra and changed keys with values masked, and generates a clean .env.example from your real file. It runs entirely in your browser, but treat production secrets with care in any tool.
Frequently asked questions
How do I convert CSV to JSON?
Paste the CSV into code.doaide.com/tools/csv-to-json. With a header row each line becomes an object keyed by column name; quoted fields, semicolon or tab delimiters and number/boolean typing are handled automatically.
Why does YAML turn NO into false?
YAML 1.1 treats yes/no/on/off as booleans, so the country code NO becomes false. YAML 1.2 only recognises true and false, but many parsers still follow 1.1 — quote such values to be safe.
What is the difference between well-formed and valid XML?
Well-formed XML follows the syntax rules (one root, matched tags, quoted attributes, escaped special characters). Valid XML is well-formed and also conforms to a schema such as an XSD or DTD.
How do I check a docker-compose file for errors?
Paste it into a Compose validator to catch YAML errors, unknown keys, bad ports and undeclared volumes or networks, then run docker compose config on the target machine, which also resolves environment variables.
More guides
- How to review code with AI, free and without sign-up
- How to convert code between languages with AI (Python, Java, JavaScript and more)
- How to generate unit tests with AI: from zero tests to a real suite
- The best free code review tools in 2026
- AI code tools for beginners: learn faster without learning less
- 10 free AI code tools every developer needs in 2026
- DoAide Code: the free alternative to GitHub Copilot
- How to review code with AI for free: workflows that stick
- How to write clean code in 2026
- Best practices for code documentation
- The best free online code formatter in 2026
- Online regex tester and builder: write regular expressions that actually work
- Free online SQL formatter and validator
- Code snippet sharing for developers: stop pasting code into chat
- How to generate a JSON Schema from a JSON sample
- The flexbox cheat sheet: every property and what it actually moves
- Meta tags for SEO: what your pages actually need in 2026
- UUID v4 vs v7: which one should you use?
- CSS Grid explained: tracks, fr, minmax and template areas
- Linux file permissions and chmod, explained
- How to mock a REST API for frontend development
- CSP, CORS and security headers, explained