XmlElem.ts 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import type { NamespaceTable } from "@/ua/NameSpaceTable";
  2. export class XMLElem {
  3. name: string;
  4. value: string;
  5. elements: XMLElem[]=[];
  6. attributes: XmlAttr[]=[];
  7. constructor(name: string, value?:string) {
  8. this.name=name;
  9. this.value=value||'';
  10. }
  11. public add(elem: XMLElem): XMLElem {
  12. this.elements.push(elem);
  13. return elem;
  14. }
  15. public attr(name:string, value: string|boolean|undefined|null): XMLElem {
  16. if(value===undefined||value===null)
  17. return this; //skip undefined/null values
  18. this.attributes.push(new XmlAttr(name, value?.toString()));
  19. return this;
  20. }
  21. public elem(name:string, value: XMLElem|string|boolean|undefined|null): XMLElem {
  22. if(value===undefined||value===null)
  23. return this; //skip undefined/null values
  24. if(value instanceof XMLElem) {
  25. this.elements.push(value);
  26. return this;
  27. }
  28. this.elements.push(new XMLElem(name, value?.toString()));
  29. return this;
  30. }
  31. public toString(level: number=0): string {
  32. let s="";
  33. if(level==0) {
  34. s+='<?xml version="1.0" encoding="utf-8" ?>\n'
  35. }
  36. s+=" ".repeat(level+1) + `<${this.name} `;
  37. for(const attr of this.attributes) {
  38. if(attr.value==undefined)
  39. continue;
  40. s+=`${attr.name}="${this.escapeXml(attr.value)}" `;
  41. }
  42. s=s.slice(0, -1);
  43. s+=`>`
  44. for(const elem of this.elements) {
  45. s+="\n"+" ".repeat(level) + elem.toString(level+1);
  46. }
  47. if(this.value && this.elements.length==0) {
  48. s+=this.escapeXml(this.value);
  49. }
  50. if(this.elements.length>0)
  51. s+="\n" + " ".repeat(level);
  52. s+=`</${this.name}>`
  53. return s;
  54. }
  55. private escapeXml(unsafe: string) {
  56. return unsafe.replace(/[<>&'"]/g, (c: string):string => {
  57. switch (c) {
  58. case '<': return '&lt;';
  59. case '>': return '&gt;';
  60. case '&': return '&amp;';
  61. case '\'': return '&apos;';
  62. case '"': return '&quot;';
  63. }
  64. return c;
  65. });
  66. }
  67. }
  68. class XmlAttr {
  69. constructor(public name: string,
  70. public value: string) {
  71. }
  72. }
  73. export interface IToXML {
  74. toXML(lnst: NamespaceTable, gnst: NamespaceTable) :XMLElem;
  75. }