xml-model 2.0.0-beta.1 → 2.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/xml/index.js CHANGED
@@ -1,17 +1,4 @@
1
- import { XML, ZXMLCommentNode, ZXMLElementNode, ZXMLNode, ZXMLRoot, ZXMLTextNode } from "./xml-js.js";
2
- import { xml } from "./schema-meta.js";
3
- import { normalizeCodecOptions, registerDefault } from "./codec.js";
4
- import { xmlModel } from "./model.js";
5
- export {
6
- XML,
7
- ZXMLCommentNode,
8
- ZXMLElementNode,
9
- ZXMLNode,
10
- ZXMLRoot,
11
- ZXMLTextNode,
12
- normalizeCodecOptions,
13
- registerDefault,
14
- xml,
15
- xmlModel
16
- };
17
- //# sourceMappingURL=index.js.map
1
+ import "./xml-js.js";
2
+ import "./schema-meta.js";
3
+ import "./codec.js";
4
+ import "./model.js";
package/dist/xml/model.js CHANGED
@@ -1,37 +1,33 @@
1
- import "zod";
2
- import { XML } from "./xml-js.js";
3
1
  import { model } from "../model.js";
4
- import { decode, XML_STATE, encode } from "./codec.js";
2
+ import XML from "./xml-js.js";
5
3
  import { root } from "./schema-meta.js";
4
+ import { XML_STATE, decode, encode } from "./codec.js";
5
+ import "zod";
6
+ //#region src/xml/model.ts
6
7
  function xmlModel(schema, options) {
7
- const _schema = options ? root(schema, options) : schema;
8
- return class extends model(_schema) {
9
- static fromXML(input) {
10
- if (typeof input === "string") {
11
- input = XML.parse(input);
12
- }
13
- if (XML.isRoot(input)) {
14
- input = XML.elementFromRoot(input);
15
- }
16
- const schema2 = this.dataSchema;
17
- const inputData = decode(this.dataSchema, input);
18
- const xmlState = inputData[XML_STATE];
19
- const parsed = schema2.parse(inputData);
20
- parsed[XML_STATE] = xmlState;
21
- return this.fromData(parsed);
22
- }
23
- static toXML(instance) {
24
- const data = this.toData(instance);
25
- const element = encode(this.dataSchema, data);
26
- return { elements: [element] };
27
- }
28
- static toXMLString(instance, options2 = {}) {
29
- const xml = this.toXML(instance);
30
- return XML.stringify(xml, options2);
31
- }
32
- };
8
+ const _schema = options ? root(schema, options) : schema;
9
+ return class extends model(_schema) {
10
+ static fromXML(input) {
11
+ if (typeof input === "string") input = XML.parse(input);
12
+ if (XML.isRoot(input)) input = XML.elementFromRoot(input);
13
+ const schema = this.dataSchema;
14
+ const inputData = decode(this.dataSchema, input);
15
+ const xmlState = inputData[XML_STATE];
16
+ const parsed = schema.parse(inputData);
17
+ parsed[XML_STATE] = xmlState;
18
+ return this.fromData(parsed);
19
+ }
20
+ static toXML(instance) {
21
+ const data = this.toData(instance);
22
+ return { elements: [encode(this.dataSchema, data)] };
23
+ }
24
+ static toXMLString(instance, options = {}) {
25
+ const xml = this.toXML(instance);
26
+ return XML.stringify(xml, options);
27
+ }
28
+ };
33
29
  }
34
- export {
35
- xmlModel
36
- };
37
- //# sourceMappingURL=model.js.map
30
+ //#endregion
31
+ export { xmlModel };
32
+
33
+ //# sourceMappingURL=model.js.map
@@ -1,96 +1,88 @@
1
+ import { getParentSchema, isZodType } from "../util/zod.js";
1
2
  import "zod";
