Браузерный парсер 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 < xmlDoc.childNodes.length; k++) { if (xmlDoc.childNodes[k].nodeName.indexOf("#text") > -1) continue;
nodes.push(xmlDoc.childNodes[k])
}
var doSpaces = function() {
var spaces = "";
for (var z=0; z < step; z++) {
spaces = spaces + " ";
}
return spaces;
}
for (var j=0; j < nodes.length; j++) {
var el = nodes[j],
spaces = doSpaces();
tree = tree + spaces + "<span class="xml-tag"> < </span>" + el.nodeName;
if (el.attributes) {
for (var i=0; i < 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'></</span>" + el.nodeName + "><br/>";
step = _step;
} else {
tree = tree + " ><br/>";
step++;
build(el);
spaces = doSpaces();
tree = tree + spaces + "<span class='xml-tag'></</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" && 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);
Посмотреть пример можно здесь. Разбираемый файл лежит здесь.