VUE实现XML高亮和格式化

  1. 首先在公用方法中写入下面的方法,我这里是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('&nbsp;&nbsp;&nbsp;&nbsp;')
        }
        t = t.join('')
        list.push(t + '&lt;<span class="code-key">' + element.nodeName + '</span>&gt;<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 + '&nbsp;&nbsp;&nbsp;&nbsp;&lt;<span class="code-key">' + nodeName +
              '</span>&gt;' + value_txt + '&lt;/<span class="code-key">' + nodeName + '</span>&gt;<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 + '&nbsp;&nbsp;&nbsp;&nbsp;&lt;<span class="code-key">' + nodeName +
              '</span>&gt;' + value_txt + '&lt;/<span class="code-key">' + nodeName + '</span>&gt;<br/>'
            list.push(item)
          } else {
            flag++
            build_xml(++index, list, element.childNodes[i])
            flag--
          }
        }
        list.push(t + '&lt;/<span class="code-key">' + element.nodeName + '</span>&gt;<BR/>')
      }
    
      const list = []
      build_xml(0, list, xml_doc.documentElement)
    
      return list.join('')
    }
  2. 在需要进行XML高亮文件中导入  import { parse_xml } from '@/utils'
  3. 给对应的参数赋值 this.formatData = parse_xml(xml)
  4. 最后在template中写入 <div v-html="formatData" />
  5. 样式中加入下面的代码
      <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>
  6. 最后的效果如下

           

 

还有一种可以识别 <?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);
    }

 两种都试过,亲测可用!

posted @ 2021-05-10 17:50  ZJTL  阅读(1025)  评论(0编辑  收藏  举报