2
- import { isZodType, getParentSchema } from "../util/zod.js";
3
- const metaKey = "@@xml-model";
3
+ //#region src/xml/schema-meta.ts
4
+ var metaKey = "@@xml-model";
5
+ /** Merge `partial` into the schema's existing meta (shallow spread, no overwrite). */
4
6
  function setMeta(schema, partial) {
5
- const existing = schema.meta()?.[metaKey] ?? {};
6
- return schema.meta({ [metaKey]: { ...existing, ...partial } });
7
+ const existing = schema.meta()?.[metaKey] ?? {};
8
+ return schema.meta({ [metaKey]: {
9
+ ...existing,
10
+ ...partial
11
+ } });
7
12
  }
8
13
  function normalizePropOptions(options) {
9
- if (!options) return {};
10
- const partial = {};
11
- if (options.tagname !== void 0)
12
- partial.propertyTagname = options.tagname;
13
- if (options.inline !== void 0) partial.inlineProperty = options.inline;
14
- if (options.match !== void 0)
15
- partial.propertyMatch = options.match;
16
- if (options.decode !== void 0) {
17
- const userDecode = options.decode;
18
- partial.decodeAsProperty = function(ctx) {
19
- const res = userDecode(ctx);
20
- if (typeof res !== "undefined") {
21
- Object.assign(ctx.result, res);
22
- }
23
- };
24
- }
25
- if (options.encode !== void 0) {
26
- const userEncode = options.encode;
27
- partial.encodeAsProperty = function(ctx) {
28
- const { property } = ctx;
29
- const res = userEncode(ctx);
30
- if (typeof res === "undefined") return;
31
- if (property.options.inlineProperty) {
32
- ctx.result.elements.push(...res.elements);
33
- } else {
34
- res.name = property.tagname;
35
- ctx.result.elements.push(res);
36
- }
37
- };
38
- }
39
- return partial;
14
+ if (!options) return {};
15
+ const partial = {};
16
+ if (options.tagname !== void 0) partial.propertyTagname = options.tagname;
17
+ if (options.inline !== void 0) partial.inlineProperty = options.inline;
18
+ if (options.match !== void 0) partial.propertyMatch = options.match;
19
+ if (options.decode !== void 0) {
20
+ const userDecode = options.decode;
21
+ partial.decodeAsProperty = function(ctx) {
22
+ const res = userDecode(ctx);
23
+ if (typeof res !== "undefined") Object.assign(ctx.result, res);
24
+ };
25
+ }
26
+ if (options.encode !== void 0) {
27
+ const userEncode = options.encode;
28
+ partial.encodeAsProperty = function(ctx) {
29
+ const { property } = ctx;
30
+ const res = userEncode(ctx);
31
+ if (typeof res === "undefined") return;
32
+ if (property.options.inlineProperty) ctx.result.elements.push(...res.elements);
33
+ else {
34
+ res.name = property.tagname;
35
+ ctx.result.elements.push(res);
36
+ }
37
+ };
38
+ }
39
+ return partial;
40
40
  }
41
41
  function root(optionsOrSchema, options) {
42
- if (isZodType(optionsOrSchema)) {
43
- return setMeta(optionsOrSchema, options ?? {});
44
- } else {
45
- return { [metaKey]: optionsOrSchema };
46
- }
42
+ if (isZodType(optionsOrSchema)) return setMeta(optionsOrSchema, options ?? {});
43
+ else return { [metaKey]: optionsOrSchema };
47
44
  }
48
45
  function prop(optionsOrSchema, options) {
49
- if (isZodType(optionsOrSchema)) {
50
- return setMeta(optionsOrSchema, normalizePropOptions(options));
51
- } else {
52
- return { [metaKey]: normalizePropOptions(optionsOrSchema) };
53
- }
46
+ if (isZodType(optionsOrSchema)) return setMeta(optionsOrSchema, normalizePropOptions(options));
47
+ else return { [metaKey]: normalizePropOptions(optionsOrSchema) };
54
48
  }
