XML URL Encode
Check it parses, strip the indentation, then escape it for a URL
XML Input
Encoded Output
XML in a query string
This usually turns up in one of two ways. Either a legacy endpoint takes an XML document as a GET parameter, or you are reproducing a request someone captured and the payload has to go back into the URL exactly as it was. Both need every angle bracket, quote and equals sign escaped, because a query string treats most of XML's punctuation as its own.
XML pays a heavier price for this than any other format here. The sample below is 215 characters of XML and 347 characters once encoded — every < becomes %3C, every quote in an attribute becomes %22, and every newline in the indentation becomes %0A. Collapsing the whitespace first brings that to 278, which is a fifth of the length gone without changing a single thing the document says.
That collapse is the part worth being careful about, so it refuses rather than guesses. Whitespace between two tags is indentation and goes. Whitespace beside an element is content and stays — in <p>Hello <b>world</b></p> that space after "Hello" is part of the sentence, and stripping it would silently rewrite the text. Anything marked xml:space="preserve" is left entirely alone, and the compacted document is compared against the original before it is used. If the two disagree, nothing is changed.
The document is also parsed before anything is encoded. Percent-encoding escapes characters, not meaning, so a malformed document encodes perfectly happily and then fails wherever it is finally parsed — by which point the error is about the request rather than about the XML. When the parse fails here you get the browser's own message, verbatim, because xmlParseEntityRef: no name is gibberish exactly once and instantly recognisable as a bare ampersand ever after.
How to use it
- Paste the XML – Type it, paste it, or upload an
.xmlfile. A document that will not parse stops here, with the real parser message and the line and column it came from. - Leave "Collapse indentation" on – It is the single biggest saving available on an XML payload, and it is guarded — see the note above about mixed content. The chip tells you how many characters went.
- Keep the style on "One value" – That is
encodeURIComponent. "Whole URL" deliberately leaves&,=and#unescaped, which for a document full of attributes and entities means the value ends at the first ampersand. - Check the length chip against 2000 – XML reaches that ceiling faster than anything else on this site. If a realistic document does not fit, that is a design signal — a POST body or a Base64 payload is usually the better answer than a longer URL.
- Decode it once, and only once – The output is the parameter value. When it comes back, XML URL Decode unwinds exactly one layer, which is what you want — the entities underneath belong to the XML.
If you are hand-building the URL in a shell, quote it. An unquoted encoded document is full of characters your shell will happily interpret, and the resulting bug looks like an encoding fault rather than a quoting one. Wrapping the whole thing in single quotes costs nothing and removes an entire category of confusion.
Why the ampersand comes out as %26amp%3B
This is the output people stop and stare at, so it is worth understanding rather than working around. There are two separate escaping layers stacked here, and they are not the same layer applied twice. XML requires an ampersand in text to be written as & — that is the XML spec, not a choice. The URL then requires the & and ; of that entity to be escaped in turn. Unwinding them in the wrong order, or one too many times, is where documents break:
<apn>internet&mms</apn> # the author typed one & # XML requires it be written # as the entity &
# encoded — both layers on %3Capn%3Einternet%26amp%3Bmms… # decode the URL layer once — # this is what you want <apn>internet&mms</apn> # strip the entity layer too # and Chromium rejects it: <apn>internet&mms</apn> # xmlParseEntityRef: no name
When this comes up
A legacy endpoint that takes XML on a GET
Older integrations do this more often than you would hope, usually because the request needed to be cacheable or because it started life as a form post. The length ceiling is the thing that eventually bites, and it does so in production rather than in testing, because test documents are small.
Replaying a captured SOAP or RSS request
You have a request from a log or a capture and want to fire it again with one field changed. Decode it with XML URL Decode, edit the readable document, and re-encode it here — much faster than editing percent-escapes by hand and far harder to get wrong.
A callback that carries a signed XML fragment
SAML and similar flows put XML into redirect parameters. Those payloads are usually Base64 rather than percent-encoded precisely because of the length cost shown above, but the percent-encoded form still turns up, and it is worth being able to read either.
Working out why a request fails only in production
A URL that works locally and fails behind a load balancer is very often a length problem rather than an encoding one. Encoding the real document here and reading the character count settles that in seconds, before anyone starts bisecting the payload.
What this page does
- Parses the document before encoding, and shows the browser's own parser error with its line and column when it fails.
- Collapses indentation without touching mixed content, CDATA sections, comments, or anything under
xml:space="preserve". - Verifies the collapsed document against the original and abandons the change if they differ.
- Reports the escape count and the encoded length, and warns past 2000 characters.
- Offers all three encoding styles, with the correct one as the default.
- Runs entirely in your browser — nothing is uploaded, which matters for anything carrying subscriber data.
Questions people actually ask
Is %26amp%3B double encoded? It looks wrong.
It is correct, and it is the most common thing people "fix" into a broken document. Two different layers are stacked: XML turned & into &, then the URL turned that into %26amp%3B. Decoding the URL layer once gives you & back, which is the right XML. Going further and turning it into a bare & gives you a document Chromium rejects with xmlParseEntityRef: no name. Double encoding looks different — it shows up as %25.
Why is my encoded XML nearly twice the length?
Because almost everything structural in XML is a reserved URL character. Angle brackets, quotes, equals signs, slashes and newlines all become three characters each. The sample here goes from 215 to 347, and it is a small document. This is why XML in a URL runs into length limits long before JSON does.
Does collapsing the indentation change my document?
Only whitespace that sits between two tags, which is indentation by definition. Text next to an element is mixed content and is left alone, as is anything under xml:space="preserve". The result is parsed again and compared with the original — element names, attributes, comments, CDATA and all non-whitespace text — and if anything differs the original is used unchanged.
What happened to my XML declaration?
It survives encoding like any other text — <?xml version="1.0"?> becomes 62 characters from 38, because the angle brackets, question marks, quotes, equals sign and space all escape. If length is tight and the receiving parser does not need it, dropping the declaration is a legitimate saving, though it is worth being sure about the encoding first.
Should I Base64 the XML instead?
For anything of real size, usually yes. Base64 is a flat 33% overhead where percent-encoded XML here ran to 61%, and the result contains nothing a URL cares about. You lose readability in the link and in your logs, which is the trade. XML to Base64 will give you both numbers for your own document.
Will this handle a document with a namespace or a DTD?
Namespaces are ordinary attributes as far as encoding is concerned, so yes. A DTD is passed through as text; note that the browser parser does not fetch external entities, so a document depending on one will parse here but may behave differently in a validating parser. The Namespaces in XML spec is the reference if a prefix is behaving unexpectedly.
Related tools
References
- XML 1.0 — Character Data and Markup – Why an ampersand must be written as an entity
- RFC 3986 §2.2 — Reserved Characters – The set a query string treats as structure
- MDN — DOMParser – The parser whose messages this page shows you