xml-writer.js 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /*
  2. Copyright 2012-2015, Yahoo Inc.
  3. Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
  4. */
  5. var INDENT = ' ';
  6. /**
  7. * a utility class to produce well-formed, indented XML
  8. * @param {ContentWriter} contentWriter the content writer that this utility wraps
  9. * @constructor
  10. */
  11. function XMLWriter(contentWriter) {
  12. this.cw = contentWriter;
  13. this.stack = [];
  14. }
  15. function attrString(attrs) {
  16. if (!attrs) {
  17. return '';
  18. }
  19. var ret = [];
  20. Object.keys(attrs).forEach(function (k) {
  21. var v = attrs[k];
  22. ret.push(k + '="' + v + '"');
  23. });
  24. return ret.length === 0 ? '' : ' ' + ret.join(' ');
  25. }
  26. XMLWriter.prototype.indent = function (str) {
  27. return this.stack.map(function () { return INDENT; }).join('') + str;
  28. };
  29. /**
  30. * writes the opening XML tag with the supplied attributes
  31. * @param {String} name tag name
  32. * @param {Object} [attrs=null] attrs attributes for the tag
  33. */
  34. XMLWriter.prototype.openTag = function (name, attrs) {
  35. var str = this.indent('<' + name + attrString(attrs) + '>');
  36. this.cw.println(str);
  37. this.stack.push(name);
  38. };
  39. /**
  40. * closes an open XML tag.
  41. * @param {String} name - tag name to close. This must match the writer's
  42. * notion of the tag that is currently open.
  43. */
  44. XMLWriter.prototype.closeTag = function (name) {
  45. if (this.stack.length === 0) {
  46. throw new Error('Attempt to close tag ' + name + ' when not opened');
  47. }
  48. var stashed = this.stack.pop(),
  49. str = '</' + name + '>';
  50. if (stashed !== name) {
  51. throw new Error('Attempt to close tag ' + name + ' when ' + stashed + ' was the one open');
  52. }
  53. this.cw.println(this.indent(str));
  54. };
  55. /**
  56. * writes a tag and its value opening and closing it at the same time
  57. * @param {String} name tag name
  58. * @param {Object} [attrs=null] attrs tag attributes
  59. * @param {String} [content=null] content optional tag content
  60. */
  61. XMLWriter.prototype.inlineTag = function (name, attrs, content) {
  62. var str = '<' + name + attrString(attrs);
  63. if (content) {
  64. str += '>' + content + '</' + name + '>';
  65. } else {
  66. str += '/>';
  67. }
  68. str = this.indent(str);
  69. this.cw.println(str);
  70. };
  71. /**
  72. * closes all open tags and ends the document
  73. */
  74. XMLWriter.prototype.closeAll = function () {
  75. var that = this;
  76. this.stack.slice().reverse().forEach(function (name) {
  77. that.closeTag(name);
  78. });
  79. };
  80. module.exports = XMLWriter;