What this tool does
It decodes the five entities XML predefines — &, <, >, " and ' — along with numeric character references in both forms: decimal A and hexadecimal A, including characters above U+FFFF, so 😀 comes back as its emoji.
Entity names are case-sensitive, as XML requires: & decodes, & does not. A reference also needs its semicolon — & without one is ordinary text and is left as such.
One pass, deliberately
Decoding runs exactly once. &lt; gives <, not <, because &lt; is the escaped form of the literal text < and that text is the correct answer.
Running the decode a second time is how escaped markup turns back into live markup — the step behind a whole class of injection bugs. If you genuinely have a doubly encoded value, paste the result back in and decode again, as a decision you make rather than one the tool makes for you.
What it does not do
HTML named entities are out of scope. , © and the several thousand others belong to HTML, not XML, and come back untouched.
Invalid numeric references are preserved verbatim rather than replaced. A surrogate code point (�) or a value beyond U+10FFFF (�) cannot map to a character, and returning the reference unchanged keeps the input recoverable instead of quietly losing it. The same applies to every character XML 1.0 cannot represent at all — NUL, most control characters, the non-characters U+FFFE and U+FFFF: � and  come back as written. Decoding them would hand you a document no XML parser will accept.
Private by design
Everything runs locally in your browser with JavaScript. Your data is never uploaded, which makes the tool safe for sensitive content, and it keeps working offline.