きれいに印刷したい、インデントされていない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>'));
これは私には完璧に機能しますが、前の関数を書いている間、もっと良い方法があるに違いないと思いました。だから私の質問は、HTMLページにきれいに印刷するXML文字列を与えられたより良い方法を知っていますか?仕事をすることができるjavascriptフレームワークおよび/またはプラグインは大歓迎です。私の唯一の要件は、これがクライアント側で行われることです。
質問のテキストから、HTML形式の結果ではなく、文字列の結果が期待されるという印象を受けます。
その場合、これを達成する最も簡単な方法は、 アイデンティティ変換 と <xsl:output indent="yes"/>
命令:
<xsl:stylesheet version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"> <xsl:output省略-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.5K未満、非常に高速:5ミリ秒未満50K XMLテキストを処理します。
Efnx clckclcksのjavascript関数のわずかな変更。書式をスペースからタブに変更しましたが、最も重要なことは、テキストを1行のままにすることです。
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;
};
これは、サードパーティのライブラリなしでネイティブ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
'<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">',
' <xsl:strip-space elements="*"/>',
' <xsl:template match="para[content-style][not(text())]">', // change to just text() to strip space in text nodes
' <xsl:value-of select="normalize-space(.)"/>',
' </xsl:template>',
' <xsl:template match="node()|@*">',
' <xsl:copy><xsl:apply-templates select="node()|@*"/></xsl:copy>',
' </xsl:template>',
' <xsl:output indent="yes"/>',
'</xsl:stylesheet>',
].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('<root><node/></root>'));
出力:
<root>
<node/>
</root>
個人的には、この関数で google-code-prettify を使用しています:
prettyPrintOne('<root><node1><root>', '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);
}
私のために働く!
または、別のjs関数でそれを実行したい場合は、ダリンの(多くの)を変更しました:
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関数は、終了タグ「>」と開始タグ「<」の間に未指定の空白があるXMLドキュメントでは機能しません。それらを修正するには、関数の最初の行を置き換えるだけです
var reg = /(>)(<)(\/*)/g;
沿って
var reg = /(>)\s*(<)(\/*)/g;
スタブノード(document.createElement( 'div')-または同等のライブラリを使用)の作成、xml文字列(innerHTML経由)の入力、ルート要素またはスタブ要素の単純な再帰関数の呼び出しについてルートを持っていません。関数は、すべての子ノードに対して自分自身を呼び出します。
次に、マークアップが整形式(innerHTMLを介して追加するときにブラウザーによって自動的に行われる)などを確認しながら、構文ハイライトを行うことができます。コードはそれほど多くなく、おそらく十分に高速です。
JavaScriptソリューションを探している場合は、 http://prettydiff.com/?m=beautify のPretty Diffツールからコードを取得するだけです。
次のようなsパラメーターを使用してツールにファイルを送信することもできます。 http://prettydiff.com/?m=beautify&s=https://stackoverflow.com/
xml-beautify できれいにフォーマットされたxmlを取得できます
var prettyXmlText = new XmlBeautify().beautify(xmlText,
{indent: " ",useSelfClosingElement: true});
indent:空白のようなインデントパターン
useSelfClosingElement:true =>空要素の場合は自己閉鎖要素を使用します。
オリジナル(前)
<?xml version="1.0" encoding="utf-8"?><example version="2.0">
<head><title>Original aTitle</title></head>
<body info="none" ></body>
</example>
美化(後)
<?xml version="1.0" encoding="utf-8"?>
<example version="2.0">
<head>
<title>Original aTitle</title>
</head>
<body info="none" />
</example>
Or just print out the special HTML characters?
Ex: <xmlstuff> 	<node /> </xmlstuff>
	 Horizontal tab
Line feed
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';
XMLSpectrum XMLをフォーマットし、属性のインデントをサポートし、XMLおよび埋め込みXPath式の構文強調表示も行います。
XMLSpectrumは、XSLT 2.0でコーディングされたオープンソースプロジェクトです。したがって、Saxon-HE(推奨)などのプロセッサでこのサーバー側を実行したり、Saxon-CEを使用してクライアント側を実行したりできます。
XMLSpectrumはまだブラウザーでの実行に最適化されていないため、このサーバー側で実行することをお勧めします。
ここに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;
}
上記のメソッドをプリティプリントに使用してから、jquery text()メソッドを使用して任意のdivに追加します。たとえば、divのidはxmldiv
で、次に使用します:
$("#xmldiv").text(formatXml(youXmlString));
var reg = /(>)\s*(<)(\/*)/g;
xml = xml.replace(/\r|\n/g, ''); //deleting already existing whitespaces
xml = xml.replace(reg, '$1\r\n$2$3');
https://www.npmjs.com/package/js-beautify
このライブラリは私のために機能します。 [タブのサポート]、Webおよびノードバージョンのサポート。 JS、HTML、CSSもサポートします。 CDNとしても利用できます。