VUE实现XML高亮和格式化
- 首先在公用方法中写入下面的方法,我这里是src/utils/index.js
export function parse_xml(content) { let xml_doc = null try { xml_doc = (new DOMParser()).parseFromString(content.replace(/[\n\r\s]/g, ''), 'text/xml') } catch (e) { return false } let flag = 0 function build_xml(index, list, element) { let t = [] for (let i = 0; i < flag; i++) { t.push(' ') } t = t.join('') list.push(t + '<<span class="code-key">' + element.nodeName + '</span>><br/>') for (let i = 0; i < element.childNodes.length; i++) { const nodeName = element.childNodes[i].nodeName if (element.childNodes[i].childNodes.length === 0) { const value_txt = '' const item = t + ' <<span class="code-key">' + nodeName + '</span>>' + value_txt + '</<span class="code-key">' + nodeName + '</span>><br/>' list.push(item) } else if ((element.childNodes[i].childNodes.length === 1 && element.childNodes[i].childNodes[0].nodeValue != null)) { const value = element.childNodes[i].childNodes[0].nodeValue const value_color = !isNaN(Number(value)) ? 'code-number' : 'code-string' const value_txt = '<span class="' + value_color + '">' + value + '</span>' const item = t + ' <<span class="code-key">' + nodeName + '</span>>' + value_txt + '</<span class="code-key">' + nodeName + '</span>><br/>' list.push(item) } else { flag++ build_xml(++index, list, element.childNodes[i]) flag-- } } list.push(t + '</<span class="code-key">' + element.nodeName + '</span>><BR/>') } const list = [] build_xml(0, list, xml_doc.documentElement) return list.join('') }
- 在需要进行XML高亮文件中导入 import { parse_xml } from '@/utils'
- 给对应的参数赋值
this.formatData = parse_xml(xml)
- 最后在template中写入
<div v-html="formatData" />
- 样式中加入下面的代码
<style> .code-string{color:#993300;} .code-number{color:#cc00cc;} .code-boolean{color:#000033;} .code-null{color:magenta;} .code-key{color:#003377;font-weight:bold;} </style>
- 最后的效果如下
还有一种可以识别 <?xml version="1.0" encoding="UTF-8"?>,格式如图:
点击button按钮,弹出弹框,弹框里面的内容,是格式化的xml字符串代码;template里内容如下
<button @click="ac">格式化</button> <el-dialog title="格式化" :visible.sync="sss"> <xmp><div v-text="result"></div></xmp> </el-dialog>
在<script>里面做具体事情
showXml(str){ function getPrefix(prefixIndex){ var span = ' '; var output = []; for(var i = 0 ; i < prefixIndex; ++i){ output.push(span); } return output.join(''); } var text = str //去掉多余的空格 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 = ''; // debugger if(isBegin == '!'){ prefix = getPrefix(nodeStack.length); }else{ if(isBegin != '/'){ prefix = getPrefix(nodeStack.length); if(!isClosed){ nodeStack.push(name); } }else{ nodeStack.pop(); prefix = getPrefix(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; }); //alert(outputText); outputText = outputText.replace(/\s+$/g,'').replace(/\r/g,'\r\n'); return outputText },
最后点击事件调用,代码如下
ac(){ this.sss=true; //此处xmls应该是后台给的xml字符串,这里是为了演示,直接给了固定的 var xmls='<?xml version="1.0" encoding="UTF-8"?><note> <to>love</to><from>ss</from> <heading>调用成功</heading> <body>你好</body> </note>'; this.result= this.showXml(xmls); }
两种都试过,亲测可用!