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, idx, idxThir); 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 } else { 116 for (; j < strXml.indexOf('<', idx); j++) { 117 let cXml: string = strXml.charAt(j); 118 switch (cXml) { 119 case '\n': 120 strXml = strXml.substring(0, j) + '\\n' + strXml.substring(j + 1); 121 break; 122 case '\v': 123 strXml = strXml.substring(0, j) + '\\v' + strXml.substring(j + 1); 124 break; 125 case '\t': 126 strXml = strXml.substring(0, j) + '\\t' + strXml.substring(j + 1); 127 break; 128 default: 129 break; 130 } 131 } 132 } 133 return strXml; 134} 135 136function dealLaterReplace(strXml: string, idx: number, idxThir: number): string { 137 let i: number = idx + 1; 138 for (; i < idxThir; i++) { 139 let cXml: string = strXml.charAt(i); 140 switch (cXml) { 141 case '\n': 142 strXml = strXml.substring(0, i) + '\\n' + strXml.substring(i + 1); 143 break; 144 case '\v': 145 strXml = strXml.substring(0, i) + '\\v' + strXml.substring(i + 1); 146 break; 147 case '\t': 148 strXml = strXml.substring(0, i) + '\\t' + strXml.substring(i + 1); 149 break; 150 default: 151 break; 152 } 153 } 154 return strXml; 155} 156 157export default { 158 ConvertXML: ConvertXML 159} 160