xref: /PHP-8.4/ext/dom/tests/bug47530.phpt (revision e127f871)
1--TEST--
2Bug #47530 (Importing objects into document fragments creates bogus "default" namespace)
3--EXTENSIONS--
4dom
5--FILE--
6<?php
7
8function test_document_fragment_with_import() {
9    $doc = new DOMDocument;
10    $doc->loadXML('<html xmlns="https://php.net/something" xmlns:ns="https://php.net/whatever"><element ns:foo="https://php.net/bar"/></html>');
11    $root = $doc->documentElement;
12    $frag = $doc->createDocumentFragment();
13    $frag->appendChild($doc->importNode($root->firstChild));
14    $root->appendChild($frag);
15    echo $doc->saveXML();
16}
17
18function test_document_fragment_without_import() {
19    $doc = new DOMDocument;
20    $doc->loadXML('<html xmlns=""><element xmlns:foo="https://php.net/bar"/></html>');
21    $frag = $doc->createDocumentFragment();
22    $frag->appendChild($doc->createElementNS('https://php.net/bar', 'bar'));
23    $frag->appendChild($doc->createElementNS('', 'bar'));
24    $element = $doc->documentElement->firstChild;
25    $element->appendChild($frag);
26    unset($frag); // Free fragment, should not break getting the namespaceURI below
27    echo $doc->saveXML();
28    unset($doc);
29    var_dump($element->firstChild->tagName);
30    var_dump($element->firstChild->namespaceURI);
31}
32
33function test_document_import() {
34    $xml = <<<XML
35<?xml version="1.0" encoding="utf-8"?>
36<feed xmlns="http://www.w3.org/2005/Atom">
37<div xmlns="http://www.w3.org/1999/xhtml">
38    <p>Test-Text</p>
39</div>
40</feed>
41XML;
42
43    $dom = new DOMDocument();
44    $dom->loadXML($xml);
45
46    $dom2 = new DOMDocument();
47    $importedNode = $dom2->importNode($dom->documentElement, true);
48    $dom2->appendChild($importedNode);
49
50    echo $dom2->saveXML();
51}
52
53function test_partial_document_import() {
54    $xml = <<<XML
55<?xml version="1.0" encoding="utf-8"?>
56<feed xmlns="http://www.w3.org/1999/xhtml" xmlns:test="https://php.net/test" xmlns:example="https://php.net/example">
57<div>
58    <p>Test-Text</p>
59    <example:p>More test text</example:p>
60    <test:p>Even more test text</test:p>
61</div>
62</feed>
63XML;
64
65    $dom = new DOMDocument();
66    $dom->loadXML($xml);
67
68    $dom2 = new DOMDocument();
69    $dom2->loadXML('<?xml version="1.0"?><container xmlns:test="https://php.net/test" xmlns="https://php.net/example"/>');
70    $importedNode = $dom2->importNode($dom->documentElement, true);
71    $dom2->documentElement->appendChild($importedNode);
72
73    // Freeing the original document shouldn't break the other document
74    unset($importedNode);
75    unset($dom);
76
77    echo $dom2->saveXML();
78}
79
80function test_document_import_with_attributes() {
81    $dom = new DOMDocument();
82    $dom->loadXML('<?xml version="1.0"?><div xmlns="https://php.net/default" xmlns:example="https://php.net/example"><p example:test="test"/><i/></div>');
83    $dom2 = new DOMDocument();
84    $dom2->loadXML('<?xml version="1.0"?><div xmlns:example="https://php.net/somethingelse"/>');
85    $dom2->documentElement->appendChild($dom2->importNode($dom->documentElement->firstChild));
86    echo $dom2->saveXML(), "\n";
87
88    $dom2->documentElement->firstChild->appendChild($dom2->importNode($dom->documentElement->firstChild->nextSibling));
89    echo $dom2->saveXML(), "\n";
90}
91
92function test_appendChild_with_shadowing() {
93    $dom = new DOMDocument();
94    $dom->loadXML('<?xml version="1.0"?><container xmlns:default="http://php.net/default"><a xmlns:foo="http://php.net/bar"/><b xmlns:foo="http://php.net/foo"><default:test foo:bar=""/><foo:test2/></b></container>');
95
96    $a = $dom->documentElement->firstElementChild;
97    $b = $a->nextSibling;
98    $b->remove();
99    $a->appendChild($b);
100
101    echo $dom->saveXML(), "\n";
102}
103
104echo "-- Test document fragment with import --\n";
105test_document_fragment_with_import();
106echo "-- Test document fragment without import --\n";
107test_document_fragment_without_import();
108echo "-- Test document import --\n";
109test_document_import();
110echo "-- Test partial document import --\n";
111test_partial_document_import();
112echo "-- Test document import with attributes --\n";
113test_document_import_with_attributes();
114echo "-- Test appendChild with shadowing --\n";
115test_appendChild_with_shadowing();
116
117?>
118--EXPECT--
119-- Test document fragment with import --
120<?xml version="1.0"?>
121<html xmlns="https://php.net/something" xmlns:ns="https://php.net/whatever"><default:element xmlns:default="https://php.net/something" ns:foo="https://php.net/bar"/></html>
122-- Test document fragment without import --
123<?xml version="1.0"?>
124<html xmlns=""><element xmlns:foo="https://php.net/bar"><foo:bar/><bar/></element></html>
125string(7) "foo:bar"
126string(19) "https://php.net/bar"
127-- Test document import --
128<?xml version="1.0"?>
129<feed xmlns="http://www.w3.org/2005/Atom" xmlns:default="http://www.w3.org/1999/xhtml">
130<default:div xmlns="http://www.w3.org/1999/xhtml">
131    <default:p>Test-Text</default:p>
132</default:div>
133</feed>
134-- Test partial document import --
135<?xml version="1.0"?>
136<container xmlns:test="https://php.net/test" xmlns="https://php.net/example"><feed xmlns="http://www.w3.org/1999/xhtml" xmlns:example="https://php.net/example">
137<div>
138    <p>Test-Text</p>
139    <example:p>More test text</example:p>
140    <test:p>Even more test text</test:p>
141</div>
142</feed></container>
143-- Test document import with attributes --
144<?xml version="1.0"?>
145<div xmlns:example="https://php.net/somethingelse"><p xmlns="https://php.net/default" xmlns:example="https://php.net/example" example:test="test"/></div>
146
147<?xml version="1.0"?>
148<div xmlns:example="https://php.net/somethingelse"><p xmlns="https://php.net/default" xmlns:example="https://php.net/example" example:test="test"><i/></p></div>
149
150-- Test appendChild with shadowing --
151<?xml version="1.0"?>
152<container xmlns:default="http://php.net/default"><a xmlns:foo="http://php.net/bar"><b xmlns:foo="http://php.net/foo"><default:test foo:bar=""/><foo:test2/></b></a></container>
153