Skip to content

Commit df17ffd

Browse files
committed
simplify xml generator and support self-closing tags
1 parent 1f6c99e commit df17ffd

File tree

2 files changed

+22
-41
lines changed

2 files changed

+22
-41
lines changed

internal/xml/index.ts

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,26 @@
1-
// Generic XML element. None of the implementations' output is sanitized.
2-
export interface IElement {
1+
// Generic XML element.
2+
export interface IXml {
33
render(): string;
44
}
55

6-
// Unstructured element that will render as the provided string.
7-
export class RawElement implements IElement {
8-
public text: string;
9-
10-
public constructor(text: string) {
11-
this.text = text;
12-
}
13-
14-
public render(): string {
15-
return this.text;
16-
}
17-
}
18-
196
// Structured element with tag, attributes and children.
20-
export class Element implements IElement {
7+
export class Xml implements IXml {
218
public tag: string;
229
public attributes: Record<string, string | number>;
23-
public children: IElement[];
10+
public children: IXml[];
2411

25-
public constructor(tag: string, attributes?: Element["attributes"]) {
12+
public constructor(tag: string, attributes?: Xml["attributes"]) {
2613
this.tag = tag;
2714
this.attributes = attributes || {};
2815
this.children = [];
2916
}
3017

31-
public add(child: IElement): Element {
32-
this.children.push(child);
33-
return this;
34-
}
35-
3618
public render(): string {
3719
const attributes = this.renderAttributes();
3820
const content = this.renderChildren();
21+
if (content === "") {
22+
return `<${this.tag}${attributes}/>`;
23+
}
3924
return `<${this.tag}${attributes}>${content}</${this.tag}>`;
4025
}
4126

internal/xml/test.ts

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,26 @@
1-
import {Element, RawElement} from ".";
1+
import {Xml} from ".";
22

33
describe("internal/xml/xml", () => {
44
describe("render", () => {
5-
it("should render raw elements", () => {
6-
const elem = new RawElement("test");
7-
expect(elem.render()).toBe("test");
8-
});
9-
105
it("should render element tags", () => {
11-
const elem = new Element("test");
12-
expect(elem.render()).toBe("<test></test>");
6+
const elem = new Xml("test");
7+
expect(elem.render()).toBe("<test/>");
138
});
149

1510
it("should render element attributes", () => {
16-
const elem = new Element("test", {a: 1, "b-c": "d"});
17-
expect(elem.render()).toBe('<test a="1" b-c="d"></test>');
11+
const elem = new Xml("test", {a: 1, "b-c": "d"});
12+
expect(elem.render()).toBe('<test a="1" b-c="d"/>');
1813
});
1914

20-
it("should render element children", () => {
21-
const a = new Element("a");
22-
const aa = new Element("aa");
23-
const ab = new Element("ab");
24-
const aba = new RawElement("aba");
25-
a.add(aa).add(ab);
26-
ab.add(aba);
27-
expect(a.render()).toBe('<a><aa></aa><ab>aba</ab></a>');
15+
it("should render nested elements", () => {
16+
const a = new Xml("a");
17+
const aa = new Xml("aa");
18+
const ab = new Xml("ab");
19+
const aba = {render: () => "aba"};
20+
a.children.push(aa);
21+
a.children.push(ab);
22+
ab.children.push(aba);
23+
expect(a.render()).toBe("<a><aa/><ab>aba</ab></a>");
2824
});
2925
});
3026
});

0 commit comments

Comments
 (0)