XML Formatting for Developers: Readability, Namespaces, and Safe Edits
How to format and inspect XML without breaking namespaces, attributes, or mixed content — plus when to beautify vs minify and how XPath fits the workflow.
How to format SQL for code review clarity, where dialects disagree, and when you should not reformat production migrations or generated queries.
By codefunc
Unreadable SQL slows reviews more than clever joins do. A 80-line query in one horizontal blob hides the WHERE that deletes too much; a consistently formatted query makes intent obvious. Formatting is not the same as rewriting — and reformatting the wrong files can create noisy diffs or, worse, change meaning when a dialect-sensitive tool "fixes" syntax.
Bottom line: Format SQL you own for human review — keywords, indentation, and clause order. Know your dialect (PostgreSQL, MySQL, SQLite, BigQuery). Do not bulk-reformat committed migrations, vendor dumps, or generated ORM SQL unless the team explicitly agrees. Use a formatter for clarity; use tests and EXPLAIN for correctness.
Backend and full-stack developers writing hand-crafted SQL, reviewing PRs with queries in strings, or cleaning analytical SQL before sharing. Frontend engineers who touch reporting queries or Supabase/RPC SQL will get the same wins.
SQL is declarative, but humans still read top-to-bottom:
-- Hard to review
SELECT u.id,u.email,count(o.id) FROM users u LEFT JOIN orders o ON o.user_id=u.id WHERE u.created_at>NOW()-INTERVAL '30 days' AND u.status='active' GROUP BY u.id,u.email HAVING count(o.id)>0 ORDER BY count(o.id) DESC LIMIT 50;
-- Reviewable
SELECT
u.id,
u.email,
COUNT(o.id) AS order_count
FROM users AS u
LEFT JOIN orders AS o
ON o.user_id = u.id
WHERE u.created_at > NOW() - INTERVAL '30 days'
AND u.status = 'active'
GROUP BY
u.id,
u.email
HAVING COUNT(o.id) > 0
ORDER BY order_count DESC
LIMIT 50;
What reviewers scan for:
| Clause | Questions |
|---|---|
FROM / JOIN |
Are join keys correct? Inner vs left? |
WHERE |
Is this accidentally too broad? |
GROUP BY |
Do selected columns match aggregates? |
ORDER BY / LIMIT |
Stable pagination? Deterministic order? |
Paste messy SQL into the SQL Formatter before review when the author did not format it — client-side formatting keeps proprietary queries on your machine.
Teams vary; pick conventions and stick to them.
| Rule | Recommendation |
|---|---|
| Keywords | Uppercase SELECT, FROM, WHERE (common) or all lowercase — not mixed |
| Indentation | One level per clause / subquery |
| Columns | One per line when there are more than three |
| Joins | JOIN + ON on following indented lines |
| Boolean logic | Align AND / OR under WHERE |
| Subqueries | Parentheses on own lines for large subselects |
| Trailing commas | Allowed in some warehouses (BigQuery); invalid in others — know your engine |
Consistency matters more than winning a style argument. Match the dominant style in the repo.
SQL is not one language. Formatters and linters need a dialect hint.
| Dialect | Gotchas |
|---|---|
| PostgreSQL | :: casts, ILIKE, RETURNING, JSON operators ->, ->> |
| MySQL | Backticks, LIMIT offset, count, different UPSERT story |
| SQLite | Dynamic types; fewer window/function conveniences in older versions |
| SQL Server | TOP, bracket quoting [Table], OUTER APPLY |
| BigQuery | Trailing commas, backticks, scripting features |
A PostgreSQL-specific cast:
SELECT payload->>'email' AS email
FROM events
WHERE created_at >= '2026-01-01'::timestamptz;
Running that through a MySQL-oriented formatter or executor will fail or mangle tokens. Set the dialect explicitly in your tool when options exist; the SQL Formatter is for readability passes — still validate in the target engine.
APIs and warehouses increasingly mix SQL with JSON payloads. When debugging:
-- Postgres: filter on JSON field
SELECT id
FROM invoices
WHERE (data->>'status') = 'paid';
Readable SQL plus pretty JSON samples in the PR description cuts "what does this payload look like?" back-and-forth.
Formatting changes are still diffs. Avoid drive-by reformat in these cases:
| Artifact | Why leave it alone |
|---|---|
| Versioned migrations already applied | Reordering/rewrapping creates huge diffs; risk of accidental edits |
| Expand/contract migration pairs | Noise obscures the real schema change |
| ORM-generated SQL in snapshots | Regenerate from the ORM; do not hand-pretty if tests compare strings |
| Vendor schema dumps | Treat as upstream; wrap or view separately |
| Query strings matched in brittle tests | Update tests deliberately or assert on parsed AST / behavior |
Safer policy:
Never "just format" a migration file in the same commit as a logic change. Reviewers will miss the
WHEREthat moved.
A pretty query can still be wrong. Formatting does not fix:
NOT IN with NULLsWHERE LOWER(email) = … without a matching index)Use formatting for review velocity; use explain plans, tests, and staging data for correctness.
Format SQL so reviewers can see joins and filters in seconds. Respect dialect differences, and keep formatters away from frozen migrations and brittle string snapshots unless the team plans a cleanup. codefunc's SQL Formatter and JSON Formatter run in the browser for quick, private cleanup before you paste into a PR or ticket.
How to format and inspect XML without breaking namespaces, attributes, or mixed content — plus when to beautify vs minify and how XPath fits the workflow.
Why compact GraphQL queries hurt reviews, how to format selection sets consistently, and a browser workflow before you paste into Apollo or GraphiQL.
How unified diffs work, when to use a patch viewer vs text/JSON diff, and a safe browser workflow for creating and applying single-file patches.
Find a developer tool