objectToXML with Arrays

Discussion of the xtools Toolkit

Moderators: Tom, Kukurykus

myranalis

objectToXML with Arrays

Post 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
myranalis

objectToXML with Arrays

Post 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;
};
xbytor

objectToXML with Arrays

Post 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;
};
myranalis

objectToXML with Arrays

Post 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.
xbytor

objectToXML with Arrays

Post 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;
    }