Skip to main content

Guide · Validators

Well-Formed XML Is Not XSD (and Not an XML Bomb Test)

Updated 2026-09-01 · 7 min read

XML people say “valid” and mean two different things. Well-formed means the document is a tree: one root, matching tags, quoted attributes. Valid in the schema sense means the tree matches an XSD (or a DTD, Relax NG, Schematron - pick your era). Browsers will help with the first. They will not quietly become a full XSD 1.1 engine in a marketing sentence.

DevOkk’s XML Validator uses DOMParser for well-formedness. Default <root></root> passes. A missing end tag fails. It is not XSD, not DTD validation, and not an XML bomb tester. After the tree is well-formed, XML to JSON can project it into JSON in the tab. Pretty-print the JSON with JSON Formatter. The projection’s weird keys are Why XML to JSON looks wrong.

JSON has the same split: A JSON validator is not JSON Schema.

Well-formedness is a short checklist

  • One root element
  • Start and end tags match and nest
  • Attribute values quoted
  • Special characters escaped in the right places
  • No overlapping elements (<a><b></a></b> is illegal)

<root></root> meets the list. <root> does not. <root><item></root> does not. That is the validator’s job. It is a large fraction of “the SOAP paste is truncated” incidents.

It is not: “this is a PurchaseOrder as defined in purchase-order.xsd.” A well-formed <foo/> is still <foo/>.

Why the browser will not do your XSD

XSD 1.0/1.1 is a large specification: types, facets, identity constraints, wildcards, assertions in 1.1. JavaScript in a tab does not include a complete processor the way a Java or .NET stack might. DevOkk does not fake one. If your CI uses xmllint --schema or an enterprise validator, keep using that. The public page is the well-formedness gate you can run without installing that stack.

DTD “validation” would also mean fetching or embedding a DTD. External DTD loads are a classic XXE-shaped hazard. This tool does not go fetch SYSTEM identifiers. That is a safety choice, not a missing checkbox.

Namespaces are preserved, not proven

DOMParser keeps xmlns declarations. It does not prove that every prefixed name is bound to the schema you had in mind, or that soap:Envelope is the SOAP version you wanted. A well-formed SOAP 1.1 envelope can still be the wrong operation, the wrong body, or a fault. Convert-to-JSON will flatten namespaces into ugly keys. That is expected.

Encoding declarations, CDATA, and processing instructions

<?xml version="1.0" encoding="UTF-8"?> is legal prologue. A well-formedness check still does not verify that the bytes matched the declaration if the browser already decoded the string you pasted. You pasted Unicode text, not a file on disk with a conflicting encoding.

CDATA sections wrap text so < does not start a tag. They are well-formed when closed. They are not a schema. Processing instructions (<?xml-stylesheet ...?>) can appear in well-formed documents. The validator is not applying the stylesheet.

Comments in XML are allowed when they nest correctly. They are not DTDs. They will vanish or become odd keys if you convert to JSON, depending on the converter. Well-formedness passed either way.

Worked example: well-formed and still useless

<root>
  <item sku="A-104">2</item>
</root>

Well-formed. Converted JSON might look like an object with @sku or a nested attribute map, plus a text node. Your code that expected { "sku": "A-104", "qty": 2 } will not find that shape. The XML validator already said yes. The contract was never asked.

A second document with two <item> siblings may become an array in JSON while one <item> stays an object. Well-formedness did not change. The converter heuristic did. Fix that after convert, not in the XML validator.

SOAP faults are well-formed XML too

A SOAP Fault envelope is still a tree. The XML validator will say yes. Your application should treat it as an error response, not as a successful PurchaseOrder. Well-formedness has no HTTP semantics. It does not know HTTP 200 versus 500. It only saw tags.

XHTML is XML. HTML5 is not required to be. Copying a React root’s innerHTML into the XML validator will fail for unquoted attributes and void tags that HTML allows. That failure is correct for XML and uninteresting for HTML. Use the right parser.

XML bombs, entities, and what this page is not

Billion laughs and related expansion attacks are about entity expansion. A well-formedness checker that does not expand external or huge internal entities is not a penetration-testing product. Do not use DevOkk as an XXE lab. Do not paste untrusted XML from a ticket to “see if it explodes.” If you handle untrusted XML, that is a server-side parser configuration problem with a security review, not a blog recipe.

