code: function walk_obj(next, next_child) {
    var tag_type, i, prop;
    var name = type(next);
  
    if ('Undefined' == name) {
      return;
    } else if (Array.isArray(next)) {
      next_child = next_child.ele('array');
      for (i = 0; i < next.length; i++) {
        walk_obj(next[i], next_child);
      }
  
    } else if (Buffer.isBuffer(next)) {
      next_child.ele('data').raw(next.toString('base64'));
  
    } else if ('Object' == name) {
      next_child = next_child.ele('dict');
      for (prop in next) {
        if (next.hasOwnProperty(prop)) {
          next_child.ele('key').txt(prop);
          walk_obj(next[prop], next_child);
        }
      }
  
    } else if ('Number' == name) {
      // detect if this is an integer or real
      // TODO: add an ability to force one way or another via a "cast"
      tag_type = (next % 1 === 0) ? 'integer' : 'real';
      next_child.ele(tag_type).txt(next.toString());
  
    } else if ('Date' == name) {
      next_child.ele('date').txt(ISODateString(new Date(next)));
  
    } else if ('Boolean' == name) {
      next_child.ele(next ? 'true' : 'false');
  
    } else if ('String' == name) {
      next_child.ele('string').txt(next);
  
    } else if ('ArrayBuffer' == name) {
      next_child.ele('data').raw(base64.fromByteArray(next));
  
    } else if (next && next.buffer && 'ArrayBuffer' == type(next.buffer)) {
      // a typed array
      next_child.ele('data').raw(base64.fromByteArray(new Uint8Array(next.buffer), next_child));
  
    }
  }
docs: depth first, recursive traversal of a javascript object. when complete,
  next_child contains a reference to the build XML object.
  
  @api private