xslt методы - Довольно печатать XML с помощью javascript




document document.html (16)

Если вы ищете решение для JavaScript, просто возьмите код из инструмента Pretty Diff по адресу http://prettydiff.com/?m=beautify

Вы также можете отправлять файлы в инструмент с помощью параметра s, например: http://prettydiff.com/?m=beautify&s=https://stackoverflow.com/

У меня есть строка, которая представляет собой XML без выраженного абзаца, который я бы хотел напечатать. Например:

<root><node/></root>

должны стать:

<root>
  <node/>
</root>

Выделение синтаксиса не является обязательным требованием. Чтобы решить проблему, я сначала преобразую 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('<root><node1/></root>'));

Это работает отлично для меня, но когда я писал предыдущую функцию, я думал, что должен быть лучший способ. Так что мой вопрос: знаете ли вы, какой способ лучше использовать XML-строку, чтобы напечатать ее на html-странице? Любые фреймворки javascript и / или плагины, которые могли бы выполнять эту работу, приветствуются. Мое единственное требование - это сделать на стороне клиента.


https://www.npmjs.com/package/js-beautify

Эта библиотека работает для меня. Поддерживает вкладку, поддерживает веб-версию и версию узла. Также поддерживает JS, HTML, CSS. Также доступен как CDN.


Из текста вопроса создается впечатление, что ожидается результат строки , в отличие от результата в формате HTML.

Если это так, самый простой способ добиться этого - обработать документ XML с преобразованием идентичности и с помощью команды <xsl:output indent="yes"/> :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:template match="node()|@*">
      <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

При применении этого преобразования на предоставленном XML-документе:

<root><node/></root>

большинство XSLT-процессоров (.NET XslCompiledTransform, Saxon 6.5.4 и Saxon 9.0.0.2, AltovaXML) создают желаемый результат:

<root>
  <node />
</root>

рассмотрим использование vkBeautify плагина

http://www.eslinstructor.net/vkbeautify/

это написано на простом javascript, очень маленьком: менее 1,5 К, если оно было уменьшено, очень быстро: менее 5 мс. для обработки 50K XML-текста.



Нашел этот поток, когда у меня было подобное требование, но я упростил код OP следующим образом:

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

работает на меня!


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';

как создать узел-заглушку (document.createElement ('div') - или используя эквивалент вашей библиотеки), заполняя его строкой xml (через innerHTML) и вызывая простую рекурсивную функцию для корневого элемента / или элемента-заглушки в том случае, если вы не имеют корня. Функция будет вызывать себя для всех дочерних узлов.

Вы могли бы затем синтаксически выделить на этом пути, убедитесь, что разметка хорошо сформирована (выполняется автоматически браузером при добавлении через innerHTML) и т. Д. Это будет не так много кода и, вероятно, достаточно быстро.


Все функции javascript, приведенные здесь, не будут работать для XML-документа с неопределенными пробелами между конечным тегом '>' и стартовым тегом '<'. Чтобы исправить их, вам просто нужно заменить первую строку в функциях

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

от

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

XMLSpectrum форматы XML, поддерживает отступ атрибутов, а также выделяет синтаксис для XML и любых встроенных выражений XPath:

XMLSpectrum - проект с открытым исходным кодом, закодированный в XSLT 2.0, поэтому вы можете запустить эту серверную часть с процессором, например Saxon-HE (рекомендуется) или на стороне клиента, используя Saxon-CE.

XMLSpectrum еще не оптимизирован для работы в браузере - отсюда и рекомендация запуска этой серверной части.


var reg = /(>)\s*(<)(\/*)/g;
xml = xml.replace(/\r|\n/g, ''); //deleting already existing whitespaces
xml = xml.replace(reg, '$1\r\n$2$3');

вот еще одна функция для форматирования xml

function formatXml(xml){
    var out = "";
    var tab = "    ";
    var indent = 0;
    var inClosingTag=false;
    var dent=function(no){
        out += "\n";
        for(var i=0; i < no; i++)
            out+=tab;
    }


    for (var i=0; i < xml.length; i++) {
        var c = xml.charAt(i);
        if(c=='<'){
            // handle </
            if(xml.charAt(i+1) == '/'){
                inClosingTag = true;
                dent(--indent);
            }
            out+=c;
        }else if(c=='>'){
            out+=c;
            // handle />
            if(xml.charAt(i-1) == '/'){
                out+="\n";
                //dent(--indent)
            }else{
              if(!inClosingTag)
                dent(++indent);
              else{
                out+="\n";
                inClosingTag=false;
              }
            }
        }else{
          out+=c;
        }
    }
    return out;
}

Или, если вам просто нужна другая функция js, я изменил Darin's (много):

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. <br />
        var closing = Boolean(ln.match(/<\/.+>/)); // is this a closing tag? ex. </a>
        var opening = Boolean(ln.match(/<[^!].*>/)); // is this even a tag (that's not <!something>)
        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;
};

Небольшая модификация функции javascript efnx clckclcks. Я изменил форматирование с пробелов на вкладку, но самое главное, я разрешил текст оставаться на одной строке:

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 <?xml ... ?> declaration
            if (ln.match(/\s*<\?xml/)) {
                formatted += ln + "\n";
                continue;
            }
            // ---

            var single = Boolean(ln.match(/<.+\/>/)); // is this line a single tag? ex. <br />
            var closing = Boolean(ln.match(/<\/.+>/)); // is this a closing tag? ex. </a>
            var opening = Boolean(ln.match(/<[^!].*>/)); // is this even a tag (that's not <!something>)
            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;
    };

Используйте метод выше для красивой печати, а затем добавьте это в любой div с помощью метода jquery text () . например, id div - xmldiv тогда используйте:

$("#xmldiv").text(formatXml(youXmlString));


Верхние 2 ответа на оба упомянутых == означает равенство и === означает идентификацию. К сожалению, это утверждение неверно.

Если оба операнда из == являются объектами, то их сравнивают, чтобы увидеть, являются ли они одним и тем же объектом. Если оба операнда указывают на один и тот же объект, то оператор равенства возвращает true. В противном случае они не равны.

var a = [1, 2, 3];  
var b = [1, 2, 3];  
console.log(a == b)  // false  
console.log(a === b) // false  

В приведенном выше коде оба == и === получают false, потому что a и b - не одни и те же объекты.

Иными словами, если оба операнда == являются объектами, == ведет себя так же, как ===, что также означает идентификацию. Существенным отличием этих двух операторов является преобразование типов. == имеет преобразование, прежде чем он проверяет равенство, но === нет.







javascript xml xslt pretty-print