Skip to content

Commit 9a40389

Browse files
committed
reuse tag from root
1 parent 929601b commit 9a40389

File tree

2 files changed

+46
-12
lines changed

2 files changed

+46
-12
lines changed

Tasks/XmlPatch/xmlPatcher.ts

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export class XmlPatcher implements patch.IPatcher {
4040
if (key[0] === '@') {
4141
target.setAttribute(key.substr(1), element);
4242
} else {
43-
let node = this.createNode(xml, this.detectNamespace(key));
43+
let node = this.createNode(xml, this.detectNamespace(xml, key));
4444
target.appendChild(node);
4545
this.transformObject(xml, element, node);
4646
}
@@ -79,15 +79,36 @@ export class XmlPatcher implements patch.IPatcher {
7979
};
8080
}
8181

82-
private detectNamespace(nodeName: string): { name: string, namespace: string | null, localName: string } {
82+
private detectNamespace(xml: Document, nodeName: string): { name: string, namespace: string | null, localName: string } {
8383
var colon = nodeName.lastIndexOf(':');
8484

8585
if (colon > 0) {
86-
return {
87-
name: nodeName,
88-
namespace: this.namespaces[nodeName.substr(0, colon)],
89-
localName: nodeName.substr(colon + 1)
90-
};
86+
const namespace = this.namespaces[nodeName.substr(0, colon)];
87+
const localName = nodeName.substr(colon + 1);
88+
89+
const defaultNamespace = xml.documentElement.lookupNamespaceURI('');
90+
const existingPrefix = xml.documentElement.lookupPrefix(namespace);
91+
92+
93+
if (defaultNamespace === namespace) {
94+
return {
95+
name: localName,
96+
namespace: namespace,
97+
localName: localName
98+
};
99+
} else if (existingPrefix !== null) {
100+
return {
101+
name: existingPrefix + ':' + localName,
102+
namespace: namespace,
103+
localName: localName
104+
};
105+
} else {
106+
return {
107+
name: nodeName,
108+
namespace: namespace,
109+
localName: nodeName.substr(colon + 1)
110+
};
111+
}
91112
}
92113

93114
return {
@@ -179,7 +200,7 @@ export class XmlPatcher implements patch.IPatcher {
179200
private add(xml: Document, select: any, patch: IPatch): boolean {
180201
let arrayOperation = this.detectArrayOperation(patch.path);
181202
if (arrayOperation.isArrayOperation) {
182-
let parsedName = this.detectNamespace(patch.value);
203+
let parsedName = this.detectNamespace(xml, patch.value);
183204
if (arrayOperation.append) {
184205
let node = <SVGSVGElement>select(arrayOperation.path, xml, true);
185206
let newNode = this.createNode(xml, parsedName);
@@ -202,11 +223,11 @@ export class XmlPatcher implements patch.IPatcher {
202223
var lastSlash = patch.path.lastIndexOf('/');
203224
var parentPath = patch.path.substr(0, lastSlash);
204225
var newNodeName = patch.path.substr(lastSlash + 1);
205-
var parsedName = this.detectNamespace(newNodeName);
226+
var parsedName = this.detectNamespace(xml, newNodeName);
206227
node = <SVGSVGElement>select(parentPath, xml, true);
207228
if (node) {
208229
if (newNodeName[0] == '@') {
209-
let attributeName = this.detectNamespace(newNodeName);
230+
let attributeName = this.detectNamespace(xml, newNodeName);
210231
if (attributeName.namespace) {
211232
node.setAttributeNS(attributeName.namespace, attributeName.name, patch.value);
212233
} else {
@@ -231,7 +252,7 @@ export class XmlPatcher implements patch.IPatcher {
231252
if (arrayOperation.isArrayOperation) {
232253
var node = <SVGSVGElement>select(arrayOperation.path, xml, true);
233254
var childNode = node.childNodes[arrayOperation.index];
234-
var newNode = this.createNode(xml, this.detectNamespace(patch.value));
255+
var newNode = this.createNode(xml, this.detectNamespace(xml, patch.value));
235256
node.insertBefore(newNode, childNode)
236257
node.removeChild(childNode);
237258
return true;

Tests/XmlPatch/xmlPatcher.spec.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,9 @@ describe("XML Patcher", () => {
253253
], namespaces);
254254
var result = patcher.apply(source);
255255

256-
expect(result).toEqual('<rootNode xmlns="http://example.com"><myns:newNode xmlns:myns="http://example.com">10</myns:newNode></rootNode>');
256+
expect(result).toEqual('<rootNode xmlns="http://example.com"><newNode>10</newNode></rootNode>');
257257
});
258+
258259

259260
it(": should support basic add with explicit namespace", () => {
260261
source = '<myns:rootNode xmlns:myns="http://example.com"></myns:rootNode>';
@@ -268,6 +269,18 @@ describe("XML Patcher", () => {
268269
expect(result).toEqual('<myns:rootNode xmlns:myns="http://example.com"><myns:newNode>10</myns:newNode></myns:rootNode>');
269270
});
270271

272+
it(": should support basic add with explicit namespace but different tag in xpath", () => {
273+
source = '<mynsorig:rootNode xmlns:mynsorig="http://example.com"></mynsorig:rootNode>';
274+
var patcher = new xmlatcher.XmlPatcher([
275+
{
276+
op: "add", path: "myns:rootNode/myns:newNode", value: "10"
277+
}
278+
], namespaces);
279+
var result = patcher.apply(source);
280+
281+
expect(result).toEqual('<mynsorig:rootNode xmlns:mynsorig="http://example.com"><mynsorig:newNode>10</mynsorig:newNode></mynsorig:rootNode>');
282+
});
283+
271284
it(": should support attribute namespace", () => {
272285
source = '<myns:rootNode xmlns:myns="http://example.com"></myns:rootNode>';
273286
var patcher = new xmlatcher.XmlPatcher([

0 commit comments

Comments
 (0)