예쁜 인쇄하려는 들여 쓰기되지 않은 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 페이지에서 예쁘게 인쇄하는 더 좋은 방법을 알고 있습니까? 작업을 수행 할 수있는 모든 자바 스크립트 프레임 워크 및 / 또는 플러그인을 환영합니다. 내 유일한 요구 사항은 클라이언트 측에서 수행해야합니다.
답변
질문의 텍스트 에서 HTML 형식의 결과와 달리 문자열 결과가 예상된다는 인상을 얻습니다 .
그렇다면 , 가장 간단한 방법은 ID 변환 과 <xsl:output indent="yes"/>
지시 사항으로 XML 문서를 처리하는 것입니다 .
<xsl : stylesheet version = "1.0" xmlns : xsl = "http://www.w3.org/1999/XSL/Transform"> <xsl : 출력 omit-xml-declaration = "yes"indent = "yes"/> <xsl : template match = "node () | @ *"> <xsl : 복사> <xsl : apply-templates select = "node () | @ *"/> </ xsl : copy> </ xsl : template> </ xsl : stylesheet>
제공된 XML 문서에이 변환을 적용 할 때 :
<root> <노드 /> </ root>
대부분의 XSLT 프로세서 (.NET XslCompiledTransform, Saxon 6.5.4 및 Saxon 9.0.0.2, AltovaXML)는 원하는 결과를 생성합니다.
<루트> <노드 /> </ root>
답변
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;
};
답변
이것은 타사 라이브러리없이 기본 자바 스크립트 도구를 사용하여 수행 할 수 있으며 @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>
@ jat255에서 지적했듯이 firefox에서는 예쁜 인쇄를 <xsl:output indent="yes"/>
지원하지 않습니다. 크롬, 오페라 및 아마도 나머지 웹킷 기반 브라우저에서만 작동하는 것 같습니다.
답변
개인적으로, 나는 이 기능으로 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 함수를 원한다면 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. <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;
};
답변
여기에 주어진 모든 자바 스크립트 함수는 종료 태그 ‘>’와 시작 태그 ‘<‘사이에 공백이 지정되지 않은 xml 문서에서 작동하지 않습니다. 그것들을 고치려면 함수의 첫 번째 줄만 바꾸면됩니다.
var reg = /(>)(<)(\/*)/g;
으로
var reg = /(>)\s*(<)(\/*)/g;