• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16interface ReceiveObject {
17  obj: Object;
18  spaces?: string | number;
19}
20
21interface NativeConvertXml {
22  new(): NativeConvertXml;
23  convert(strXml: string, options?: Object): ReceiveObject;
24  convertToJSObject(strXml: string, options?: Object): ReceiveObject;
25}
26interface ConvertXML {
27  ConvertXml: NativeConvertXml;
28}
29declare function requireInternal(s: string): ConvertXML;
30const convertXml = requireInternal('convertxml');
31
32const LESS_SIGN_INDEX = 3;
33const TypeErrorCode = 401;
34class BusinessError extends Error {
35  code: number;
36  constructor(msg: string) {
37    super(msg)
38    this.name = 'BusinessError';
39    this.code = TypeErrorCode;
40  }
41}
42
43class ConvertXML {
44  convertxmlclass: NativeConvertXml;
45  constructor() {
46    this.convertxmlclass = new convertXml.ConvertXml();
47  }
48  convert(strXml: string, options?: Object): ReceiveObject {
49    strXml = dealXml(strXml);
50    let converted: ReceiveObject = this.convertxmlclass.convert(strXml, options);
51    let strEnd: string = '';
52    if (converted.hasOwnProperty('spaces')) {
53      let space: string | number | undefined = converted.spaces;
54      delete converted.spaces;
55    }
56    return converted;
57  }
58
59  convertToJSObject(strXml: string, options?: Object): ReceiveObject {
60    if (typeof strXml !== 'string') {
61      throw new BusinessError(`Parameter error.The type of ${strXml} must be string`);
62    }
63    if (options && !(typeof options === 'undefined' || options === null) && typeof options !== 'object') {
64      throw new BusinessError(`Parameter error.The type of ${options} must be object`);
65    }
66    strXml = dealXml(strXml);
67    let converted: ReceiveObject = this.convertxmlclass.convert(strXml, options);
68    let strEnd: string = '';
69    if (converted.hasOwnProperty('spaces')) {
70      let space: string | number | undefined = converted.spaces;
71      delete converted.spaces;
72    }
73    return converted;
74  }
75}
76
77function dealXml(strXml: string): string {
78  let idx: number = 0;
79  let idxSec: number = 0;
80  let idxThir: number = 0;
81  let idxCData: number = 0;
82  let idxCDataSec: number = 0;
83  while ((idx = strXml.indexOf(']]><![CDATA')) !== -1) {
84    strXml = strXml.substring(0, idx + LESS_SIGN_INDEX) + ' ' + strXml.substring(idx + LESS_SIGN_INDEX);
85  }
86  while ((idx = strXml.indexOf('>', idxSec)) !== -1) {
87    idxThir = strXml.indexOf('<', idx);
88    strXml = dealPriorReplace(strXml, idx, idxThir);
89    idxSec = strXml.indexOf('<', idx);
90    if (idxSec !== -1) {
91      idxCData = strXml.indexOf('<![CDATA', idxCDataSec);
92      if (idxSec === idxCData) {
93        idxSec = strXml.indexOf(']]>', idxCData);
94        strXml = dealLaterReplace(strXml, idxCData, idxSec);
95        idxCDataSec = idxSec;
96      }
97    } else {
98      break;
99    }
100  }
101  return strXml;
102}
103
104function dealPriorReplace(strXml: string, idx: number, idxThir: number): string {
105  let i: number = idx + 1;
106  for (; i < idxThir; i++) {
107    let cXml: string = strXml.charAt(i);
108    if (cXml !== '\n' && cXml !== '\v' && cXml !== '\t' && cXml !== ' ') {
109      break;
110    }
111  }
112  let j: number = idx + 1;
113  if (i === idxThir) {
114    strXml = strXml.substring(0, j) + strXml.substring(idxThir);
115  }
116  if (j < strXml.indexOf('<', idx)) {
117    let temp: string = strXml.substring(j, strXml.indexOf('<', idx));
118    if (temp.indexOf('\n') !== -1 || temp.indexOf('\v') !== -1 || temp.indexOf('\t') !== -1) {
119      let pattern: RegExp = /[\n\v\t]/g;
120      let result: string = temp.replace(pattern, function (match) {
121        switch (match) {
122          case '\n':
123            return '\\n';
124          case '\v':
125            return '\\v';
126          case '\t':
127            return '\\t';
128          default:
129            return match;
130        }
131      });
132      strXml = strXml.replace(temp, result);
133    }
134  }
135  return strXml;
136}
137
138function dealLaterReplace(strXml: string, idx: number, idxThir: number): string {
139  let i: number = idx + 1;
140  let res = strXml.substring(i, idxThir);
141  if (res.indexOf('\n') !== -1 || res.indexOf('\v') !== -1 || res.indexOf('\t') !== -1 || res.indexOf('\r') !== -1) {
142    let pattern: RegExp = /[\n\v\t\r]/g;
143    let result: string = res.replace(pattern, function (match) {
144      switch (match) {
145        case '\n':
146          return '\\n';
147        case '\v':
148          return '\\v';
149        case '\t':
150          return '\\t';
151        case '\r':
152          return '\\r';
153        default:
154          return match;
155      }
156    });
157    strXml = strXml.replace(res, result);
158  }
159  return strXml;
160}
161
162export default {
163  ConvertXML: ConvertXML
164};
165