What's the best way to pretty-print xml in JavaScript? I obtain xml content through ajax call and before displaying this request in textarea i want to format it so it looks nice to the eye :)
-
5Making XML look nice to the eye would be a magic trick! – Josh Stodola Jul 27 '09 at 23:04
-
1In my opinion the canonical SO thread regarding this problem is [pretty printing xml with javascript](https://stackoverflow.com/questions/376373/pretty-printing-xml-with-javascript) – Martin Jul 27 '21 at 11:06
6 Answers
This does not take care of any indenting, but helps to encode the XML for use within <pre>
or <textarea>
tags:
/* hack to encode HTML entities */
var d = document.createElement('div');
var t = document.createTextNode(myXml);
d.appendChild(t);
document.write('<pre>' + d.innerHTML + '</pre>');
And if, instead of a <textarea>
, you'd want highlighting and the nodes to be collapsable/expandable, then see Displaying XML in Chrome Browser on Super User.
take a look at the vkBeautify.js plugin
http://www.eslinstructor.net/vkbeautify/
it is exactly what you need. it's written in plain javascript, less then 1.5K minified and very fast: takes less then 5 msec. to process 50K XML text.

- 1,461
- 15
- 11
-
1
-
1it is on npm: https://github.com/vkiryukhin/pretty-data; see documentation on http://www.eslinstructor.net/pretty-data/ – vadimk Dec 09 '16 at 18:43
-
-
Here is a small self contained prettifier that works for most cases does nice indenting for long lines and colorizes the output if needed.
function formatXml(xml,colorize,indent) {
function esc(s){return s.replace(/[-\/&<> ]/g,function(c){ // Escape special chars
return c==' '?' ':'&#'+c.charCodeAt(0)+';';});}
var sm='<div class="xmt">',se='<div class="xel">',sd='<div class="xdt">',
sa='<div class="xat">',tb='<div class="xtb">',tc='<div class="xtc">',
ind=indent||' ',sz='</div>',tz='</div>',re='',is='',ib,ob,at,i;
if (!colorize) sm=se=sd=sa=sz='';
xml.match(/(?<=<).*(?=>)|$/s)[0].split(/>\s*</).forEach(function(nd){
ob=('<'+nd+'>').match(/^(<[!?\/]?)(.*?)([?\/]?>)$/s); // Split outer brackets
ib=ob[2].match(/^(.*?)>(.*)<\/(.*)$/s)||['',ob[2],'']; // Split inner brackets
at=ib[1].match(/^--.*--$|=|('|").*?\1|[^\t\n\f \/>"'=]+/g)||['']; // Split attributes
if (ob[1]=='</') is=is.substring(ind.length); // Decrease indent
re+=tb+tc+esc(is)+tz+tc+sm+esc(ob[1])+sz+se+esc(at[0])+sz;
for (i=1;i<at.length;i++) re+=(at[i]=="="?sm+"="+sz+sd+esc(at[++i]):sa+' '+at[i])+sz;
re+=ib[2]?sm+esc('>')+sz+sd+esc(ib[2])+sz+sm+esc('</')+sz+se+ib[3]+sz:'';
re+=sm+esc(ob[3])+sz+tz+tz;
if (ob[1]+ob[3]+ib[2]=='<>') is+=ind; // Increase indent
});
return re;
}
for demo see https://jsfiddle.net/dkb0La16/

- 79
- 3
-
Nice. Why are you using id= instead of class=? This code produces multiple elements with the same id. – Trade-Ideas Philip Sep 15 '21 at 14:45
-
1Thanks for the feedback. Totally messed up the code/link during initial post. Fixed. – HuepfelGnuepfel Sep 16 '21 at 06:14
-
I also added the "s" flag. Some of my XML files include linefeeds. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/dotAll – Trade-Ideas Philip Sep 21 '21 at 19:45
-
-
I added an "s" to the end of all three match() regular repressions. (Not the split() or the replace().) It might have taken less, I didn't try all the combinations. This is easy enough to test. Add a newline after every ">" in your file. – Trade-Ideas Philip Sep 22 '21 at 15:48
-
Understood and found a another bug with leading/trailing spaces. Should work now. – HuepfelGnuepfel Sep 24 '21 at 17:07
I agree with Arjan on utilizing the <pre>
tags. I was trying to decipher 'ugly' xml code in my html output before I tried this out about 2 days ago. Makes life much easier and keeps you sane.

- 3,948
- 8
- 35
- 47
-
Well, I'm not sure we couldn't have lived *without* the answer even if it were a comment, but well... Deleting it now may also purge the upvote, so wait until you've got at least 60 reputation then. :-) – Arjan Jul 29 '09 at 08:11
-
Now that a few years have passed, I guess deletion of this is due ;-) (Given its age, you'll keep the reputation, if I understand correctly.) – Arjan Nov 14 '18 at 14:19
This is not the best way to do this but you can get the xml as text and use RegExp to find and replace '>' with tabs according to the depth of the node and breaklines but I don't really know RegExp very well, sorry.
You can also use XSLT and transform it using javascript.
Check this link and take a look at this tutorial.

- 18,571
- 25
- 126
- 193
Use prettydiff.com/markup_beauty.js. This is capable of supporting invalid markup, fragments, and JSTL code.
<c:out value="<strong>text</strong>"/>
You can demo that application using a web tool at prettydiff.com. Just choose the "beautify" and "markup" options.
It is important that you use a proper tool to beautify your XML and not arbitrarily rush the job. Otherwise you will add white space tokens where they were not intended and remove them where they were intended. To raw data this may be consequential, but to human consumable content this destroys the integrity of your code, especially with regard to recursion.

- 807
- 10
- 9