HTML5 is not XML. A random page from “view source” will fail XML well-formedness for reasons that are legal HTML. Use an HTML parser or the HTML↔Markdown tool when the job is HTML. HTML ↔ Markdown Converter is a different category.

Attributes, mixed content, and the converter you run next

Well-formed <title xml:lang="en">Hello</title> is a tiny tree. JSON has no attribute axis, so XML to JSON will invent a convention (@xml:lang, _attributes, or similar). The XML validator already finished its job. The “wrong JSON” ticket is a projection ticket. Read Why XML to JSON looks wrong instead of loosening well-formedness.

Mixed content (<p>See <b>this</b> note</p>) is well-formed XML and hostile to a typed JSON object. The validator will not warn you that the JSON will grow #text keys. That is not an XSD failure either unless your schema forbade mixed content - which this browser page cannot apply.

YAML and JSON are not XML with different punctuation

YAML Validator parses YAML. JSON Validator parses JSON. Passing XML well-formedness does not make JSON.parse succeed. Convert first if the next consumer is JSON. Keep the XML if you still need comments, mixed content, or the original prefixes.

What “not well-formed” usually is in a paste

Truncation is first: you selected from <Envelope> and missed </Envelope>. Second is HTML copied from a browser that repaired tags you cannot see. Third is a log line prefix (2026-09-01 ERROR ) before the <. Strip the prefix. Fourth is smart quotes from a word processor around attributes. Fifth is an unescaped & in a URL inside an attribute.

The line the parser reports is a gift. Fix that site, re-validate, then convert. Do not run XML-to-JSON on a document that is not a tree and then file a JSON ticket.

HTML entities and named character references

XML has a small built-in entity set (lt, gt, amp, apos, quot). Named HTML entities like &nbsp; are not automatically defined in XML unless a DTD you are not loading said so. A paste from HTML that contains &nbsp; can fail well-formedness for a reason that surprises frontend engineers. Replace with the numeric character or actual Unicode. That is still not XSD.

& in a URL inside an attribute must be &amp; in XML. The validator is right to fail the raw ampersand. The converter never gets a vote.

Empty documents and whitespace-only pastes

An empty textarea is not well-formed XML. Whitespace-only is not a tree. A document that is only <!-- comment --> without an element is not a well-formed XML document in the usual one-root sense. Paste <root></root> to see a pass, then break it on purpose. The default exists so the first-run is a green well-formed example, not a mystery.

The converter never gets a vote. If you needed HTML, you are in the wrong validator. If you needed XSD, you are still in the wrong validator. Well-formedness is a gate, not a contract. A green well-formed result on a SOAP fault is still a fault.

Privacy of SOAP bodies

The document stays in the browser. Customer SOAP, health records, and payment XML are still a bad paste into any site you do not have a contract with. Prefer the local tab over a cloud “XML validate” upload. localStorage can remember the draft. Clear it. See What not to paste into online developer tools.

A well-formed dump can still be the wrong document

Open XML Validator when the question is “will this even parse as XML.” Open XML to JSON when you need a JSON projection of a tree that already nests. Keep XSD in the toolchain that actually implements it. The browser told you the tags matched. Your application still has to care what the tags meant.

Frequently asked questions

What does well-formed mean?

Tags nest, names match, attributes are quoted, and there is a single root. <root></root> is well-formed. <root> is not. That is not the same as valid against a schema. XML Validator checks well-formedness with the browser DOMParser.

Do you validate XSD?

No. Browser JavaScript does not ship a complete XSD 1.1 processor. The page is honest about that limit. A well-formed dump can still be the wrong document for your application.

Are DTDs loaded?

No. External DTD fetches would be a network and XXE-style hazard. The parser is used for well-formedness only.

Is this an XML bomb or XXE tester?

No. It will not expand billion-laughs payloads as a security product and it will not fetch external entities. Do not paste hostile XML into random tools to ‘see what happens.’

Does the XML leave the browser?

No. Drafts stay locally for up to 30 days. Convert only after the document is well-formed, on XML to JSON.

Why does the JSON still look wrong after a valid XML check?

Well-formed XML can still have attributes, mixed content, and namespaces that JSON cannot represent cleanly. That is Why XML to JSON looks wrong.

More reading that links back to the same tools and workflows.