Skip to content

Commit 2ba20fa

Browse files
committed
Merge branch 'svobik7-master'
2 parents 723a92b + 466c819 commit 2ba20fa

File tree

2 files changed

+72
-10
lines changed

2 files changed

+72
-10
lines changed

src/builder/XMLBuilderImpl.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,17 @@ export class XMLBuilderImpl implements XMLBuilder {
377377

378378
const importedNode = node.node
379379

380+
const updateImportedNodeNs = (clone: Element) => {
381+
// update namespace of imported node only when not specified
382+
if (!clone._namespace) {
383+
const [prefix] = namespace_extractQName(
384+
clone.prefix ? clone.prefix + ':' + clone.localName : clone.localName
385+
);
386+
const namespace = hostNode.lookupNamespaceURI(prefix)
387+
new XMLBuilderImpl(clone)._updateNamespace(namespace)
388+
}
389+
};
390+
380391
if (Guard.isDocumentNode(importedNode)) {
381392
// import document node
382393
const elementNode = importedNode.documentElement
@@ -385,28 +396,22 @@ export class XMLBuilderImpl implements XMLBuilder {
385396
}
386397
const clone = hostDoc.importNode(elementNode, true) as Element
387398
hostNode.appendChild(clone)
388-
const [prefix] = namespace_extractQName(clone.prefix ? clone.prefix + ':' + clone.localName : clone.localName)
389-
const namespace = hostNode.lookupNamespaceURI(prefix)
390-
new XMLBuilderImpl(clone)._updateNamespace(namespace)
399+
updateImportedNodeNs(clone)
391400
} else if (Guard.isDocumentFragmentNode(importedNode)) {
392401
// import child nodes
393402
for (const childNode of importedNode.childNodes) {
394403
const clone = hostDoc.importNode(childNode, true)
395404
hostNode.appendChild(clone)
396405
if (Guard.isElementNode(clone)) {
397-
const [prefix] = namespace_extractQName(clone.prefix ? clone.prefix + ':' + clone.localName : clone.localName)
398-
const namespace = hostNode.lookupNamespaceURI(prefix)
399-
new XMLBuilderImpl(clone)._updateNamespace(namespace)
406+
updateImportedNodeNs(clone)
400407
}
401408
}
402409
} else {
403410
// import node
404411
const clone = hostDoc.importNode(importedNode, true)
405412
hostNode.appendChild(clone)
406413
if (Guard.isElementNode(clone)) {
407-
const [prefix] = namespace_extractQName(clone.prefix ? clone.prefix + ':' + clone.localName : clone.localName)
408-
const namespace = hostNode.lookupNamespaceURI(prefix)
409-
new XMLBuilderImpl(clone)._updateNamespace(namespace)
414+
updateImportedNodeNs(clone)
410415
}
411416
}
412417

@@ -766,7 +771,7 @@ export class XMLBuilderImpl implements XMLBuilder {
766771
for (const childNode of ele.childNodes) {
767772
const newChildNode = childNode.cloneNode(true)
768773
newEle.appendChild(newChildNode)
769-
if (Guard.isElementNode(newChildNode)) {
774+
if (Guard.isElementNode(newChildNode) && !newChildNode._namespace) {
770775
const [newChildNodePrefix] = namespace_extractQName(newChildNode.prefix ? newChildNode.prefix + ':' + newChildNode.localName : newChildNode.localName)
771776
const newChildNodeNS = newEle.lookupNamespaceURI(newChildNodePrefix)
772777
new XMLBuilderImpl(newChildNode)._updateNamespace(newChildNodeNS)

test/issues/issue-178.test.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import $$ from '../TestHelpers';
2+
3+
describe('Replicate issue', () => {
4+
// https://github.com/oozcitak/xmlbuilder2/issues/90
5+
describe(`#178 - Namespace is removed when importing fragments.`, () => {
6+
const expectedOutput = $$.t`<?xml version="1.0"?><Root xmlns="ns1"><Parent xmlns="ns2"><Child xmlns="ns3"><GrandChild xmlns="ns4">txt</GrandChild></Child></Parent></Root>`;
7+
describe(`with defined namespaces on each element`, () => {
8+
test(`using .ele()`, () => {
9+
const doc = $$.create();
10+
const root = doc.ele('ns1', 'Root');
11+
const parent = root.ele('ns2', 'Parent');
12+
const child = parent.ele('ns3', 'Child');
13+
child.ele('ns4', 'GrandChild').txt('txt');
14+
15+
expect(doc.end()).toBe(expectedOutput);
16+
});
17+
test(`using .import()`, () => {
18+
const doc = $$.create();
19+
const root = doc.ele('ns1', 'Root');
20+
const parent = $$.fragment().ele('ns2', 'Parent');
21+
const child = $$.fragment().ele('ns3', 'Child');
22+
const grandChild = $$.fragment().ele('ns4', 'GrandChild').txt('txt');
23+
24+
child.import(grandChild);
25+
parent.import(child);
26+
root.import(parent);
27+
28+
expect(doc.end()).toBe(expectedOutput);
29+
});
30+
});
31+
describe(`with undefined namespaces on parent element`, () => {
32+
const expectedOutput = $$.t`<?xml version="1.0"?><Root xmlns="ns1"><Parent><Child xmlns="ns3"><GrandChild xmlns="ns4">txt</GrandChild></Child></Parent></Root>`;
33+
test(`using .ele()`, () => {
34+
const doc = $$.create();
35+
const root = doc.ele('ns1', 'Root');
36+
const parent = root.ele('Parent');
37+
const child = parent.ele('ns3', 'Child');
38+
child.ele('ns4', 'GrandChild').txt('txt');
39+
40+
expect(doc.end()).toBe(expectedOutput);
41+
});
42+
test(`using .import()`, () => {
43+
const doc = $$.create();
44+
const root = doc.ele('ns1', 'Root');
45+
const parent = $$.fragment().ele('Parent');
46+
const child = $$.fragment().ele('ns3', 'Child');
47+
const grandChild = $$.fragment().ele('ns4', 'GrandChild').txt('txt');
48+
49+
child.import(grandChild);
50+
parent.import(child);
51+
root.import(parent);
52+
53+
expect(doc.end()).toBe(expectedOutput);
54+
});
55+
});
56+
});
57+
});

0 commit comments

Comments
 (0)