6

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 :)

mgamer
  • 13,580
  • 25
  • 87
  • 145
  • 5
    Making XML look nice to the eye would be a magic trick! – Josh Stodola Jul 27 '09 at 23:04
  • 1
    In 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 Answers6

6

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.

Community
  • 1
  • 1
Arjan
  • 22,808
  • 11
  • 61
  • 71
6

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.

vadimk
  • 1,461
  • 15
  • 11
4

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==' '?'&nbsp;':'&#'+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/

3

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.

Allen Liu
  • 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
1

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.

the_drow
  • 18,571
  • 25
  • 126
  • 193
1

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.

austincheney
  • 807
  • 10
  • 9