diff --git a/package-lock.json b/package-lock.json index 3cccfa6caf..34fb4a49e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -86,6 +86,7 @@ "ssdeep.js": "0.0.3", "stream-browserify": "^3.0.0", "tesseract.js": "3.0.3", + "timers": "^0.1.1", "ua-parser-js": "^1.0.34", "unorm": "^1.6.0", "utf8": "^3.0.0", @@ -12587,6 +12588,11 @@ "dev": true, "license": "MIT" }, + "node_modules/timers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/timers/-/timers-0.1.1.tgz", + "integrity": "sha512-pkJC8uIP/gxDHxNQUBUbjHyl6oZfT+ofn7tbaHW+CFIUjI+Q2MBbHcx1JSBQfhDaTcO9bNg328q0i7Vk5PismQ==" + }, "node_modules/timers-browserify": { "version": "2.0.2", "dev": true, @@ -22393,6 +22399,11 @@ "version": "1.1.0", "dev": true }, + "timers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/timers/-/timers-0.1.1.tgz", + "integrity": "sha512-pkJC8uIP/gxDHxNQUBUbjHyl6oZfT+ofn7tbaHW+CFIUjI+Q2MBbHcx1JSBQfhDaTcO9bNg328q0i7Vk5PismQ==" + }, "timers-browserify": { "version": "2.0.2", "dev": true, diff --git a/package.json b/package.json index 45328dd196..17c6cbae32 100644 --- a/package.json +++ b/package.json @@ -168,6 +168,7 @@ "ssdeep.js": "0.0.3", "stream-browserify": "^3.0.0", "tesseract.js": "3.0.3", + "timers": "^0.1.1", "ua-parser-js": "^1.0.34", "unorm": "^1.6.0", "utf8": "^3.0.0", diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index cf4d91be09..f9f8fcad0a 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -66,6 +66,7 @@ "CSV to JSON", "JSON to CSV", "Avro to JSON", + "XML to JSON", "CBOR Encode", "CBOR Decode" ] diff --git a/src/core/operations/XMLToJSON.mjs b/src/core/operations/XMLToJSON.mjs new file mode 100644 index 0000000000..dcf142c8d7 --- /dev/null +++ b/src/core/operations/XMLToJSON.mjs @@ -0,0 +1,49 @@ +/** + * @author jpledref [jp.ledref@gmail.com] + * @copyright Crown Copyright 2023 + * @license Apache-2.0 + */ + +import xml2js from "xml2js"; +import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; + +/** + * XML to JSON operation + */ +class XMLToJSON extends Operation { + + /** + * XMLToJSON constructor + */ + constructor() { + super(); + + this.name = "XML to JSON"; + this.module = "Default"; + this.description = "Converts XML data to JSON format."; + this.infoURL = "https://wikipedia.org/wiki/XML"; + this.inputType = "string"; + this.outputType = "JSON"; + this.args = [ + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {JSON} + */ + run(input, args) { + let result; + try { + xml2js.parseString(input, {}, (e, r) => result = JSON.stringify(r)); + return JSON.parse(result); + } catch (err) { + throw new OperationError("Unable to parse XML to JSON: " + err.toString()); + } + } + +} + +export default XMLToJSON; diff --git a/tests/operations/tests/XMLToJSON.mjs b/tests/operations/tests/XMLToJSON.mjs new file mode 100644 index 0000000000..4d4c185c19 --- /dev/null +++ b/tests/operations/tests/XMLToJSON.mjs @@ -0,0 +1,24 @@ +/** + * XML to JSON tests. + * + * @author jpledref [jp.ledref@gmail.com] + * @copyright Crown Copyright 2023 + * @license Apache-2.0 + */ +import TestRegister from "../../lib/TestRegister.mjs"; + +const EXPECTED_JSON = { "root": {"shelf": ["over"], "wood": ["do"], "natural": ["sale"]}}; + +TestRegister.addTests([ + { + name: "XML to JSON", + input: "\nover\ndo\nsale\n", + expectedOutput: EXPECTED_JSON, + recipeConfig: [ + { + op: "XML to JSON", + args: [] + }, + ], + } +]);