builder.js
  1  var util = require('../util');
  2  var XmlNode = require('./xml-node').XmlNode;
  3  var XmlText = require('./xml-text').XmlText;
  4  
  5  function XmlBuilder() { }
  6  
  7  XmlBuilder.prototype.toXML = function(params, shape, rootElement, noEmpty) {
  8    var xml = new XmlNode(rootElement);
  9    applyNamespaces(xml, shape, true);
 10    serialize(xml, params, shape);
 11    return xml.children.length > 0 || noEmpty ? xml.toString() : '';
 12  };
 13  
 14  function serialize(xml, value, shape) {
 15    switch (shape.type) {
 16      case 'structure': return serializeStructure(xml, value, shape);
 17      case 'map': return serializeMap(xml, value, shape);
 18      case 'list': return serializeList(xml, value, shape);
 19      default: return serializeScalar(xml, value, shape);
 20    }
 21  }
 22  
 23  function serializeStructure(xml, params, shape) {
 24    util.arrayEach(shape.memberNames, function(memberName) {
 25      var memberShape = shape.members[memberName];
 26      if (memberShape.location !== 'body') return;
 27  
 28      var value = params[memberName];
 29      var name = memberShape.name;
 30      if (value !== undefined && value !== null) {
 31        if (memberShape.isXmlAttribute) {
 32          xml.addAttribute(name, value);
 33        } else if (memberShape.flattened) {
 34          serialize(xml, value, memberShape);
 35        } else {
 36          var element = new XmlNode(name);
 37          xml.addChildNode(element);
 38          applyNamespaces(element, memberShape);
 39          serialize(element, value, memberShape);
 40        }
 41      }
 42    });
 43  }
 44  
 45  function serializeMap(xml, map, shape) {
 46    var xmlKey = shape.key.name || 'key';
 47    var xmlValue = shape.value.name || 'value';
 48  
 49    util.each(map, function(key, value) {
 50      var entry = new XmlNode(shape.flattened ? shape.name : 'entry');
 51      xml.addChildNode(entry);
 52  
 53      var entryKey = new XmlNode(xmlKey);
 54      var entryValue = new XmlNode(xmlValue);
 55      entry.addChildNode(entryKey);
 56      entry.addChildNode(entryValue);
 57  
 58      serialize(entryKey, key, shape.key);
 59      serialize(entryValue, value, shape.value);
 60    });
 61  }
 62  
 63  function serializeList(xml, list, shape) {
 64    if (shape.flattened) {
 65      util.arrayEach(list, function(value) {
 66        var name = shape.member.name || shape.name;
 67        var element = new XmlNode(name);
 68        xml.addChildNode(element);
 69        serialize(element, value, shape.member);
 70      });
 71    } else {
 72      util.arrayEach(list, function(value) {
 73        var name = shape.member.name || 'member';
 74        var element = new XmlNode(name);
 75        xml.addChildNode(element);
 76        serialize(element, value, shape.member);
 77      });
 78    }
 79  }
 80  
 81  function serializeScalar(xml, value, shape) {
 82    xml.addChildNode(
 83      new XmlText(shape.toWireFormat(value))
 84    );
 85  }
 86  
 87  function applyNamespaces(xml, shape, isRoot) {
 88    var uri, prefix = 'xmlns';
 89    if (shape.xmlNamespaceUri) {
 90      uri = shape.xmlNamespaceUri;
 91      if (shape.xmlNamespacePrefix) prefix += ':' + shape.xmlNamespacePrefix;
 92    } else if (isRoot && shape.api.xmlNamespaceUri) {
 93      uri = shape.api.xmlNamespaceUri;
 94    }
 95  
 96    if (uri) xml.addAttribute(prefix, uri);
 97  }
 98  
 99  /**
100   * @api private
101   */
102  module.exports = XmlBuilder;