Браузерный парсер XML-файла

Требуется сделать вывод XML-файла на экран в удобном для человека виде, со своим набором цветов, отступов, в отдельном окне или блоке на странице и так далее. Стандартный вывод реализован в браузерах (например, Internet Explorer или Chrome). Ниже представлена функция, которая умеет это делать.

Сначала мы тем или иным способом получаем XML во внутреннем представлении, а потом строим само дерево:

function xmlTree(doc) {
				
	var xml = new XMLHttpRequest();
	xml.open("GET", doc, false);
	xml.send(null);
	var parseXml = function(xmlStr) {         
       if (typeof window.DOMParser != "undefined") {                   
            return ( new window.DOMParser() ).parseFromString(xmlStr, "text/xml");    
       } else if (typeof window.ActiveXObject != "undefined" && new window.ActiveXObject("Microsoft.XMLDOM")) {               
           var xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM");
           xmlDoc.async = "false";
           xmlDoc.loadXML(xmlStr);
           return xmlDoc;    
       } else {
           throw new Error("No XML parser found");
       }
    }
            
    var xmlDoc = parseXml(xml.responseText),
         tree = "",        
         lastNode = "",    
         step = 1;                
 
 
    var build = function(xmlDoc) {   
 
          // нужно для отрисовки тегов с содержимым типа <tag>text</tag>, без отступов
          var _step = 1; 
 
          // выкидываем текстовые узлы из набора
          var nodes = [];
          for (var k=0; k &lt; xmlDoc.childNodes.length; k++) {              if (xmlDoc.childNodes[k].nodeName.indexOf("#text") &gt; -1) continue; 
             nodes.push(xmlDoc.childNodes[k])
          }
          var doSpaces = function() {
              var spaces = "";
              for (var z=0; z &lt; step; z++) {                  
                 spaces = spaces + "   ";   
              }
              return spaces;
          }
          for (var j=0; j &lt; nodes.length; j++) {
              var el = nodes[j],
                 spaces = doSpaces();                                     
              tree = tree + spaces + "<span class="xml-tag"> &lt; </span>" + el.nodeName;
              if (el.attributes) {
                  for (var i=0; i &lt; el.attributes.length; i++) {     
                    tree = tree + " <span class="xml-attr-name">" + el.attributes[i].nodeName + "=</span><span class="xml-attr">\"" + el.attributes[i].value + "\"</span>"
                  }
              }           
              if (el.childNodes.length > 0) {  
                 // тег без вложенных тегов, но с текстовым содержимым
                 if (el.childNodes.length == 1 && el.innerHTML.length > 0) {
                    var s = el.innerHTML;
                    tree = tree + " >" + s;
                    _step = step;
                    step = 0;
                    build(el);
                    spaces = doSpaces();
                    tree = tree + spaces + "<span class='xml-tag'>&lt;/</span>" + el.nodeName + "><br/>";      
                    step = _step;       
                 } else {
                    tree = tree + " ><br/>";
                    step++;              
                    build(el);
                    spaces = doSpaces();
                    tree = tree + spaces + "<span class='xml-tag'>&lt;/</span>" + el.nodeName + "><br/>";    
                 }                     
              } else {  
                 if (el.innerHTML.length > 0) {
                    var s = el.innerHTML;
                    tree = tree + " >" + s + "<br/>"
                 }
                 tree = tree + "<span class='xml-tag'> /></span><br/>";
              }   
              if (j == (nodes.length - 1)) {step--;}             
          }        
      }
      build(xmlDoc);                  
      return tree        
}
 
var res = xmlTree("example.xml");
document.getElementById("html").innerHTML = res;

Если XML-документ уже получен программой (например, AJAX-запросом), то первая часть (до функции build) может быть чуть проще:

var parseXml = function(xmlStr) {         
    if (typeof window.DOMParser != "undefined") {                   
       return ( new window.DOMParser() ).parseFromString(xmlStr, "text/xml");    
    } else if (typeof window.ActiveXObject != "undefined" &amp;&amp; new window.ActiveXObject("Microsoft.XMLDOM")) {               
       var xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM");
       xmlDoc.async = "false";
       xmlDoc.loadXML(xmlStr);
       return xmlDoc;    
   } else {
       throw new Error("No XML parser found");
   }
}
            
var xmlDoc = parseXml(doc),
   tree = "",        
   lastNode = "",    
   step = 1; 

Вызываем, соответственно, так:

var res = xmlTree(gotXml);

Посмотреть пример можно здесь. Разбираемый файл лежит здесь.

Теги: