static-xform.js 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. const BaseXform = require('./base-xform');
  2. const XmlStream = require('../../utils/xml-stream');
  3. // const model = {
  4. // tag: 'name',
  5. // $: {attr: 'value'},
  6. // c: [
  7. // { tag: 'child' }
  8. // ],
  9. // t: 'some text'
  10. // };
  11. function build(xmlStream, model) {
  12. xmlStream.openNode(model.tag, model.$);
  13. if (model.c) {
  14. model.c.forEach(child => {
  15. build(xmlStream, child);
  16. });
  17. }
  18. if (model.t) {
  19. xmlStream.writeText(model.t);
  20. }
  21. xmlStream.closeNode();
  22. }
  23. class StaticXform extends BaseXform {
  24. constructor(model) {
  25. super();
  26. // This class is an optimisation for static (unimportant and unchanging) xml
  27. // It is stateless - apart from its static model and so can be used as a singleton
  28. // Being stateless - it will only track entry to and exit from it's root xml tag during parsing and nothing else
  29. // Known issues:
  30. // since stateless - parseOpen always returns true. Parent xform must know when to start using this xform
  31. // if the root tag is recursive, the parsing will behave unpredictably
  32. this._model = model;
  33. }
  34. render(xmlStream) {
  35. if (!this._xml) {
  36. const stream = new XmlStream();
  37. build(stream, this._model);
  38. this._xml = stream.xml;
  39. }
  40. xmlStream.writeXml(this._xml);
  41. }
  42. parseOpen() {
  43. return true;
  44. }
  45. parseText() {}
  46. parseClose(name) {
  47. switch (name) {
  48. case this._model.tag:
  49. return false;
  50. default:
  51. return true;
  52. }
  53. }
  54. }
  55. module.exports = StaticXform;