/********************************
* jQuery XML Helper
*
* Created by Kamran Ayub (c)2011
* https://github.com/kamranayub/jQuery-XML-Helper
*
* Makes working with XML using jQuery a bit easier
* for Internet Explorer.
*
*
*/
var $$ = $.sub();
$.xml = function (xml) {
/// <summary>
/// Makes working with XML a little more
/// cross-browser compatible by overloading
/// and extending some core jQuery functions
/// </summary>
"use strict";
$$.parseXML = function (data, xml, tmp) {
// Slightly modified to use
// ActiveX for IE9 as well (reversed
// statements
if ( window.ActiveXObject ) { // IE6+
xml = new ActiveXObject( "Microsoft.XMLDOM" );
xml.async = "false";
xml.loadXML( data );
} else { // Standard
tmp = new DOMParser();
xml = tmp.parseFromString( data , "text/xml" );
}
tmp = xml.documentElement;
if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
jQuery.error( "Invalid XML: " + data );
}
return xml;
};
$$.fn.append = function () {
var target = arguments[0],
nodes = [],
numNodes,
curDOM,
fallback = false;
this.each(function () {
curDOM = this;
if (curDOM !== null && $.find.isXML(curDOM)) {
// XMLDOM?
if ($.find.isXML(target)) {
nodes = target.childNodes;
// $-wrapped XML?
} else if (target instanceof $ && $.find.isXML(target[0])) {
nodes = target;
// String?
} else if (typeof target === "string") {
// Wrap in case multiple elements were requested
nodes = $$.parseXML("<jxmlroot>" + target + "</jxmlroot>").firstChild.childNodes;
}
// Nodes get removed from array when moved
numNodes = nodes.length;
for (i = 0; i < numNodes; i++) {
if ($.browser.webkit) {
curDOM.appendChild(curDOM.ownerDocument.importNode(nodes[i], true));
} else {
curDOM.appendChild(nodes[0]);
}
}
} else {
fallback = true;
}
});
if (fallback === true) {
return $.fn.append.apply(this, arguments);
} else {
return this;
}
};
$$.fn.before = function () {
if (typeof arguments[0] === "string") {
if ($.browser.webkit) {
arguments[0] = this[0].ownerDocument.importNode(
$$.parseXML("<jxmlroot>" + arguments[0] + "</jxmlroot>"
).firstChild, true).childNodes;
} else {
arguments[0] = $.xml(arguments[0]);
}
return $.fn.before.apply(this, arguments);
} else {
return $.fn.before.apply(this, arguments);
}
};
$$.fn.text = function () {
var text = arguments[0],
curDOM,
textNode, i,
curNodes, curNodeLength, node;
if (text) {
this.each(function () {
curDOM = this;
textNode = curDOM.ownerDocument.createTextNode(text);
curNodes = curDOM.childNodes;
curNodeLength = curNodes.length;
// Remove all nodes as we're setting the value of the node to
// a text node
for (i = 0; i < curNodeLength; i++) {
node = curNodes[0];
node.parentNode.removeChild(node);
}
curDOM.appendChild(textNode);
});
return this;
} else {
return $.fn.text.apply(this, arguments);
}
};
$$.fn.cdata = function (data) {
var curDOM, i, node, cdata;
// Set CDATA
if (data) {
this.each(function () {
curDOM = this;
cdata = curDOM.ownerDocument.createCDATASection(data);
// Remove existing CDATA, if any.
for (i = 0; i < curDOM.childNodes.length; i++) {
node = curDOM.childNodes[i];
if (node.nodeType === 4) { // cdata
node.parentNode.removeChild(node);
break;
}
}
if ($.browser.webkit) {
curDOM.appendChild(curDOM.ownerDocument.importNode(cdata, true));
} else {
curDOM.appendChild(cdata);
}
});
return this;
} else {
// Get CDATA
curDOM = this[0];
for (i = 0; i < curDOM.childNodes.length; i++) {
if (curDOM.childNodes[i].nodeType === 4) { // cdata
return curDOM.childNodes[i].nodeValue;
}
}
}
return null;
};
$$.fn.html = function () {
// Redirect HTML w/ no args to .cdata()
if ($.find.isXML(this[0]) && !arguments[0]) {
return this.cdata();
} else if ($.find.isXML(this[0]) && arguments[0]) {
return this.cdata(arguments[0]);
} else {
return $.fn.html.apply(this, arguments);
}
};
$$.fn.xml = function () {
/// <summary>
/// Gets outer XML. Expects $-wrapped XMLDOM.
/// </summary>
// for IE
if (window.ActiveXObject) {
return this[0].xml;
} else {
// code for Mozilla, Firefox, Opera, etc.
return (new XMLSerializer()).serializeToString(this[0]);
}
};
// Wrap in root tag so when creating new standalone markup, things
// should still work.
var parser = $$.parseXML("<jxmlroot>" + xml + "</jxmlroot>");
return $$(parser).find("jxmlroot > *");
};
// XML Formatter
// =============
// A small jQuery plugin that works in conjunction with [jquery.xml](https://github.com/kamranayub/jQuery-XML-Helper) to format
// an XML DOM structure.
//
//
// Usage:
// ------
//
// $(function () {
// var $xml = $.xml("<foo attr='foo'><bar></bar></foo>");
//
// $("#xmlOutput").formatXml($xml);
// });
(function ($) {
$.fn.formatXml = function ($xml) {
return this.each(function () {
var // Element container
$container = $(this),
// Recursive traversal function
traverse = function($node, $container) {
var $ul = $("<ul />"),
$li = $("<li />");
$li.append('<strong>' + $node[0].tagName + '</strong>');
$ul.append($li);
$container.append($ul);
// Find any attributes
if ($node[0].attributes.length) {
var $attrs = $("<ul />");
$.each($node[0].attributes, function(i, attr) {
$attrs.append("<li><em>@" + attr.name + "=<span>\"" + attr.value + "\"</span></em></li>");
});
$li.append($attrs);
}
// Text nodes
if ($node.children().length == 0 && $node.text().length) {
$li.append("<ul><li>" + $node.text() + "</li></ul>");
}
// Traverse children (if any)
if ($node.children().length > 0) {
$node.children().each(function(i, node) {
traverse($(node), $li);
});
}
};
// Traverse the XML tree
$container.empty();
traverse($xml, $container);
});
}
})(jQuery);
var xml = "<foo><bar><baz zing='true'>Text</baz></bar></foo>";
$("#container").formatXml($.xml(xml));
<div id="container"></div>
#container {
font-family: Arial, Verdana;
background: #222;
color: #eee;
padding: 10px;
ul {
list-style-type: none;
margin: 0 0 0 15px;
padding: 0;
strong { color: orangered; }
em { color: #888; span { color: #fff; } }
}
}