Formatting XML strings in JavaScript for readability
I've been looking something like this, nice idea. But Your function couldn't parse text nodes. Try insert some text, example:

&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"&gt;&lt;soapenv:Body&gt;textNode&lt;soapenv:temp&gt;innerText&lt;/soapenv:temp&gt;&lt;ns:temp&gt;&lt;ns:getCourseResponse xmlns:ns="http://course.ws.blackboard" /&gt;&lt;/ns:temp&gt;&lt;/soapenv:Body&gt;&lt;/soapenv:Envelope&gt;


My proposition for this problem is:

1) change spliting code in this way:

.replace( /(&lt;([a-zA-Z]+\b)[^&gt;]*&gt;)(?!&lt;\/\2&gt;|[\w\s])/g, "$1\n" ) //add \n after tag if not followed by the closing tag of pair or text node
.replace( /(&lt;\/[a-zA-Z]+[^&gt;]*&gt;)/g, "$1\n") //add \n after closing tag
.replace( /&gt;\s+(.+?)\s+&lt;(?!\/)/g, "&gt;\n$1\n&lt;") //add \n between sets of angled brackets and text node between them
.replace( /&gt;(.+?)&lt;([a-zA-Z])/g, "&gt;\n$1\n&lt;$2") //add \n between angled brackets and text node between them
.replace(/\?&gt;&lt;/, "?&gt;\n&lt;") //detect a header of XML


2) little modify third statement else if and add one more:

 else if (/&lt;.*&gt;/.test(line)) //if the line starts with an opening tag and does not contain an entire node
 {
  xmlArr[i] = tabs + line;  //add the tabs at the beginning of the line
  tabs += indent;  //and add one indent to the store
 }
 else  //if the line contain a text node
 {
  xmlArr[i] = tabs + line;  // add the tabs at the beginning of the line
 }


So finaly, our function will be:

function formatXML(input,indent)
{
  indent = indent || '\t'; //you can set/define other ident than tabs


  //PART 1: Add \n where necessary
  xmlString = input.replace(/^\s+|\s+$/g, '');  //trim it (just in case) {method trim() not working in IE8}

  xmlString = input
                   .replace( /(&lt;([a-zA-Z]+\b)[^&gt;]*&gt;)(?!&lt;\/\2&gt;|[\w\s])/g, "$1\n" ) //add \n after tag if not followed by the closing tag of pair or text node
                   .replace( /(&lt;\/[a-zA-Z]+[^&gt;]*&gt;)/g, "$1\n") //add \n after closing tag
                   .replace( /&gt;\s+(.+?)\s+&lt;(?!\/)/g, "&gt;\n$1\n&lt;") //add \n between sets of angled brackets and text node between them
                   .replace( /&gt;(.+?)&lt;([a-zA-Z])/g, "&gt;\n$1\n&lt;$2") //add \n between angled brackets and text node between them
                   .replace(/\?&gt;&lt;/, "?&gt;\n&lt;") //detect a header of XML

  xmlArr = xmlString.split('\n');  //split it into an array (for analise each line separately)



  //PART 2: indent each line appropriately

  var tabs = '';  //store the current indentation
  var start = 0;  //starting line

  if (/^&lt;[?]xml/.test(xmlArr[0]))  start++;  //if the first line is a header, ignore it

  for (var i = start; i &lt; xmlArr.length; i++) //for each line
  {  
    var line = xmlArr[i].replace(/^\s+|\s+$/g, '');  //trim it (just in case)

    if (/^&lt;[/]/.test(line))  //if the line is a closing tag
     {
      tabs = tabs.replace(indent, '');  //remove one indent from the store
      xmlArr[i] = tabs + line;  //add the tabs at the beginning of the line
     }
     else if (/&lt;.*&gt;.*&lt;\/.*&gt;|&lt;.*[^&gt;]\/&gt;/.test(line))  //if the line contains an entire node
     {
      //leave the store as is
      xmlArr[i] = tabs + line; //add the tabs at the beginning of the line
     }
     else if (/&lt;.*&gt;/.test(line)) //if the line starts with an opening tag and does not contain an entire node
     {
      xmlArr[i] = tabs + line;  //add the tabs at the beginning of the line
      tabs += indent;  //and add one indent to the store
     }
     else  //if the line contain a text node
     {
      xmlArr[i] = tabs + line;  // add the tabs at the beginning of the line
     }
  }


  //PART 3: return formatted string (source)
  return  xmlArr.join('\n');  //rejoin the array to a string and return it
}