55
49
  function attr(optionsOrSchema, options) {
56
- const opts = isZodType(optionsOrSchema) ? options ?? {} : optionsOrSchema ?? {};
57
- const partial = {
58
- decodeAsProperty(ctx) {
59
- const { name, options: propOptions } = ctx.property;
60
- const attrName = opts.name ?? name;
61
- const attrValue = ctx.xml?.attributes[attrName];
62
- ctx.result[name] = propOptions.schema.parse(attrValue);
63
- },
64
- encodeAsProperty(ctx) {
65
- const { value, name } = ctx.property;
66
- const attrName = opts.name ?? name;
67
- ctx.result.attributes[attrName] = value.toString();
68
- }
69
- };
70
- if (isZodType(optionsOrSchema)) {
71
- return setMeta(optionsOrSchema, partial);
72
- } else {
73
- return { [metaKey]: partial };
74
- }
50
+ const opts = isZodType(optionsOrSchema) ? options ?? {} : optionsOrSchema ?? {};
51
+ const partial = {
52
+ decodeAsProperty(ctx) {
53
+ const { name, options: propOptions } = ctx.property;
54
+ const attrName = opts.name ?? name;
55
+ const attrValue = ctx.xml?.attributes[attrName];
56
+ ctx.result[name] = propOptions.schema.parse(attrValue);
57
+ },
58
+ encodeAsProperty(ctx) {
59
+ const { value, name } = ctx.property;
60
+ const attrName = opts.name ?? name;
61
+ ctx.result.attributes[attrName] = value.toString();
62
+ }
63
+ };
64
+ if (isZodType(optionsOrSchema)) return setMeta(optionsOrSchema, partial);
65
+ else return { [metaKey]: partial };
75
66
  }
76
- const xml = { root, prop, attr };
67
+ /** Namespace object for XML metadata helpers. */
68
+ var xml = {
69
+ root,
70
+ prop,
71
+ attr
72
+ };
77
73
  function getOwnUserOptions(schema) {
78
- const meta = schema.meta();
79
- return meta?.[metaKey] ?? {};
74
+ return schema.meta()?.[metaKey] ?? {};
80
75
  }
81
76
  function getUserOptions(schema) {
82
- const own = getOwnUserOptions(schema);
83
- const parentSchema = getParentSchema(schema);
84
- if (!parentSchema) return own;
85
- const parentOptions = getUserOptions(parentSchema);
86
- return { ...parentOptions, ...own };
77
+ const own = getOwnUserOptions(schema);
78
+ const parentSchema = getParentSchema(schema);
79
+ if (!parentSchema) return own;
80
+ return {
81
+ ...getUserOptions(parentSchema),
82
+ ...own
83
+ };
87
84
  }
88
- export {
89
- attr,
90
- getOwnUserOptions,
91
- getUserOptions,
92
- prop,
93
- root,
94
- xml
95
- };
96
- //# sourceMappingURL=schema-meta.js.map
85
+ //#endregion
86
+ export { getUserOptions, root, xml };
87
+
88
+ //# sourceMappingURL=schema-meta.js.map
@@ -1,4 +1,3 @@
1
- import { Options, Element } from 'xml-js';
2
1
  import { z } from 'zod';
