Skip to content

Commit e439f57

Browse files
author
Chris Wiechmann
authored
Merge pull request #63 from Axway-API-Builder-Ext/add-remove-all-namespaces
2 parents 961d45f + 59b0325 commit e439f57

4 files changed

Lines changed: 76 additions & 6 deletions

File tree

api-builder-plugin-fn-xml-node/src/flow-nodes.yml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,21 @@ flow-nodes:
2626
type: boolean
2727
selectPath:
2828
name: Select object with path
29-
description: "Select the object within the returned structure using this path. Example: $[\"soap:Envelope\"][\"soap:Body\"]"
29+
description: "Select the object within the returned structure using this path. Example: $[\"soap:Envelope\"][\"soap:Body\"]. If you remove namespaces, remember to also remove them here."
3030
required: false
3131
initialType: string
3232
schema:
3333
type: string
34+
removeAllNamespaces:
35+
name: Remove all namespaces
36+
description: 'This will remove all namespaces from the JSON-message. Overrides Remove Specific Namespaces.'
37+
required: false
38+
initialType: boolean
39+
schema:
40+
default: false
41+
type: boolean
3442
removeNamespaces:
35-
name: Remove namespaces
43+
name: Remove specific namespaces
3644
description: 'An Array of namespaces to be removed from the JSON-Message. Example: ["v1"] will convert the following: "<v1:radius_airportsResponse>" into "radius_airportsResponse": {'
3745
required: false
3846
initialType: array

api-builder-plugin-fn-xml-node/src/xmlToJson.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ var jp = require('jsonpath');
2121
* does not define "next", the first defined output).
2222
*/
2323
async function xml2json(params, options) {
24-
const { xmlData, asString, selectPath, removeNamespaces, ignoreCdata, nativeBooleans } = params;
24+
const { xmlData, asString, selectPath, removeAllNamespaces, removeNamespaces, ignoreCdata, nativeBooleans } = params;
2525
const { logger } = options;
2626
if (!xmlData) {
2727
throw new Error('Missing required parameter: xmlData');
@@ -42,7 +42,7 @@ async function xml2json(params, options) {
4242
if(nativeBooleans) {
4343
xml2JsonOptions.textFn = handleTextFnNativeBoolean;
4444
}
45-
if (removeNamespaces) {
45+
if ((removeNamespaces) || (removeAllNamespaces)) {
4646
xml2JsonOptions.elementNameFn = removeNamespacesFn;
4747
}
4848

@@ -59,15 +59,18 @@ async function xml2json(params, options) {
5959
logger.error(e.message);
6060
throw new Error(`Failed to convert XML to JSON. Error: ${e.message}`);
6161
}
62+
6263
if (typeof result === 'undefined') {
6364
throw new Error(`Failed to convert XML to JSON. Error: result is undefined`);
6465
}
66+
6567
if (selectPath) {
6668
result = jp.value(result, selectPath);
6769
if (result == undefined) {
6870
throw new Error(`Nothing found in response message based on path: '${selectPath}'.`);
6971
}
7072
}
73+
7174
return result;
7275

7376
function handleTextFn(value, parentElement) {
@@ -133,13 +136,22 @@ async function xml2json(params, options) {
133136
}
134137

135138
function removeNamespacesFn(val) {
136-
if (val.indexOf(":") == -1) return val;
139+
if (val.indexOf(":") == -1) {
140+
return val;
141+
}
142+
143+
if (removeAllNamespaces == true) {
144+
// Don't need to check for ":" because of previous check
145+
return val.split(":")[1];
146+
}
147+
137148
for (var i = 0; i < removeNamespaces.length; ++i) {
138149
var namespace = removeNamespaces[i];
139150
if (val.startsWith(`${namespace}:`)) {
140151
return val.replace(`${namespace}:`, '');
141152
}
142153
}
154+
143155
return val;
144156
}
145157
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"Envelope": {
3+
"Header": {},
4+
"Body": {
5+
"radius_airportsResponse": {
6+
"return": {
7+
"fs": "TXL",
8+
"iata": "TXL",
9+
"icao": "TXL",
10+
"faa": "TXL",
11+
"name": "Berlin Tegel",
12+
"street1": "Saatwinkler Damm",
13+
"city": "Berlin",
14+
"cityCode": "B",
15+
"stateCode": "B",
16+
"postalCode": "13405",
17+
"countryCode": "DE",
18+
"countryName": "Germany",
19+
"regionName": "DE",
20+
"timeZoneRegionName": "GMT",
21+
"weatherZone": "Germany",
22+
"localTime": "19:02",
23+
"utcOffsetHours": "-1",
24+
"latitude": "39.0438",
25+
"longitude": "-77.4874"
26+
}
27+
}
28+
}
29+
}
30+
}

api-builder-plugin-fn-xml-node/test/xmlToJsonTest.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,27 @@ describe('api-builder-plugin-fn-xml-node', () => {
104104
expect(output).to.equal('error');
105105
});
106106

107-
it('should return only the SOAP-Body and Namespaces removed', async () => {
107+
it('should return only the SOAP-Body and all Namespaces removed and removeNamespaces not set', async () => {
108+
var xmlMessage = require('fs').readFileSync('./test/testMessages/airports_soap_response_namespace.xml', 'utf8');
109+
var jsonMessage = JSON.parse(require('fs').readFileSync('./test/testMessages/airports_soap_body_no_namespace_or_envelope.json', 'utf8'));
110+
const { value, output } = await flowNode.xml2json({ xmlData: xmlMessage, selectPath: '$[\"Envelope\"][\"Body\"]', removeAllNamespaces: true, removeNamespaces: null });
111+
112+
expect(output).to.equal('next');
113+
expect(value).to.be.a('object');
114+
expect(value).to.deep.equal(jsonMessage['Envelope']['Body']);
115+
});
116+
117+
it('should return only the SOAP-Body and all Namespaces removed and removeNamespaces also set to only one value', async () => {
118+
var xmlMessage = require('fs').readFileSync('./test/testMessages/airports_soap_response_namespace.xml', 'utf8');
119+
var jsonMessage = JSON.parse(require('fs').readFileSync('./test/testMessages/airports_soap_body_no_namespace_or_envelope.json', 'utf8'));
120+
const { value, output } = await flowNode.xml2json({ xmlData: xmlMessage, selectPath: '$[\"Envelope\"][\"Body\"]', removeAllNamespaces: true, removeNamespaces: ['v1'] });
121+
122+
expect(output).to.equal('next');
123+
expect(value).to.be.a('object');
124+
expect(value).to.deep.equal(jsonMessage['Envelope']['Body']);
125+
});
126+
127+
it('should return only the SOAP-Body and Namespaces removed and RemoveAllNamespaces not set', async () => {
108128
var xmlMessage = require('fs').readFileSync('./test/testMessages/airports_soap_response_namespace.xml', 'utf8');
109129
var jsonMessage = JSON.parse(require('fs').readFileSync('./test/testMessages/airports_soap_body_no_namespace.json', 'utf8'));
110130
const { value, output } = await flowNode.xml2json({ xmlData: xmlMessage, selectPath: '$[\"soapenv:Envelope\"][\"soapenv:Body\"]', removeNamespaces: ['v1', 'v2'] });

0 commit comments

Comments
 (0)