diff --git a/app/core/client.js b/app/core/client.js index dfbe3fd..7c5ac88 100644 --- a/app/core/client.js +++ b/app/core/client.js @@ -7,9 +7,10 @@ //Подключение библиотек //--------------------- -import { XMLParser, XMLBuilder } from "fast-xml-parser"; //Конвертация XML в JSON и JSON в XML +import { XMLBuilder } from "fast-xml-parser"; //Конвертация XML в JSON и JSON в XML import dayjs from "dayjs"; //Работа с датами import config from "../../app.config"; //Настройки приложения +import { xml2JSON } from "./utils"; //Вспомогательные функции //--------- //Константы @@ -34,26 +35,6 @@ const ERR_UNEXPECTED = "Неожиданный ответ сервера"; //Н const ERR_NETWORK = "Ошибка соединения с сервером"; //Ошибка сети const ERR_UNAUTH = "Сеанс завершен. Пройдите аутентификацию повторно."; //Ошибка аутентификации -//Типовые пути конвертации в массив (при переводе XML -> JSON) -const XML_ALWAYS_ARRAY_PATHS = [ - "XRESPOND.XPAYLOAD.XOUT_ARGUMENTS", - "XRESPOND.XPAYLOAD.XROWS", - "XRESPOND.XPAYLOAD.XCOLUMNS_DEF", - "XRESPOND.XPAYLOAD.XCOLUMNS_DEF.values", - "XRESPOND.XPAYLOAD.XGROUPS", - "XRESPOND.XPAYLOAD.XGANTT_DEF.taskAttributes", - "XRESPOND.XPAYLOAD.XGANTT_DEF.taskColors", - "XRESPOND.XPAYLOAD.XGANTT_TASKS", - "XRESPOND.XPAYLOAD.XGANTT_TASKS.dependencies", - "XRESPOND.XPAYLOAD.XCHART.labels", - "XRESPOND.XPAYLOAD.XCHART.datasets", - "XRESPOND.XPAYLOAD.XCHART.datasets.data", - "XRESPOND.XPAYLOAD.XCHART.datasets.items" -]; - -//Типовой постфикс тега для массива (при переводе XML -> JSON) -const XML_ALWAYS_ARRAY_POSTFIX = "__SYSTEM__ARRAY__"; - //----------- //Тело модуля //----------- @@ -70,26 +51,8 @@ const getServerDataType = value => { const makeRespErr = ({ message }) => ({ SSTATUS: RESP_STATUS_ERR, SMESSAGE: message }); //Разбор XML -const parseXML = (xmlDoc, isArray, transformTagName, tagValueProcessor, attributeValueProcessor) => { - return new Promise((resolve, reject) => { - try { - let opts = { - ignoreDeclaration: true, - ignoreAttributes: false, - parseAttributeValue: true, - attributeNamePrefix: "" - }; - if (isArray) opts.isArray = isArray; - if (transformTagName) opts.transformTagName = transformTagName; - if (tagValueProcessor) opts.tagValueProcessor = tagValueProcessor; - if (attributeValueProcessor) opts.attributeValueProcessor = attributeValueProcessor; - const parser = new XMLParser(opts); - resolve(parser.parse(xmlDoc)); - } catch (e) { - reject(e); - } - }); -}; +const parseXML = async (xmlDoc, isArray, transformTagName, tagValueProcessor, attributeValueProcessor) => + await xml2JSON({ xmlDoc, isArray, transformTagName, tagValueProcessor, attributeValueProcessor, useDefaultPatterns: true }); //Формирование XML const buildXML = jsonObj => { @@ -160,7 +123,7 @@ const executeAction = async ({ serverURL, action, payload = {}, isArray, transfo throw new Error(ERR_UNEXPECTED); //Всё хорошо - возвращаем (без корня, он не нужен) console.log("SERVER RESPONSE JSON:"); - console.log(responseJSON.XRESPOND); + console.log(JSON.parse(JSON.stringify(responseJSON.XRESPOND))); return responseJSON.XRESPOND; }; @@ -192,8 +155,7 @@ const executeStored = async ({ serverURL: `${config.SYSTEM.SERVER}${!config.SYSTEM.SERVER.endsWith("/") ? "/" : ""}Process`, action: SRV_FN_CODE_EXEC_STORED, payload: { SSTORED: stored, XARGUMENTS: serverArgs, SRESP_ARG: respArg }, - isArray: (name, jPath) => - XML_ALWAYS_ARRAY_PATHS.indexOf(jPath) !== -1 || jPath.endsWith(XML_ALWAYS_ARRAY_POSTFIX) || (isArray ? isArray(name, jPath) : false), + isArray, tagValueProcessor, attributeValueProcessor }); diff --git a/app/core/utils.js b/app/core/utils.js index 69492d1..32ebd4c 100644 --- a/app/core/utils.js +++ b/app/core/utils.js @@ -30,6 +30,42 @@ const DISPLAY_SIZE = { [DISPLAY_SIZE_CODE.LG]: { WIDTH_FROM: 1200, WIDTH_TO: 1000000 } //Large - большой экран >= 1200px }; +//Типовые пути конвертации в массив (при переводе XML -> JSON) +const XML_ALWAYS_ARRAY_PATHS = [ + "XRESPOND.XPAYLOAD.XOUT_ARGUMENTS", + "XRESPOND.XPAYLOAD.XROWS", + "XRESPOND.XPAYLOAD.XCOLUMNS_DEF", + "XRESPOND.XPAYLOAD.XCOLUMNS_DEF.values", + "XRESPOND.XPAYLOAD.XGROUPS", + "XRESPOND.XPAYLOAD.XGANTT_DEF.taskAttributes", + "XRESPOND.XPAYLOAD.XGANTT_DEF.taskColors", + "XRESPOND.XPAYLOAD.XGANTT_TASKS", + "XRESPOND.XPAYLOAD.XGANTT_TASKS.dependencies", + "XRESPOND.XPAYLOAD.XCHART.labels", + "XRESPOND.XPAYLOAD.XCHART.datasets", + "XRESPOND.XPAYLOAD.XCHART.datasets.data", + "XRESPOND.XPAYLOAD.XCHART.datasets.items" +]; + +//Типовые шаблоны конвертации в массив (при переводе XML -> JSON) +const XML_ALWAYS_ARRAY_PATH_PATTERNS = [ + /(.*)XROWS$/, + /(.*)XCOLUMNS_DEF$/, + /(.*)XCOLUMNS_DEF.values$/, + /(.*)XGROUPS$/, + /(.*)XGANTT_DEF.taskAttributes$/, + /(.*)XGANTT_DEF.taskColors$/, + /(.*)XGANTT_TASKS$/, + /(.*)XGANTT_TASKS.dependencies$/, + /(.*)XCHART.labels$/, + /(.*)XCHART.datasets$/, + /(.*)XCHART.datasets.data$/, + /(.*)XCHART.datasets.items$/ +]; + +//Типовой постфикс тега для массива (при переводе XML -> JSON) +const XML_ALWAYS_ARRAY_POSTFIX = "__SYSTEM__ARRAY__"; + //----------- //Тело модуля //----------- @@ -57,7 +93,7 @@ const object2Base64XML = (obj, builderOptions) => { }; //Конвертация XML в JSON -const xml2JSON = ({ xmlDoc, attributeValueProcessor, isArray }) => { +const xml2JSON = ({ xmlDoc, isArray, transformTagName, tagValueProcessor, attributeValueProcessor, useDefaultPatterns = true }) => { return new Promise((resolve, reject) => { try { let opts = { @@ -66,8 +102,16 @@ const xml2JSON = ({ xmlDoc, attributeValueProcessor, isArray }) => { parseAttributeValue: true, attributeNamePrefix: "" }; + if (useDefaultPatterns) + opts.isArray = (name, jPath, isLeafNode, isAttribute) => + XML_ALWAYS_ARRAY_PATHS.indexOf(jPath) !== -1 || + XML_ALWAYS_ARRAY_PATH_PATTERNS.some(pattern => pattern.test(jPath)) || + jPath.endsWith(XML_ALWAYS_ARRAY_POSTFIX) || + (isArray ? isArray(name, jPath, isLeafNode, isAttribute) : undefined); + else if (isArray) opts.isArray = isArray; + if (transformTagName) opts.transformTagName = transformTagName; + if (tagValueProcessor) opts.tagValueProcessor = tagValueProcessor; if (attributeValueProcessor) opts.attributeValueProcessor = attributeValueProcessor; - if (isArray) opts.isArray = isArray; const parser = new XMLParser(opts); resolve(parser.parse(xmlDoc)); } catch (e) {