Format XML online
Paste one long line of XML, such as a catalog of books, and get a tree indented two spaces per level, with attributes quoted consistently. The whole document is checked first, so a mismatched tag or a missing root is reported instead of half-formatted. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Nested elements become visually clear, attributes use consistent quoting, and insignificant layout whitespace is removed. If tags are mismatched, an entity is invalid, an attribute is malformed, or the document has no single root element, the operation returns an error instead of producing output that only looks correct.
Turn compressed XML into a structure people can review
Although machines can consume that representation, people struggle to see where one record ends and another begins. Paste the source into the formatter and each structural level is indented consistently, making parents, children, siblings, attributes, comments, and processing instructions easier to distinguish. The formatter accepts an optional indentation string, so you can choose spaces or tabs to match an existing repository convention.
It keeps text-bearing elements compact to avoid inserting layout characters into mixed content, while elements that contain other structural nodes are expanded across lines. This distinction matters because XML whitespace may be meaningful to downstream software. Formatting does not rename elements, reorder attributes, invent namespaces, or repair broken markup behind your back.
Validation happens before formatted output is returned
Pretty indentation is useful only when the underlying document is valid. The parser therefore checks the whole input before returning a formatted result. Every opening element must have the correct closing element, attribute names may occur only once on a tag, quoted attribute values must terminate correctly, and the document must contain exactly one root element.
Comments, CDATA sections, processing instructions, numeric character references, the five predefined XML entities, and a document type declaration are recognized and checked in their legal positions. Unknown named entities are rejected because resolving an external or custom entity without its declaration would be ambiguous and potentially unsafe. Errors include a concise reason, such as a mismatched closing tag or an unterminated comment, so you can locate the class of problem rather than receiving a partially formatted document.
What you can do with it
Reject malformed imports
Check incoming XML at a pipeline boundary and return a useful input error when tags, entities, or attributes are invalid.
FAQ
Does this repair malformed XML?
No. It returns an error when the document is not well-formed, so accidental repairs cannot hide a source-data problem.
Can I choose tabs or spaces?
Yes. Set the indent field to a string of spaces or tabs, up to eight characters. Two spaces are used by default.
Will formatting change text content?
Text-bearing and mixed-content elements stay compact so indentation is not inserted into their content. Entity spelling and attribute quoting may be normalized while preserving their parsed values.
Does it check my XML against an XSD or DTD?
No. It checks that the document itself is well-formed and never downloads definitions from the network. It does not confirm that the content follows a particular vocabulary or XSD, so use a dedicated validator for that.
Why is my XML rejected?
Because it is not well-formed. Typical reasons are a closing tag that does not match, an attribute repeated on one tag, an unterminated quote or comment, more than one root element, or an unknown named entity. The message names the kind of problem.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/web/xml-format \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"xml":"<catalog><book id=\"1\"><title>Practical XML</title><available>true</available></book></catalog>"}'const res = await fetch("https://api.kit.forhosting.com/web/xml-format", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"xml": "<catalog><book id=\"1\"><title>Practical XML</title><available>true</available></book></catalog>"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/web/xml-format",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"xml": "<catalog><book id=\"1\"><title>Practical XML</title><available>true</available></book></catalog>"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/web/xml-format", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"xml":"<catalog><book id=\\"1\\"><title>Practical XML</title><available>true</available></book></catalog>"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"xml":"<catalog><book id=\"1\"><title>Practical XML</title><available>true</available></book></catalog>"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/web/xml-format", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"xml": "<catalog><book id=\"1\"><title>Practical XML</title><available>true</available></book></catalog>"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "web.xml_format",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
timeout_sec | 30 |
max_crawl_pages | 25 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
Readable XML makes configuration, feeds, integration payloads, and document formats much easier to inspect. This formatter parses the XML you provide, verifies that its structure is well-formed, and serializes it again with predictable indentation.
Turn compressed XML into a structure people can review
XML often reaches a developer as one long line from an API response, an exported settings file, or a message copied from a log.
Validation happens before formatted output is returned
This capability deliberately does not fetch schemas, DTD resources, or namespace definitions from the network. It checks whether the XML itself is well-formed; it does not claim that the document conforms to a particular business vocabulary or XSD.
Use the browser for quick checks and the API for repeatable workflows
Because the implementation uses no network calls, random values, clocks, or model inference, identical input and indentation settings produce identical output. That stability is valuable in version control: formatting changes remain focused and do not drift between runs. Treat the result as a presentation-normalized version of the same XML structure, not as canonical XML for cryptographic signatures. For recurring work, the API makes the same deterministic algorithm available to tests, ingestion pipelines, support utilities, and editor integrations for $0.002 per request. If a signature, byte-for-byte preservation, schema validation, external entity expansion, or a specialized canonicalization standard is required, use a security-reviewed XML library designed for that exact workflow before verifying or signing the document.
Integration use cases
Review an API payload
Expand a compact XML response into a readable hierarchy before debugging field values, nesting, and attributes.
Normalize test fixtures
Apply stable indentation to generated XML so code reviews and snapshot comparisons show structural changes clearly.
Technical questions
How much does XML formatting cost?
It is free in the browser runner and costs $0.002 per API request.
Does it validate against an XSD or DTD?
No. It checks XML well-formedness only and does not fetch or apply external schemas or DTD resources.