Wednesday, December 27, 2006

Serialize JavaScript objects to XML (for use with Ajax)

The following 3 functions can be added to any JavaScript library to serialize objects to XML for use with Ajax.

--- serialize.js ---

Array.prototype.toXml = function(t){
var s = new Array(), i, l = this.length, v;
var t2 = (t.charAt(t.length-1)=='s')?t.substring(0,t.length-1):t;

for(i=0;i<l;i++){
v = this[i];
switch (typeof v) {
case 'undefined':
case 'function':
case 'unknown':break;
case 'object':if(v!=null){s.push(v.toXml(t2));}break;
case 'string':v = v.toXml();
default:s.push('<'+t2+'>'+v+'');
}
}
if(s.length>1)return '<'+t+'>'+s.join('')+'';
return s;
};

Object.prototype.toXml = function(t){
var sa = new Array(''), se = new Array('');
if(!t) t=this._tagName||'object';

for(var i in this){
if (this.hasOwnProperty(i) && i.charAt(0)!='_') {
var v = this[i];
switch (typeof v) {
case 'undefined':
case 'function':
case 'unknown':break;
case 'object':if(v!=null){se.push(v.toXml(i));}break;
case 'string':v = v.toXml();
default: sa.push(' '+i+'="'+v+'"');
}
}
}
var s = se.join('');
return '<'+t+sa.join('')+((s!='')?'>'+s+'':'/>');
};

String.prototype.toXml = function(){
return this.replace('&','&amp;').
replace('<','&lt;').replace('>','&gt;').
replace('\'','&apos;').replace('"','&quot;');
};


Sample Usage

<script language="javascript" src="serialize.js"></script>
<script language="javascript">

function Car(make,model,color){
this.make = make;
this.model = model;
this.color = color;
}

var cars = new Array();
cars.push(new Car('BMW','545i','Silver'));
cars.push(new Car('Toyota','Corrola','Red'));
cars.push(new Car('Honda','Accord','Black'));

//serialize to xml
alert(cars.toXml());
</script>


Note:
1. Private properties are prefixed with an underscore
2. You can add a default TagName for an object using the this._tagName property. For example in the Cars object above, you can add:
this._tagName = 'car';
...

5 comments:

  1. Looks good.
    But You forget close tags for a valid xml

    Thanks....is useful for me.

    ReplyDelete
  2. http://svn.mirekrusin.com/pub/javascript/to_xml/trunk looks much nicer!

    ReplyDelete
  3. JavaScript is a good program and very easy to use. I don´t like a complex program. I prefer javascript because i consider it like a device very eficient and it have a good quality.
    I always looking for the quality that is why i prefer to buy viagra because i always have a great result in my sexual life.

    ReplyDelete
  4. This is a great script, thanks. For all your home security needs go to http://www.securehomeadvice.com

    ReplyDelete
  5. here is a better version, base on the code above:

    Array.prototype.toXml = function (t) {
    var s = new Array(), i, v;
    if (typeof t === 'undefined' || t === null) {
    t = this._tagName || 'array';
    }

    for (i = 0; i < this.length; i++) {
    v = this[i];
    switch (typeof v) {
    case 'undefined':
    case 'function':
    case 'unknown':
    {
    break;
    }
    case 'object':
    {
    if (v != null) {
    s.push(v.toXml(t));
    }
    break;
    }
    case 'string':
    {
    v = v.toXml();
    }
    default:
    {
    s.push('<' + t + '>' + v + '');
    }
    }
    }
    var result = '';
    if (s.length > 0) {
    result = s.join('');
    }
    return result;
    };

    Object.prototype.toXml = function (t) {
    var sa = new Array();
    var se = new Array();
    if(!t) t=this._tagName||'object';
    if (typeof t === 'undefined' || t === null) {
    t = this._tagName || 'object';
    }

    for (var i in this) {
    if (this.hasOwnProperty(i) && i.charAt(0) != '_') {
    var v = this[i];
    switch (typeof v) {
    case 'undefined':
    case 'function':
    case 'unknown':
    {
    break;
    }
    case 'object':
    {
    if (v != null) {
    se.push(v.toXml(i));
    }
    break;
    }
    case 'string':
    {
    v = v.toXml();
    }
    default:
    {
    if (i === '$text')
    {
    if (v != null) {
    se.push(v.toXml(i));
    }
    }
    else if (i.charAt(0) === "@")
    {
    sa.push(i.slice(1) + '="' + v + '"');
    }
    else
    {
    sa.push(i + '="' + v + '"');
    }
    }
    }
    }
    }

    var result = '<' + t;
    if (sa.length > 0)
    {
    result += ' ' + sa.join(' ');
    }
    if (se.length > 0)
    {
    result += '>' + se.join('') + '';
    }
    else
    {
    result += '/>';
    }

    return result;
    };

    String.prototype.toXml = function () {
    return this.replace('&','&').replace('<','<').replace('>','>').replace('\'','&apos;').replace('"','"');
    };

    ReplyDelete