<?php /** * Dom\XMLDocument::C14N() drops namespace declarations on DOM-built documents * * When a Dom\XMLDocument is built via the DOM API (createElementNS, appendChild), * non-exclusive C14N() strips all namespace declarations while keeping prefixed * element names, producing invalid XML that cannot be re-parsed. * * This does NOT happen when: * - The document is parsed from a string (createFromString) * - Using legacy DOMDocument (DOM-built or parsed) * - Using exclusive C14N (C14N(exclusive: true)) * * Related: https://github.com/php/php-src/issues/20444 * Possibly related fix: https://github.com/php/php-src/commit/40c291cf932c31a302fa584bb50b6edb199fb07e * (but still broken on PHP 8.4.19) */ echo "PHP " . PHP_VERSION . PHP_EOL . PHP_EOL; // 1. DOM-built document: C14N drops namespace declarations $doc = Dom\XMLDocument::createEmpty(); $root = $doc->createElementNS("urn:envelope", "env:Root"); $doc->appendChild($root); $child = $doc->createElementNS("urn:child", "x:Child"); $root->appendChild($child); echo "DOM-built Dom\XMLDocument" . PHP_EOL; echo " saveXML: " . trim($doc->saveXML()) . PHP_EOL; echo " C14N: " . $doc->C14N() . PHP_EOL; // Expected: <env:Root xmlns:env="urn:envelope"><x:Child xmlns:x="urn:child"></x:Child></env:Root> // Actual: <env:Root><x:Child></x:Child></env:Root> // ^ namespace declarations are missing, this is not valid XML echo PHP_EOL; // 2. Same structure parsed from string: C14N works correctly $doc2 = Dom\XMLDocument::createFromString( '<env:Root xmlns:env="urn:envelope"><x:Child xmlns:x="urn:child"/></env:Root>' ); echo "Parsed Dom\XMLDocument" . PHP_EOL; echo " C14N: " . $doc2->C14N() . PHP_EOL; // Correct: <env:Root xmlns:env="urn:envelope"><x:Child xmlns:x="urn:child"></x:Child></env:Root> echo PHP_EOL; // 3. Legacy DOMDocument DOM-built: C14N works correctly $doc3 = new DOMDocument(); $root3 = $doc3->createElementNS("urn:envelope", "env:Root"); $doc3->appendChild($root3); $child3 = $doc3->createElementNS("urn:child", "x:Child"); $root3->appendChild($child3); echo "DOM-built DOMDocument (legacy)" . PHP_EOL; echo " C14N: " . $doc3->C14N() . PHP_EOL; // Correct: <env:Root xmlns:env="urn:envelope"><x:Child xmlns:x="urn:child"></x:Child></env:Root> echo PHP_EOL; // 4. Exclusive C14N on DOM-built document: works correctly echo "DOM-built Dom\XMLDocument (exclusive C14N)" . PHP_EOL; echo " C14N: " . $doc->C14N(exclusive: true) . PHP_EOL; // Correct: <env:Root xmlns:env="urn:envelope"><x:Child xmlns:x="urn:child"></x:Child></env:Root>
You have javascript disabled. You will not be able to edit any code.