遇到了一個做soap的API的操作,中途需要說明xml的組裝模式等,
如上圖,組裝產生的mxl代碼葯格式化並展示.由於是在前端做的,所以需要將字符串將xml進行格式化並輸出,找到別人寫的算法稍加更改並整理如下:
//格式化xml代碼 function formateXml(xmlStr){ text = xmlStr; //使用replace去空格 text = '\n' + text.replace(/(<\w+)(\s.*?>)/g,function($0, name, props){ return name + ' ' + props.replace(/\s+(\w+=)/g," $1"); }).replace(/>\s*?</g,">\n<"); //處理注釋 text = text.replace(/\n/g,'\r').replace(/<!--(.+?)-->/g,function($0, text){ var ret = '<!--' + escape(text) + '-->'; return ret; }).replace(/\r/g,'\n'); //調整格式 以壓棧方式遞歸調整縮進 var rgx = /\n(<(([^\?]).+?)(?:\s|\s*?>|\s*?(\/)>)(?:.*?(?:(?:(\/)>)|(?:<(\/)\2>)))?)/mg; var nodeStack = []; var output = text.replace(rgx,function($0,all,name,isBegin,isCloseFull1,isCloseFull2 ,isFull1,isFull2){ var isClosed = (isCloseFull1 == '/') || (isCloseFull2 == '/' ) || (isFull1 == '/') || (isFull2 == '/'); var prefix = ''; if(isBegin == '!'){//!開頭 prefix = setPrefix(nodeStack.length); }else { if(isBegin != '/'){///開頭 prefix = setPrefix(nodeStack.length); if(!isClosed){//非關閉標簽 nodeStack.push(name); } }else{ nodeStack.pop();//彈棧 prefix = setPrefix(nodeStack.length); } } var ret = '\n' + prefix + all; return ret; }); var prefixSpace = -1; var outputText = output.substring(1); //還原注釋內容 outputText = outputText.replace(/\n/g,'\r').replace(/(\s*)<!--(.+?)-->/g,function($0, prefix, text){ if(prefix.charAt(0) == '\r') prefix = prefix.substring(1); text = unescape(text).replace(/\r/g,'\n'); var ret = '\n' + prefix + '<!--' + text.replace(/^\s*/mg, prefix ) + '-->'; return ret; }); outputText= outputText.replace(/\s+$/g,'').replace(/\r/g,'\r\n'); return outputText; } //計算頭函數 用來縮進 function setPrefix(prefixIndex) { var result = ''; var span = ' ';//縮進長度 var output = []; for(var i = 0 ; i < prefixIndex; ++i){ output.push(span); } result = output.join(''); return result; }
以上