Page 1 of 1

objectToXML with Arrays

Posted: Sun Nov 13, 2011 8:58 pm
by myranalis
I've been using objectToXML to save simple objects out to an easily readable format no worries. This time though, I've got an array of little helper objects rather than just simple data types. The method blows up with the error 'Not well-formed (invalid token)' when it trys to save out the array. It looks like it is trying to create an xml object <0></0> for the first object and fails at that point. Any pointers on getting this to work? Thanks!

Anna

objectToXML with Arrays

Posted: Sun Nov 13, 2011 9:36 pm
by myranalis
Well I've got it to save correctly with some mods to the function. Now I'll just have to get it to read in again

Code: Select allStdlib.objectToXML = function(obj, name, xml) {
  if (!xml) {
    if (name == undefined) {
      name = "Object";
    }
   if (!isNumber(name)) {
        xml = new XML('<' + name + "></" + name + '>');
    } else {
        xml = new XML('<el' + name + "></el" + name + '>');
    }
    // do the eval because of non-CS/2 syntax
    eval('xml.@type = (obj instanceof Array) ? "array" : "object"');
  }

  function _addChild(xml, obj, idx) {
    var val = obj[idx];

    var isArray = (obj instanceof Array);

    // skip 'hidden' properties
    if (idx.toString()[0] == '_') {
      return undefined;
    }

    // just skip undefined values
    if (val == undefined) {
      return undefined;
    }
    var type = typeof val;

    var child;

    switch (type){
    case "number":
    case "boolean":
    case "string":
      if (!isNumber(idx)) {
        child = new XML('<' + idx + "></" + idx + '>');
      } else {
        child = new XML('<el' + idx + "></el" + idx + '>');
      }
      child.appendChild(val);
      // do the eval because of non-CS/2 syntax
      eval('child.@type = type');
      break;

    case "object":
     if (!isNumber(idx)) {
       child = Stdlib.objectToXML(val, idx);
      } else {
         child = Stdlib.objectToXML(val, val.toString());
      }
      break;

    default:
      return undefined;
      break;
    }

    xml.appendChild(child);
  };

  if (obj instanceof Array) {
    for (var i = 0; i < obj.length; i++) {
      _addChild(xml, obj, i);
    }
  } else {
    for (var idx in obj) {
      _addChild(xml, obj, idx);
    }
    if (xml.children().length() == 0) {
      xml.appendChild(obj.toString());
      // do the eval because of non-CS/2 syntax
      eval('xml.@type = "string"');
    }
  }

  return xml;
};

objectToXML with Arrays

Posted: Sun Nov 13, 2011 10:19 pm
by xbytor
See if this works. It's a simplification of the original and your fix.

Code: Select allStdlib.objectToXML = function(obj, name, xml) {
  if (!xml) {
    if (name == undefined) {
      name = "Object";
    }
    xml = new XML('<' + name + "></" + name + '>');
    // do the eval because of non-CS/2 syntax
    eval('xml.@type = (obj instanceof Array) ? "array" : "object"');
  }

  function _addChild(xml, obj, idx) {
    var val = obj[idx];

    var isArray = (obj instanceof Array);

    // skip 'hidden' properties
    if (idx.toString()[0] == '_') {
      return undefined;
    }

    // just skip undefined values
    if (val == undefined) {
      return undefined;
    }
    var type = typeof val;

    var child;

    if (isNumber(idx)) {
      idx = "el" + idx;
    }

    switch (type){
    case "number":
    case "boolean":
    case "string":
      child = new XML('<' + idx + "></" + idx + '>');
      child.appendChild(val);
      // do the eval because of non-CS/2 syntax
      eval('child.@type = type');
      break;

    case "object":
      child = Stdlib.objectToXML(val, idx);
      break;

    default:
      return undefined;
      break;
    }

    xml.appendChild(child);
  };

  if (obj instanceof Array) {
    for (var i = 0; i < obj.length; i++) {
      _addChild(xml, obj, i);
    }
  } else {
    for (var idx in obj) {
      _addChild(xml, obj, idx);
    }
    if (xml.children().length() == 0) {
      xml.appendChild(obj.toString());
      // do the eval because of non-CS/2 syntax
      eval('xml.@type = "string"');
    }
  }

  return xml;
};

objectToXML with Arrays

Posted: Sun Nov 13, 2011 10:30 pm
by myranalis
I think that would work too, the only thing is - I like the way my fix uses the object name as the xml element rather than the el0, etc. *shrug* That's just cosmetic though really I guess.

objectToXML with Arrays

Posted: Sun Nov 13, 2011 11:00 pm
by xbytor
I like the way my fix uses the object name as the xml element rather than the el0

Missed that part. Good idea. Here's the fix for that.

Code: Select all    if (isNumber(idx)) {
      idx = xml.localName() + idx;
    }