3
2
  export declare const ZXMLElementNode: z.ZodObject<{
4
3
  type: z.ZodLiteral<"element">;
@@ -63,13 +62,156 @@ export type XMLRoot = {
63
62
  };
64
63
  type EmptyObj = Record<PropertyKey, never>;
65
64
  export type XMLVoid = EmptyObj;
66
- export type ParseOptions = Omit<Options.XML2JS, "compact">;
65
+ type IgnoreOptions = {
66
+ /** Whether to ignore the XML declaration (`<?xml?>`). @default false */
67
+ ignoreDeclaration?: boolean;
68
+ /** Whether to ignore processing instructions (`<?go there?>`). @default false */
69
+ ignoreInstruction?: boolean;
70
+ /** Whether to ignore element attributes. @default false */
71
+ ignoreAttributes?: boolean;
72
+ /** Whether to ignore comments (`<!-- -->`). @default false */
73
+ ignoreComment?: boolean;
74
+ /** Whether to ignore CData sections (`<![CDATA[ ]]>`). @default false */
75
+ ignoreCdata?: boolean;
76
+ /** Whether to ignore DOCTYPE declarations. @default false */
77
+ ignoreDoctype?: boolean;
78
+ /** Whether to ignore text content inside elements. @default false */
79
+ ignoreText?: boolean;
80
+ };
81
+ type ChangingKeyNames = {
82
+ /** Override the key name used for the declaration property. @default "declaration" */
83
+ declarationKey?: string;
84
+ /** Override the key name used for processing instructions. @default "instruction" */
85
+ instructionKey?: string;
86
+ /** Override the key name used for element attributes. @default "attributes" */
87
+ attributesKey?: string;
88
+ /** Override the key name used for text content. @default "text" */
89
+ textKey?: string;
90
+ /** Override the key name used for CData sections. @default "cdata" */
91
+ cdataKey?: string;
92
+ /** Override the key name used for DOCTYPE. @default "doctype" */
93
+ doctypeKey?: string;
94
+ /** Override the key name used for comments. @default "comment" */
95
+ commentKey?: string;
96
+ /** Override the key name used for the parent back-reference (when `addParent` is enabled). @default "parent" */
97
+ parentKey?: string;
98
+ /** Override the key name used for node type. @default "type" */
99
+ typeKey?: string;
100
+ /** Override the key name used for element name. @default "name" */
101
+ nameKey?: string;
102
+ /** Override the key name used for child elements array. @default "elements" */
103
+ elementsKey?: string;
104
+ };
105
+ /** Options for parsing XML into a JS object tree. */
106
+ export type ParseOptions = IgnoreOptions & ChangingKeyNames & {
107
+ /** Whether to trim whitespace surrounding text content. @default false */
108
+ trim?: boolean;
109
+ /**
110
+ * Whether to replace `&`, `<`, `>` with their XML entities in text nodes.
111
+ * @deprecated See https://github.com/nashwaan/xml-js/issues/26
112
+ * @default false
113
+ */
114
+ sanitize?: boolean;
115
+ /** Whether to coerce numeric and boolean text values to their native JS types. @default false */
116
+ nativeType?: boolean;
117
+ /**
118
+ * Whether to add a `parent` property on each element pointing back to its parent.
119
+ * Useful for upward traversal but creates circular references.
120
+ * @default false
121
+ */
122
+ addParent?: boolean;
123
+ /**
124
+ * Whether to always wrap sub-elements in an array, even when there is only one.
125
+ * Pass an array of element names to restrict this behaviour to those names only.
126
+ * Only applicable in compact mode.
127
+ * @default false
128
+ */
129
+ alwaysArray?: boolean | Array<string>;
130
+ /**
131
+ * Whether to always emit an `elements` array even on empty elements.
132
+ * `<a></a>` becomes `{ elements: [{ type: "element", name: "a", elements: [] }] }`
133
+ * instead of `{ elements: [{ type: "element", name: "a" }] }`.
134
+ * Only applicable in non-compact mode.
135
+ * @default false
136
+ */
137
+ alwaysChildren?: boolean;
138
+ /**
139
+ * Whether to parse the contents of processing instructions as attributes.
140
+ * `<?go to="there"?>` becomes `{ go: { attributes: { to: "there" } } }`
141
+ * instead of `{ go: 'to="there"' }`.
142
+ * @default false
143
+ */
144
+ instructionHasAttributes?: boolean;
145
+ /** Whether to preserve whitespace-only text nodes that appear between elements. @default false */
146
+ captureSpacesBetweenElements?: boolean;
147
+ /** Custom processing hook called for each DOCTYPE value. */
148
+ doctypeFn?: (value: string, parentElement: object) => void;
149
+ /** Custom processing hook called for each processing instruction value. */
150
+ instructionFn?: (instructionValue: string, instructionName: string, parentElement: string) => void;
151
+ /** Custom processing hook called for each CData section. */
152
+ cdataFn?: (value: string, parentElement: object) => void;
153
+ /** Custom processing hook called for each comment. */
154
+ commentFn?: (value: string, parentElement: object) => void;
155
+ /** Custom processing hook called for each text node. */
156
+ textFn?: (value: string, parentElement: object) => void;
157
+ /** Custom processing hook called for each processing instruction name. */
158
+ instructionNameFn?: (instructionName: string, instructionValue: string, parentElement: string) => void;
159
+ /** Custom processing hook called for each element name. */
160
+ elementNameFn?: (value: string, parentElement: object) => void;
161
+ /** Custom processing hook called for each attribute name. */
162
+ attributeNameFn?: (attributeName: string, attributeValue: string, parentElement: string) => void;
163
+ /** Custom processing hook called for each attribute value. */
164
+ attributeValueFn?: (attributeValue: string, attributeName: string, parentElement: string) => void;
165
+ /** Custom processing hook called for the whole attributes object of an element. */
166
+ attributesFn?: (value: string, parentElement: string) => void;
167
+ };
67
168
  declare function parse(xml: string, options?: ParseOptions): XMLRoot;
68
- export type StringifyOptions = Options.JS2XML;
169
+ /** Options for serializing a JS object tree back to XML. */
170
+ export type StringifyOptions = IgnoreOptions & ChangingKeyNames & {
171
+ /** Number of spaces (or a string like `'\t'`) to use for indenting XML output. @default 0 */
172
+ spaces?: number | string;
173
+ /** Whether to indent text nodes onto their own line when `spaces` is set. @default false */
174
+ indentText?: boolean;
175
+ /** Whether to write CData sections on a new indented line. @default false */
176
+ indentCdata?: boolean;
177
+ /** Whether to print each attribute on its own indented line (when `spaces` is set). @default false */
178
+ indentAttributes?: boolean;
179
+ /** Whether to indent processing instructions onto their own line. @default false */
180
+ indentInstruction?: boolean;
181
+ /** Whether to emit empty elements as full tag pairs (`<a></a>`) instead of self-closing (`<a/>`). @default false */
182
+ fullTagEmptyElement?: boolean;
183
+ /** Whether to omit quotes around attribute values that are native JS types (numbers, booleans). @default false */
184
+ noQuotesForNativeAttributes?: boolean;
185
+ /** Custom processing hook called for each DOCTYPE value. */
186
+ doctypeFn?: (value: string, currentElementName: string, currentElementObj: object) => void;
187
+ /** Custom processing hook called for each processing instruction value. */
188
+ instructionFn?: (instructionValue: string, instructionName: string, currentElementName: string, currentElementObj: object) => void;
189
+ /** Custom processing hook called for each CData section. */
190
+ cdataFn?: (value: string, currentElementName: string, currentElementObj: object) => void;
191
+ /** Custom processing hook called for each comment. */
192
+ commentFn?: (value: string, currentElementName: string, currentElementObj: object) => void;
193
+ /** Custom processing hook called for each text node. */
194
+ textFn?: (value: string, currentElementName: string, currentElementObj: object) => void;
195
+ /** Custom processing hook called for each processing instruction name. */
196
+ instructionNameFn?: (instructionName: string, instructionValue: string, currentElementName: string, currentElementObj: object) => void;
197
+ /** Custom processing hook called for each element name. */
198
+ elementNameFn?: (value: string, currentElementName: string, currentElementObj: object) => void;
199
+ /** Custom processing hook called for each attribute name. */
200
+ attributeNameFn?: (attributeName: string, attributeValue: string, currentElementName: string, currentElementObj: object) => void;
201
+ /** Custom processing hook called for each attribute value. */
202
+ attributeValueFn?: (attributeValue: string, attributeName: string, currentElementName: string, currentElementObj: object) => void;
203
+ /** Custom processing hook called for the whole attributes object of an element. */
204
+ attributesFn?: (value: string, currentElementName: string, currentElementObj: object) => void;
205
+ /**
206
+ * Per-element override for `fullTagEmptyElement`.
207
+ * Return `true` to emit a full tag pair for the given element, `false` for self-closing.
208
+ */
209
+ fullTagEmptyElementFn?: (currentElementName: string, currentElementObj: object) => void;
210
+ };
69
211
  declare function stringify(xml: XMLRoot, options?: StringifyOptions): string;
70
- declare function isRoot(xml: Element): xml is XMLRoot;
212
+ declare function isRoot(xml: object): xml is XMLRoot;
71
213
  declare function elementFromRoot(root: XMLRoot): XMLElementNode | undefined;
72
- declare function isEmpty(xml: Element): xml is XMLVoid;
214
+ declare function isEmpty(xml: object): xml is XMLVoid;
73
215
  /**
74
216
  * Extracts the text content from an element that has a single text child node.
75
217
  *
@@ -1,93 +1,122 @@
1
- import { xml2js, js2xml } from "xml-js";
1
+ import { require_lib } from "../node_modules/xml-js/lib/index.js";
2
2
  import { z } from "zod";
3
- const ZXMLElementNode = z.object({
4
- type: z.literal("element"),
5
- // TODO: test if required
6
- name: z.string(),
7
- attributes: z.record(z.string(), z.string()).optional(),
8
- get elements() {
9
- return z.array(ZXMLNode).optional();
10
- }
11
- // TODO: other fields
3
+ //#region src/xml/xml-js.ts
4
+ var import_lib = require_lib();
5
+ var ZXMLElementNode = z.object({
6
+ type: z.literal("element"),
7
+ name: z.string(),
8
+ attributes: z.record(z.string(), z.string()).optional(),
9
+ get elements() {
10
+ return z.array(ZXMLNode).optional();
11
+ }
12
12
  });
13
- const ZXMLCommentNode = z.object({ type: z.literal("comment"), comment: z.string() });
14
- const ZXMLTextNode = z.object({ type: z.literal("text"), text: z.string() });
15
- const ZXMLNode = z.discriminatedUnion("type", [ZXMLElementNode, ZXMLCommentNode, ZXMLTextNode]);
16
- const ZXMLRoot = z.object({ elements: z.array(ZXMLNode) });
13
+ var ZXMLCommentNode = z.object({
14
+ type: z.literal("comment"),
15
+ comment: z.string()
16
+ });
17
+ var ZXMLTextNode = z.object({
18
+ type: z.literal("text"),
19
+ text: z.string()
20
+ });
21
+ var ZXMLNode = z.discriminatedUnion("type", [
22
+ ZXMLElementNode,
23
+ ZXMLCommentNode,
24
+ ZXMLTextNode
25
+ ]);
26
+ var ZXMLRoot = z.object({ elements: z.array(ZXMLNode) });
17
27
  function parse(xml, options = {}) {
18
- const strippedOptions = { ...options };
19
- delete strippedOptions["compact"];
20
- const res = xml2js(xml, strippedOptions);
21
- if ("elements" in res) return res;
22
- throw new Error("Got empty XML");
28
+ const strippedOptions = { ...options };
29
+ delete strippedOptions["compact"];
30
+ const res = (0, import_lib.xml2js)(xml, strippedOptions);
31
+ if ("elements" in res) return res;
32
+ throw new Error("Got empty XML");
23
33
  }
24
34
  function stringify(xml, options = {}) {
25
- return js2xml(xml, options);
35
+ return (0, import_lib.js2xml)(xml, options);
26
36
  }
27
37
  function isRoot(xml) {
28
- const keys = Object.keys(xml);
29
- return keys.length === 1 && Array.isArray(xml.elements);
38
+ return Object.keys(xml).length === 1 && "elements" in xml && Array.isArray(xml.elements);
30
39
  }
31
40
  function elementFromRoot(root) {
32
- return root.elements.find((el) => el.type === "element");
41
+ return root.elements.find((el) => el.type === "element");
33
42
  }
34
43
  function isEmpty(xml) {
35
- return Object.keys(xml).length === 0;
44
+ return Object.keys(xml).length === 0;
36
45
  }
46
+ /**
47
+ * Extracts the text content from an element that has a single text child node.
48
+ *
49
+ * @param xml - An `XMLElement` expected to contain a single text node.
50
+ * @returns The text value, or an empty string when there are no child elements.
51
+ * @throws {TypeError} When the element has multiple or non-text children.
52
+ */
37
53
  function getContent(xml) {
38
- if (xml.elements?.length === 1) {
39
- const content = xml.elements[0];
40
- if (content.type === "text") return content.text;
41
- }
42
- if (!xml.elements) return "";
43
- throw new TypeError(`can't get text from XMLElement: ${JSON.stringify(xml)}`);
54
+ if (xml.elements?.length === 1) {
55
+ const content = xml.elements[0];
56
+ if (content.type === "text") return content.text;
57
+ }
58
+ if (!xml.elements) return "";
59
+ throw new TypeError(`can't get text from XMLElement: ${JSON.stringify(xml)}`);
44
60
  }
45
61
  function fromContent(content = "", tag, attributes) {
46
- const elements = content ? [{ type: "text", text: String(content) }] : [];
47
- if (!tag) {
48
- return { elements };
49
- }
50
- const el = {
51
- type: "element",
52
- name: tag,
53
- elements
54
- };
55
- if (attributes) {
56
- el.attributes = attributes;
57
- }
58
- return el;
62
+ const elements = content ? [{
63
+ type: "text",
64
+ text: String(content)
65
+ }] : [];
66
+ if (!tag) return { elements };
67
+ const el = {
68
+ type: "element",
69
+ name: tag,
70
+ elements
71
+ };
72
+ if (attributes) el.attributes = attributes;
73
+ return el;
59
74
  }
75
+ /**
76
+ * Appends a child element to `xml`, initialising the `elements` array if needed.
77
+ *
78
+ * @param xml - The parent element to modify.
79
+ * @param element - The child element to append.
80
+ */
60
81
  function addElement(xml, element) {
61
- if (!xml.elements) xml.elements = [];
62
- xml.elements.push(element);
82
+ if (!xml.elements) xml.elements = [];
83
+ xml.elements.push(element);
63
84
  }
85
+ /**
86
+ * Sets an attribute on an element, initialising the `attributes` map if needed.
87
+ *
88
+ * @param xml - The element to modify.
89
+ * @param attribute - The attribute name.
90
+ * @param value - The attribute value.
91
+ */
64
92
  function setAttribute(xml, attribute, value) {
65
- if (!xml.attributes) xml.attributes = {};
66
- xml.attributes[attribute] = value;
93
+ if (!xml.attributes) xml.attributes = {};
94
+ xml.attributes[attribute] = value;
67
95
  }
96
+ /**
97
+ * Removes an attribute from an element. Does nothing if the element has no attributes.
98
+ *
99
+ * @param xml - The element to modify.
100
+ * @param attribute - The attribute name to remove.
101
+ */
68
102
  function deleteAttribute(xml, attribute) {
69
- if (!xml.attributes) return;
70
- delete xml.attributes[attribute];
103
+ if (!xml.attributes) return;
104
+ delete xml.attributes[attribute];
71
105
  }
72
- const XML = {
73
- parse,
74
- stringify,
75
- isRoot,
76
- elementFromRoot,
77
- isEmpty,
78
- fromContent,
79
- getContent,
80
- addElement,
81
- setAttribute,
82
- deleteAttribute
83
- };
84
- export {
85
- XML,
86
- ZXMLCommentNode,
87
- ZXMLElementNode,
88
- ZXMLNode,
89
- ZXMLRoot,
90
- ZXMLTextNode,
91
- XML as default
106
+ /** Namespace object bundling all XML utility functions. */
107
+ var XML = {
108
+ parse,
109
+ stringify,
110
+ isRoot,
111
+ elementFromRoot,
112
+ isEmpty,
113
+ fromContent,
114
+ getContent,
115
+ addElement,
116
+ setAttribute,
117
+ deleteAttribute
92
118
  };
93
- //# sourceMappingURL=xml-js.js.map
119
+ //#endregion
120
+ export { ZXMLCommentNode, ZXMLElementNode, ZXMLNode, ZXMLRoot, ZXMLTextNode, XML as default };
121
+
122
+ //# sourceMappingURL=xml-js.js.map