XML is strict about syntax and dangerously generous about entities
One unescaped ampersand and a conforming parser must stop; that’s well-formedness. A DOCTYPE can also define entities that expand into other entities or pull in files from disk, which is how billion-laughs and XXE attacks work. Namespaces then make the same tag name mean different things. This page parses with your browser’s own XML parser, then shows the encoding, the namespace-resolved tree, live XPath, entity expansion and Canonical XML hashing.
<?xml version="1.0" encoding="UTF-8"?><invoice xmlns="urn:example:invoice:2" xmlns:addr="urn:example:address" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:example:invoice:2 invoice.xsd" number="INV-2026-0417" currency="EUR" xml:lang="de">
In XPath 1.0 an unprefixed name means “no namespace”. So once a document declares xmlns="…", //invoice matches nothing even though the tag says invoice. You have to bind a prefix to the URI and write //inv:invoice. The prefixes below are taken from the file, plus inv: for its default namespace.
Each level of the billion-laughs DTD repeats the previous entity ten times. The page works out the expanded size arithmetically rather than expanding it. It then hands your browser a safe three-level version and a document with an external SYSTEM entity, to see what its parser really does.
<?xml version="1.0"?><!DOCTYPE lolz [ <!ENTITY lol0 "lol"> <!ENTITY lol1 "&lol0;&lol0;&lol0;&lol0;&lol0;&lol0;&lol0;&lol0;&lol0;&lol0;"> <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;"> <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;"> <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;"> <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;"> <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;"> <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;"> <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;"> <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">]><lolz>&lol9;</lolz>
Attribute order, quote style, empty-tag shorthand, character references and CRLF don’t change what an XML document means, so XML-DSig signs a canonical form instead (C14N 1.0). This page writes that form itself: attributes sorted by namespace and name, namespace declarations first, <a/> expanded to <a></a>, text escaped one fixed way. Then it hashes it with SHA-256. Edit either side.
<order xmlns="urn:shop" currency="EUR" id="42"> <item qty="2" sku="A-1"></item> <note>café & bar</note></order>c14n sha-256 83db40aa68ad3d62adb1f0feeb8923d96d614e4aaa99665a4f87caf32147556f
<order xmlns="urn:shop" currency="EUR" id="42"> <item qty="2" sku="A-1"></item> <note>café & bar</note></order>c14n sha-256 83db40aa68ad3d62adb1f0feeb8923d96d614e4aaa99665a4f87caf32147556f