XML Serializer
By Mark Gibson
Description
Serialize DOM elements as an XML fragment.
Usage
To serialize an element:
var xmlString = $('#something').toXML();
Returns a string containing the serialized XML representation of the element.
Source
jQuery.fn.toXML = function () {
var out = '';
if (this.length > 0) {
if (typeof XMLSerializer == 'function' ||
typeof XMLSerializer == 'object')
{
var xs = new XMLSerializer();
this.each(function() {
out += xs.serializeToString(this);
});
} else if (this[0].xml !== undefined) {
this.each(function() {
out += this.xml;
});
} else {
// TODO: Manually serialize DOM here,
// for browsers that support neither
// of two methods above.
}
}
return out;
};
Notes
If the jQuery object holds several elements, the output will NOT be a valid XML Document, as it will have multiple root nodes. If you must have a valid document ensure you limit to a single element in the chain before calling toXML(), eg:
$('.something').eq(0).toXML();
This plugin is not widely tested yet, and will not work at all in browsers that don't support XMLSerializer, or the .xml property. (I think these need to be identified before implementing the fallback serialization routine).
Several suggestions were made on the mailing list for alternative ways to implement this. One was to partially implement XMLSerializer if it doesn't exist - I've decided against this - as I believe if we were to follow that route, then any implementation of XMLSerializer should be feature complete - but we don't really need things like serializeToStream() in this situation.
Tested In
- Firefox 1.5.0.7 / 2.0
- Opera 9.02
Note: Doesn't work in IE(6)
Extended for IE
Added the missing code for generating xml code with IE. Just handling attributes, elements and text. The nodetypes 4-12 are just added as nodeValue. Tested with IE7.
jQuery.fn.toXML = function ()
{
var toXML = function(node)
{
var out = '';
var attributes = '';
var content = '';
out += '<' + node.nodeName;
if (node.childNodes)
{
for (var i = 0; i < node.childNodes.length; i++)
{
switch(node.childNodes[i].nodeType)
{
case 1: // ELEMENT_NODE
content += toXML(node.childNodes[i]);
break;
case 2: // ATTRIBUTE_NODE
attributes += ' ' + node.childNodes[i].nodeName + '="'
+ node.childNodes[i].nodeValue + '"';
break;
case 3: // TEXT_NODE
case 4: // CDATA_SECTION_NODE
case 5: // ENTITY_REFERENCE_NODE
case 6: // ENTITY_NODE
case 7: // PROCESSING_INSTRUCTION_NODE
case 8: // COMMENT_NODE
case 9: // DOCUMENT_NODE
case 10: // DOCUMENT_TYPE_NODE
case 11: // DOCUMENT_FRAGMENT_NODE
case 12: // NOTATION_NODE
content += node.childNodes[i].nodeValue;
break;
}
}
}
out += attributes;
if (content.length > 0)
{
out += '>' + content;
out += '</' + node.tagName + '>';
}
else
{
out += '/>';
}
return out;
}
var out = '';
if (this.length > 0) {
if (typeof XMLSerializer == 'function' ||
typeof XMLSerializer == 'object')
{
var xs = new XMLSerializer();
this.each(function() { out += xs.serializeToString(this); });
}
else if (this[0].xml !== undefined)
{
this.each(function() { out += this.xml; });
}
else
{
if (this.length > 0)
{
this.each( function() { out += toXML(this); } );
}
}
}
return out;
};