当前位置:  开发笔记 > 编程语言 > 正文

用javascript打印XML

如何解决《用javascript打印XML》经验,为你挑选了7个好方法。

我有一个字符串,表示我想要打印的非缩进XML.例如:


应成为:


  

语法突出显示不是必需的.为了解决这个问题,我首先转换XML以添加回车符和空格,然后使用pre标签输出XML.为了添加新行和空格,我编写了以下函数:

function formatXml(xml) {
    var formatted = '';
    var reg = /(>)(<)(\/*)/g;
    xml = xml.replace(reg, '$1\r\n$2$3');
    var pad = 0;
    jQuery.each(xml.split('\r\n'), function(index, node) {
        var indent = 0;
        if (node.match( /.+<\/\w[^>]*>$/ )) {
            indent = 0;
        } else if (node.match( /^<\/\w/ )) {
            if (pad != 0) {
                pad -= 1;
            }
        } else if (node.match( /^<\w[^>]*[^\/]>.*$/ )) {
            indent = 1;
        } else {
            indent = 0;
        }

        var padding = '';
        for (var i = 0; i < pad; i++) {
            padding += '  ';
        }

        formatted += padding + node + '\r\n';
        pad += indent;
    });

    return formatted;
}

然后我调用这个函数:

jQuery('pre.formatted-xml').text(formatXml(''));

这对我来说非常好,但在我写前一个函数时,我认为必须有更好的方法.所以我的问题是,你知道有什么更好的方法给XML字符串在html页面中漂亮打印吗?任何可以完成这项工作的javascript框架和/或插件都是受欢迎的.我唯一的要求就是在客户端完成.



1> Dimitre Nova..:

从问题的文本中我得到的结果是预期字符串结果,而不是HTML格式的结果.

如果是这样,最简单的方法是使用标识转换和指令处理XML文档:


 

    
      
        
      
    

在提供的XML文档上应用此转换时:


大多数XSLT处理器(.NET XslCompiledTransform,Saxon 6.5.4和Saxon 9.0.0.2,AltovaXML)产生想要的结果:


  


@ablmf:什么"不起作用"?什么是"Chrome"?我从来没有听说过这样的XSLT处理器.此外,如果您查看答案的日期,那么Chrome浏览器当时就不存在了.
它看起来像一个很好的解决方案 是否有任何跨浏览器方式在javascript中应用此转换?我没有可依赖的服务器端脚本.
@ablmf:还要注意这个问题(以及我对它的回答)是将漂亮的XML作为字符串(文本)而不是HTML.难怪这样的字符串不会在浏览器中显示.对于精美的HTML输出(ala IE XML显示),请参阅XPath Visualizer中使用的XSLT转换.您可以在http://huttar.net/dimitre/XPV/TopXML-XPV.html下载XPath Visualizer.您可能需要稍微调整一下代码(例如删除用于折叠/展开节点的javascript扩展函数),否则生成的HTML应该显示正常.
是.看看Sarissa:http://dev.abiss.gr/sarissa/,在这里:http://www.xml.com/pub/a/2005/02/23/sarissa.html

2> 小智..:

轻微修改efnx clckclcks的javascript函数.我将格式从空格更改为制表符,但最重要的是我允许文本保留在一行:

var formatXml = this.formatXml = function (xml) {
        var reg = /(>)\s*(<)(\/*)/g; // updated Mar 30, 2015
        var wsexp = / *(.*) +\n/g;
        var contexp = /(<.+>)(.+\n)/g;
        xml = xml.replace(reg, '$1\n$2$3').replace(wsexp, '$1\n').replace(contexp, '$1\n$2');
        var pad = 0;
        var formatted = '';
        var lines = xml.split('\n');
        var indent = 0;
        var lastType = 'other';
        // 4 types of tags - single, closing, opening, other (text, doctype, comment) - 4*4 = 16 transitions 
        var transitions = {
            'single->single': 0,
            'single->closing': -1,
            'single->opening': 0,
            'single->other': 0,
            'closing->single': 0,
            'closing->closing': -1,
            'closing->opening': 0,
            'closing->other': 0,
            'opening->single': 1,
            'opening->closing': 0,
            'opening->opening': 1,
            'opening->other': 1,
            'other->single': 0,
            'other->closing': -1,
            'other->opening': 0,
            'other->other': 0
        };

        for (var i = 0; i < lines.length; i++) {
            var ln = lines[i];

            // Luca Viggiani 2017-07-03: handle optional  declaration
            if (ln.match(/\s*<\?xml/)) {
                formatted += ln + "\n";
                continue;
            }
            // ---

            var single = Boolean(ln.match(/<.+\/>/)); // is this line a single tag? ex. 
var closing = Boolean(ln.match(/<\/.+>/)); // is this a closing tag? ex. var opening = Boolean(ln.match(/<[^!].*>/)); // is this even a tag (that's not ) var type = single ? 'single' : closing ? 'closing' : opening ? 'opening' : 'other'; var fromTo = lastType + '->' + type; lastType = type; var padding = ''; indent += transitions[fromTo]; for (var j = 0; j < indent; j++) { padding += '\t'; } if (fromTo == 'opening->closing') formatted = formatted.substr(0, formatted.length - 1) + ln + '\n'; // substr removes line break (\n) from prev loop else formatted += padding + ln + '\n'; } return formatted; };



3> Artur Klesu..:

这可以使用原生的javascript工具完成,没有第三方库,扩展了@Dimitre Novatchev的答案:

var prettifyXml = function(sourceXml)
{
    var xmlDoc = new DOMParser().parseFromString(sourceXml, 'application/xml');
    var xsltDoc = new DOMParser().parseFromString([
        // describes how we want to modify the XML - indent everything
        '',
        '  ',
        '  ', // change to just text() to strip space in text nodes
        '    ',
        '  ',
        '  ',
        '    ',
        '  ',
        '  ',
        '',
    ].join('\n'), 'application/xml');

    var xsltProcessor = new XSLTProcessor();    
    xsltProcessor.importStylesheet(xsltDoc);
    var resultDoc = xsltProcessor.transformToDocument(xmlDoc);
    var resultXml = new XMLSerializer().serializeToString(resultDoc);
    return resultXml;
};

console.log(prettifyXml(''));

输出:


  

的jsfiddle


我收到一个错误,但是该错误没有消息。使用Firefox,它也发生在小提琴中。

4> Touv..:

Personnaly,我使​​用google-code-prettify这个函数:

prettyPrintOne('', 'xml')


Oups,你需要缩进XML和google-code-prettify只对代码着色.抱歉.
这与http://code.google.com/p/vkbeautify/结合使用了一个很好的组合缩进.

5> arcturus..:

当我有类似的要求时发现这个线程但我简化了OP的代码如下:

function formatXml(xml, tab) { // tab = optional indent value, default is tab (\t)
    var formatted = '', indent= '';
    tab = tab || '\t';
    xml.split(/>\s*\r\n';
        if (node.match( /^]*[^\/]$/ )) indent += tab;              // increase indent
    });
    return formatted.substring(1, formatted.length-3);
}

适合我!



6> schellsan..:

或者如果你只是喜欢另一个js函数来做,我已经修改了Darin(很多):

var formatXml = this.formatXml = function (xml) {
    var reg = /(>)(<)(\/*)/g;
    var wsexp = / *(.*) +\n/g;
    var contexp = /(<.+>)(.+\n)/g;
    xml = xml.replace(reg, '$1\n$2$3').replace(wsexp, '$1\n').replace(contexp, '$1\n$2');
    var pad = 0;
    var formatted = '';
    var lines = xml.split('\n');
    var indent = 0;
    var lastType = 'other';
    // 4 types of tags - single, closing, opening, other (text, doctype, comment) - 4*4 = 16 transitions 
    var transitions = {
        'single->single'    : 0,
        'single->closing'   : -1,
        'single->opening'   : 0,
        'single->other'     : 0,
        'closing->single'   : 0,
        'closing->closing'  : -1,
        'closing->opening'  : 0,
        'closing->other'    : 0,
        'opening->single'   : 1,
        'opening->closing'  : 0, 
        'opening->opening'  : 1,
        'opening->other'    : 1,
        'other->single'     : 0,
        'other->closing'    : -1,
        'other->opening'    : 0,
        'other->other'      : 0
    };

    for (var i=0; i < lines.length; i++) {
        var ln = lines[i];
        var single = Boolean(ln.match(/<.+\/>/)); // is this line a single tag? ex. 
var closing = Boolean(ln.match(/<\/.+>/)); // is this a closing tag? ex. var opening = Boolean(ln.match(/<[^!].*>/)); // is this even a tag (that's not ) var type = single ? 'single' : closing ? 'closing' : opening ? 'opening' : 'other'; var fromTo = lastType + '->' + type; lastType = type; var padding = ''; indent += transitions[fromTo]; for (var j = 0; j < indent; j++) { padding += ' '; } formatted += padding + ln + '\n'; } return formatted; };



7> Chuan Ma..:

此处给出的所有javascript函数都不适用于在结束标记">"和开始标记"<"之间具有未指定空格的xml文档.要修复它们,您只需要替换函数中的第一行

var reg = /(>)(<)(\/*)/g;

通过

var reg = /(>)\s*(<)(\/*)/g;

推荐阅读
黄晓敏3023
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有