Subversion Repositories munaweb

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
// flattens an object (recursively!), similarly to Array#flatten
2
// e.g. flatten({ a: { b: { c: "hello!" } } }); // => "hello!"
3
function flatten(object) {
4
  var check = _.isPlainObject(object) && _.size(object) === 1;
5
  return check ? flatten(_.values(object)[0]) : object;
6
}
7
 
8
function XMLparse(xml) {
9
  var data = {};
10
 
11
  var isText = xml.nodeType === 3,
12
      isElement = xml.nodeType === 1,
13
      body = xml.textContent && xml.textContent.trim(),
14
      hasChildren = xml.children && xml.children.length,
15
      hasAttributes = xml.attributes && xml.attributes.length;
16
 
17
  // if it's text just return it
18
  if (isText) { return xml.nodeValue.trim(); }
19
 
20
  // if it doesn't have any children or attributes, just return the contents
21
  if (!hasChildren && !hasAttributes) { return body; }
22
 
23
  // if it doesn't have children but _does_ have body content, we'll use that
24
  if (!hasChildren && body.length) { data.text = body; }
25
 
26
  // if it's an element with attributes, add them to data.attributes
27
  if (isElement && hasAttributes) {
28
    data.attributes = _.reduce(xml.attributes, function(obj, name, id) {
29
      var attr = xml.attributes.item(id);
30
      obj[attr.name] = attr.value;
31
      return obj;
32
    }, {});
33
  }
34
 
35
  // recursively call #XMLparse over children, adding results to data
36
  _.each(xml.children, function(child) {
37
    var name = child.nodeName;
38
 
39
    // if we've not come across a child with this nodeType, add it as an object
40
    // and return here
41
    if (!_.has(data, name)) {
42
      data[name] = XMLparse(child);
43
      return;
44
    }
45
 
46
    // if we've encountered a second instance of the same nodeType, make our
47
    // representation of it an array
48
    if (!_.isArray(data[name])) { data[name] = [data[name]]; }
49
 
50
    // and finally, append the new child
51
    data[name].push(XMLparse(child));
52
  });
53
 
54
  // if we can, let's fold some attributes into the body
55
  _.each(data.attributes, function(value, key) {
56
    if (data[key] != null) { return; }
57
    data[key] = value;
58
    delete data.attributes[key];
59
  });
60
 
61
  // if data.attributes is now empty, get rid of it
62
  if (_.isEmpty(data.attributes)) { delete data.attributes; }
63
 
64
  // simplify to reduce number of final leaf nodes and return
65
  return flatten(data);
66
}