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 (Object.prototype.hasOwnProperty.call(converted, '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; 68 if (arguments.length === 1) { 69 converted = this.convertxmlclass.convert(strXml); 70 } else { 71 converted = this.convertxmlclass.convert(strXml, options); 72 } 73 if (Object.prototype.hasOwnProperty.call(converted, 'spaces')) { 74 let space: string | number | undefined = converted.spaces; 75 delete converted.spaces; 76 } 77 return converted; 78 } 79} 80 81function dealXml(strXml: string): string { 82 strXml = strXml.replace(/(<!\[CDATA\[[\s\S]*?\]\]>)|(>\s+<)/g, function(match, group) { 83 if (group) { 84 return group; 85 } else { 86 return '><'; 87 } 88 }).trim(); 89 if ((strXml.indexOf('[CDATA')) !== -1) { 90 return dealXmlInner(strXml); 91 } 92 return strXml; 93} 94 95function dealXmlInner(strXml: string): string { 96 strXml = strXml.replace(/\]\]><!\[CDATA/g, ']]> <![CDATA'); 97 return strXml.replace(/<!\[CDATA\[[\s\S]*?\]\]>/g, function (match) { 98 return match.replace(/\\/g, '\\\\').replace(/[\r\n\t\v]/g, function (suit) { 99 switch (suit) { 100 case '\n': return '\\n'; 101 case '\r': return '\\r'; 102 case '\t': return '\\t'; 103 case '\v': return '\\v'; 104 default: return suit; 105 } 106 }); 107 }); 108} 109 110export default { 111 ConvertXML: ConvertXML 112}; 113