@abapify/ts-xsd 0.4.0 → 0.4.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/README.md +143 -211
- package/dist/codegen/cli.d.mts +1 -0
- package/dist/codegen/cli.mjs +137 -0
- package/dist/codegen/cli.mjs.map +1 -0
- package/dist/generate-Br6rW6sE.mjs +262 -0
- package/dist/generate-Br6rW6sE.mjs.map +1 -0
- package/dist/generators/index.d.mts +197 -0
- package/dist/generators/index.d.mts.map +1 -0
- package/dist/generators/index.mjs +635 -0
- package/dist/generators/index.mjs.map +1 -0
- package/dist/index.d.mts +1193 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +1923 -0
- package/dist/index.mjs.map +1 -0
- package/dist/runner-BSGqj8LM.mjs +1822 -0
- package/dist/runner-BSGqj8LM.mjs.map +1 -0
- package/dist/runner-D1RCU_go.d.mts +741 -0
- package/dist/runner-D1RCU_go.d.mts.map +1 -0
- package/dist/types-Ch0GQQ5n.mjs +527 -0
- package/dist/types-Ch0GQQ5n.mjs.map +1 -0
- package/package.json +2 -2
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,1923 @@
|
|
|
1
|
+
import { _ as getLocalName, a as loadAndLinkSchema, c as getSubstitutes, d as SchemaTraverser, f as resolveSchemaTypes, g as getChildElements, h as getAttributeValue, i as linkSchema, l as resolveSchema, m as getAllChildElements, n as createSchemaLoader, o as loadSchema, p as parseXsd, r as defaultLoader, s as parseSchemaContent, t as runCodegen, u as SchemaResolver, v as getTextContent } from "./runner-BSGqj8LM.mjs";
|
|
2
|
+
import { n as generateSchemaLiteral, t as generateSchemaFile } from "./generate-Br6rW6sE.mjs";
|
|
3
|
+
import { n as deriveRootTypeName, r as generateInterfaces, t as defineConfig } from "./types-Ch0GQQ5n.mjs";
|
|
4
|
+
import { DOMImplementation, DOMParser, XMLSerializer } from "@xmldom/xmldom";
|
|
5
|
+
|
|
6
|
+
//#region src/xsd/build.ts
|
|
7
|
+
/**
|
|
8
|
+
* Build an XSD string from a typed Schema object
|
|
9
|
+
*/
|
|
10
|
+
function buildXsd(schema, options = {}) {
|
|
11
|
+
const prefix = options.prefix ?? "xs";
|
|
12
|
+
const pretty = options.pretty ?? true;
|
|
13
|
+
const ctx = {
|
|
14
|
+
prefix,
|
|
15
|
+
pretty,
|
|
16
|
+
indent: options.indent ?? " ",
|
|
17
|
+
level: 0
|
|
18
|
+
};
|
|
19
|
+
const lines = [];
|
|
20
|
+
lines.push("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
|
21
|
+
lines.push(buildSchema(schema, ctx));
|
|
22
|
+
return lines.join(pretty ? "\n" : "");
|
|
23
|
+
}
|
|
24
|
+
function buildSchema(schema, ctx) {
|
|
25
|
+
const attrs = [];
|
|
26
|
+
if (schema.$xmlns) for (const [prefix, uri] of Object.entries(schema.$xmlns)) if (prefix === "") attrs.push(`xmlns="${uri}"`);
|
|
27
|
+
else attrs.push(`xmlns:${prefix}="${uri}"`);
|
|
28
|
+
addAttr(attrs, "id", schema.id);
|
|
29
|
+
addAttr(attrs, "targetNamespace", schema.targetNamespace);
|
|
30
|
+
addAttr(attrs, "version", schema.version);
|
|
31
|
+
addAttr(attrs, "finalDefault", schema.finalDefault);
|
|
32
|
+
addAttr(attrs, "blockDefault", schema.blockDefault);
|
|
33
|
+
addAttr(attrs, "attributeFormDefault", schema.attributeFormDefault);
|
|
34
|
+
addAttr(attrs, "elementFormDefault", schema.elementFormDefault);
|
|
35
|
+
addAttr(attrs, "defaultAttributes", schema.defaultAttributes);
|
|
36
|
+
addAttr(attrs, "xpathDefaultNamespace", schema.xpathDefaultNamespace);
|
|
37
|
+
addAttr(attrs, "xml:lang", schema["xml:lang"]);
|
|
38
|
+
const children = [];
|
|
39
|
+
const childCtx = {
|
|
40
|
+
...ctx,
|
|
41
|
+
level: ctx.level + 1
|
|
42
|
+
};
|
|
43
|
+
if (schema.annotation) for (const ann of schema.annotation) children.push(buildAnnotation(ann, childCtx));
|
|
44
|
+
if (schema.include) for (const inc of schema.include) children.push(buildInclude(inc, childCtx));
|
|
45
|
+
if (schema.import) for (const imp of schema.import) children.push(buildImport(imp, childCtx));
|
|
46
|
+
if (schema.redefine) for (const red of schema.redefine) children.push(buildRedefine(red, childCtx));
|
|
47
|
+
if (schema.override) for (const ovr of schema.override) children.push(buildOverride(ovr, childCtx));
|
|
48
|
+
if (schema.defaultOpenContent) children.push(buildDefaultOpenContent(schema.defaultOpenContent, childCtx));
|
|
49
|
+
if (schema.simpleType && Array.isArray(schema.simpleType)) for (const st of schema.simpleType) children.push(buildTopLevelSimpleType(st, childCtx));
|
|
50
|
+
if (schema.complexType && Array.isArray(schema.complexType)) for (const ct of schema.complexType) children.push(buildTopLevelComplexType(ct, childCtx));
|
|
51
|
+
if (schema.group) for (const grp of schema.group) children.push(buildNamedGroup(grp, childCtx));
|
|
52
|
+
if (schema.attributeGroup) for (const ag of schema.attributeGroup) children.push(buildNamedAttributeGroup(ag, childCtx));
|
|
53
|
+
if (schema.element) for (const el of schema.element) children.push(buildTopLevelElement(el, childCtx));
|
|
54
|
+
if (schema.attribute) for (const attr of schema.attribute) children.push(buildTopLevelAttribute(attr, childCtx));
|
|
55
|
+
if (schema.notation) for (const not of schema.notation) children.push(buildNotation(not, childCtx));
|
|
56
|
+
return buildElement$1(`${ctx.prefix}:schema`, attrs, children, ctx);
|
|
57
|
+
}
|
|
58
|
+
function buildAnnotation(ann, ctx) {
|
|
59
|
+
const attrs = [];
|
|
60
|
+
addAttr(attrs, "id", ann.id);
|
|
61
|
+
const children = [];
|
|
62
|
+
const childCtx = {
|
|
63
|
+
...ctx,
|
|
64
|
+
level: ctx.level + 1
|
|
65
|
+
};
|
|
66
|
+
if (ann.appinfo) for (const ai of ann.appinfo) children.push(buildAppinfo(ai, childCtx));
|
|
67
|
+
if (ann.documentation) for (const doc of ann.documentation) children.push(buildDocumentation(doc, childCtx));
|
|
68
|
+
return buildElement$1(`${ctx.prefix}:annotation`, attrs, children, ctx);
|
|
69
|
+
}
|
|
70
|
+
function buildDocumentation(doc, ctx) {
|
|
71
|
+
const attrs = [];
|
|
72
|
+
addAttr(attrs, "source", doc.source);
|
|
73
|
+
addAttr(attrs, "xml:lang", doc["xml:lang"]);
|
|
74
|
+
if (doc._text) return buildElementWithText(`${ctx.prefix}:documentation`, attrs, doc._text, ctx);
|
|
75
|
+
return buildElement$1(`${ctx.prefix}:documentation`, attrs, [], ctx);
|
|
76
|
+
}
|
|
77
|
+
function buildAppinfo(ai, ctx) {
|
|
78
|
+
const attrs = [];
|
|
79
|
+
addAttr(attrs, "source", ai.source);
|
|
80
|
+
if (ai._text) return buildElementWithText(`${ctx.prefix}:appinfo`, attrs, ai._text, ctx);
|
|
81
|
+
return buildElement$1(`${ctx.prefix}:appinfo`, attrs, [], ctx);
|
|
82
|
+
}
|
|
83
|
+
function buildInclude(inc, ctx) {
|
|
84
|
+
const attrs = [];
|
|
85
|
+
addAttr(attrs, "id", inc.id);
|
|
86
|
+
addAttr(attrs, "schemaLocation", inc.schemaLocation);
|
|
87
|
+
const children = [];
|
|
88
|
+
if (inc.annotation) children.push(buildAnnotation(inc.annotation, {
|
|
89
|
+
...ctx,
|
|
90
|
+
level: ctx.level + 1
|
|
91
|
+
}));
|
|
92
|
+
return buildElement$1(`${ctx.prefix}:include`, attrs, children, ctx);
|
|
93
|
+
}
|
|
94
|
+
function buildImport(imp, ctx) {
|
|
95
|
+
const attrs = [];
|
|
96
|
+
addAttr(attrs, "id", imp.id);
|
|
97
|
+
addAttr(attrs, "namespace", imp.namespace);
|
|
98
|
+
addAttr(attrs, "schemaLocation", imp.schemaLocation);
|
|
99
|
+
const children = [];
|
|
100
|
+
if (imp.annotation) children.push(buildAnnotation(imp.annotation, {
|
|
101
|
+
...ctx,
|
|
102
|
+
level: ctx.level + 1
|
|
103
|
+
}));
|
|
104
|
+
return buildElement$1(`${ctx.prefix}:import`, attrs, children, ctx);
|
|
105
|
+
}
|
|
106
|
+
function buildRedefine(red, ctx) {
|
|
107
|
+
const attrs = [];
|
|
108
|
+
addAttr(attrs, "id", red.id);
|
|
109
|
+
addAttr(attrs, "schemaLocation", red.schemaLocation);
|
|
110
|
+
const children = [];
|
|
111
|
+
const childCtx = {
|
|
112
|
+
...ctx,
|
|
113
|
+
level: ctx.level + 1
|
|
114
|
+
};
|
|
115
|
+
if (red.annotation) for (const ann of red.annotation) children.push(buildAnnotation(ann, childCtx));
|
|
116
|
+
if (red.simpleType) for (const st of red.simpleType) children.push(buildTopLevelSimpleType(st, childCtx));
|
|
117
|
+
if (red.complexType) for (const ct of red.complexType) children.push(buildTopLevelComplexType(ct, childCtx));
|
|
118
|
+
if (red.group) for (const grp of red.group) children.push(buildNamedGroup(grp, childCtx));
|
|
119
|
+
if (red.attributeGroup) for (const ag of red.attributeGroup) children.push(buildNamedAttributeGroup(ag, childCtx));
|
|
120
|
+
return buildElement$1(`${ctx.prefix}:redefine`, attrs, children, ctx);
|
|
121
|
+
}
|
|
122
|
+
function buildOverride(ovr, ctx) {
|
|
123
|
+
const attrs = [];
|
|
124
|
+
addAttr(attrs, "id", ovr.id);
|
|
125
|
+
addAttr(attrs, "schemaLocation", ovr.schemaLocation);
|
|
126
|
+
const children = [];
|
|
127
|
+
const childCtx = {
|
|
128
|
+
...ctx,
|
|
129
|
+
level: ctx.level + 1
|
|
130
|
+
};
|
|
131
|
+
if (ovr.annotation) for (const ann of ovr.annotation) children.push(buildAnnotation(ann, childCtx));
|
|
132
|
+
if (ovr.simpleType) for (const st of ovr.simpleType) children.push(buildTopLevelSimpleType(st, childCtx));
|
|
133
|
+
if (ovr.complexType) for (const ct of ovr.complexType) children.push(buildTopLevelComplexType(ct, childCtx));
|
|
134
|
+
if (ovr.group) for (const grp of ovr.group) children.push(buildNamedGroup(grp, childCtx));
|
|
135
|
+
if (ovr.attributeGroup) for (const ag of ovr.attributeGroup) children.push(buildNamedAttributeGroup(ag, childCtx));
|
|
136
|
+
if (ovr.element) for (const el of ovr.element) children.push(buildTopLevelElement(el, childCtx));
|
|
137
|
+
if (ovr.attribute) for (const attr of ovr.attribute) children.push(buildTopLevelAttribute(attr, childCtx));
|
|
138
|
+
if (ovr.notation) for (const not of ovr.notation) children.push(buildNotation(not, childCtx));
|
|
139
|
+
return buildElement$1(`${ctx.prefix}:override`, attrs, children, ctx);
|
|
140
|
+
}
|
|
141
|
+
function buildTopLevelElement(el, ctx) {
|
|
142
|
+
const attrs = [];
|
|
143
|
+
addAttr(attrs, "id", el.id);
|
|
144
|
+
addAttr(attrs, "name", el.name);
|
|
145
|
+
addAttr(attrs, "type", el.type);
|
|
146
|
+
addAttr(attrs, "substitutionGroup", el.substitutionGroup);
|
|
147
|
+
addAttr(attrs, "default", el.default);
|
|
148
|
+
addAttr(attrs, "fixed", el.fixed);
|
|
149
|
+
addBoolAttr(attrs, "nillable", el.nillable);
|
|
150
|
+
addBoolAttr(attrs, "abstract", el.abstract);
|
|
151
|
+
addAttr(attrs, "final", el.final);
|
|
152
|
+
addAttr(attrs, "block", el.block);
|
|
153
|
+
const children = [];
|
|
154
|
+
const childCtx = {
|
|
155
|
+
...ctx,
|
|
156
|
+
level: ctx.level + 1
|
|
157
|
+
};
|
|
158
|
+
if (el.annotation) children.push(buildAnnotation(el.annotation, childCtx));
|
|
159
|
+
if (el.simpleType) children.push(buildLocalSimpleType(el.simpleType, childCtx));
|
|
160
|
+
if (el.complexType) children.push(buildLocalComplexType(el.complexType, childCtx));
|
|
161
|
+
if (el.alternative) for (const alt of el.alternative) children.push(buildAlternative(alt, childCtx));
|
|
162
|
+
if (el.unique) for (const u of el.unique) children.push(buildUnique(u, childCtx));
|
|
163
|
+
if (el.key) for (const k of el.key) children.push(buildKey(k, childCtx));
|
|
164
|
+
if (el.keyref) for (const kr of el.keyref) children.push(buildKeyref(kr, childCtx));
|
|
165
|
+
return buildElement$1(`${ctx.prefix}:element`, attrs, children, ctx);
|
|
166
|
+
}
|
|
167
|
+
function buildLocalElement(el, ctx) {
|
|
168
|
+
const attrs = [];
|
|
169
|
+
addAttr(attrs, "id", el.id);
|
|
170
|
+
addAttr(attrs, "name", el.name);
|
|
171
|
+
addAttr(attrs, "ref", el.ref);
|
|
172
|
+
addAttr(attrs, "type", el.type);
|
|
173
|
+
addOccursAttr(attrs, "minOccurs", el.minOccurs);
|
|
174
|
+
addOccursAttr(attrs, "maxOccurs", el.maxOccurs);
|
|
175
|
+
addAttr(attrs, "default", el.default);
|
|
176
|
+
addAttr(attrs, "fixed", el.fixed);
|
|
177
|
+
addBoolAttr(attrs, "nillable", el.nillable);
|
|
178
|
+
addAttr(attrs, "block", el.block);
|
|
179
|
+
addAttr(attrs, "form", el.form);
|
|
180
|
+
addAttr(attrs, "targetNamespace", el.targetNamespace);
|
|
181
|
+
const children = [];
|
|
182
|
+
const childCtx = {
|
|
183
|
+
...ctx,
|
|
184
|
+
level: ctx.level + 1
|
|
185
|
+
};
|
|
186
|
+
if (el.annotation) children.push(buildAnnotation(el.annotation, childCtx));
|
|
187
|
+
if (el.simpleType) children.push(buildLocalSimpleType(el.simpleType, childCtx));
|
|
188
|
+
if (el.complexType) children.push(buildLocalComplexType(el.complexType, childCtx));
|
|
189
|
+
if (el.alternative) for (const alt of el.alternative) children.push(buildAlternative(alt, childCtx));
|
|
190
|
+
if (el.unique) for (const u of el.unique) children.push(buildUnique(u, childCtx));
|
|
191
|
+
if (el.key) for (const k of el.key) children.push(buildKey(k, childCtx));
|
|
192
|
+
if (el.keyref) for (const kr of el.keyref) children.push(buildKeyref(kr, childCtx));
|
|
193
|
+
return buildElement$1(`${ctx.prefix}:element`, attrs, children, ctx);
|
|
194
|
+
}
|
|
195
|
+
function buildTopLevelAttribute(attr, ctx) {
|
|
196
|
+
const attrs = [];
|
|
197
|
+
addAttr(attrs, "id", attr.id);
|
|
198
|
+
addAttr(attrs, "name", attr.name);
|
|
199
|
+
addAttr(attrs, "type", attr.type);
|
|
200
|
+
addAttr(attrs, "default", attr.default);
|
|
201
|
+
addAttr(attrs, "fixed", attr.fixed);
|
|
202
|
+
addBoolAttr(attrs, "inheritable", attr.inheritable);
|
|
203
|
+
const children = [];
|
|
204
|
+
const childCtx = {
|
|
205
|
+
...ctx,
|
|
206
|
+
level: ctx.level + 1
|
|
207
|
+
};
|
|
208
|
+
if (attr.annotation) children.push(buildAnnotation(attr.annotation, childCtx));
|
|
209
|
+
if (attr.simpleType) children.push(buildLocalSimpleType(attr.simpleType, childCtx));
|
|
210
|
+
return buildElement$1(`${ctx.prefix}:attribute`, attrs, children, ctx);
|
|
211
|
+
}
|
|
212
|
+
function buildLocalAttribute(attr, ctx) {
|
|
213
|
+
const attrs = [];
|
|
214
|
+
addAttr(attrs, "id", attr.id);
|
|
215
|
+
addAttr(attrs, "name", attr.name);
|
|
216
|
+
addAttr(attrs, "ref", attr.ref);
|
|
217
|
+
addAttr(attrs, "type", attr.type);
|
|
218
|
+
addAttr(attrs, "use", attr.use);
|
|
219
|
+
addAttr(attrs, "default", attr.default);
|
|
220
|
+
addAttr(attrs, "fixed", attr.fixed);
|
|
221
|
+
addAttr(attrs, "form", attr.form);
|
|
222
|
+
addAttr(attrs, "targetNamespace", attr.targetNamespace);
|
|
223
|
+
addBoolAttr(attrs, "inheritable", attr.inheritable);
|
|
224
|
+
const children = [];
|
|
225
|
+
const childCtx = {
|
|
226
|
+
...ctx,
|
|
227
|
+
level: ctx.level + 1
|
|
228
|
+
};
|
|
229
|
+
if (attr.annotation) children.push(buildAnnotation(attr.annotation, childCtx));
|
|
230
|
+
if (attr.simpleType) children.push(buildLocalSimpleType(attr.simpleType, childCtx));
|
|
231
|
+
return buildElement$1(`${ctx.prefix}:attribute`, attrs, children, ctx);
|
|
232
|
+
}
|
|
233
|
+
function buildTopLevelComplexType(ct, ctx) {
|
|
234
|
+
const attrs = [];
|
|
235
|
+
addAttr(attrs, "id", ct.id);
|
|
236
|
+
addAttr(attrs, "name", ct.name);
|
|
237
|
+
addBoolAttr(attrs, "mixed", ct.mixed);
|
|
238
|
+
addBoolAttr(attrs, "abstract", ct.abstract);
|
|
239
|
+
addAttr(attrs, "final", ct.final);
|
|
240
|
+
addAttr(attrs, "block", ct.block);
|
|
241
|
+
addBoolAttr(attrs, "defaultAttributesApply", ct.defaultAttributesApply);
|
|
242
|
+
return buildComplexTypeContent(ct, attrs, ctx);
|
|
243
|
+
}
|
|
244
|
+
function buildLocalComplexType(ct, ctx) {
|
|
245
|
+
const attrs = [];
|
|
246
|
+
addAttr(attrs, "id", ct.id);
|
|
247
|
+
addBoolAttr(attrs, "mixed", ct.mixed);
|
|
248
|
+
return buildComplexTypeContent(ct, attrs, ctx);
|
|
249
|
+
}
|
|
250
|
+
function buildComplexTypeContent(ct, attrs, ctx) {
|
|
251
|
+
const children = [];
|
|
252
|
+
const childCtx = {
|
|
253
|
+
...ctx,
|
|
254
|
+
level: ctx.level + 1
|
|
255
|
+
};
|
|
256
|
+
if (ct.annotation) children.push(buildAnnotation(ct.annotation, childCtx));
|
|
257
|
+
if (ct.simpleContent) children.push(buildSimpleContent(ct.simpleContent, childCtx));
|
|
258
|
+
else if (ct.complexContent) children.push(buildComplexContent(ct.complexContent, childCtx));
|
|
259
|
+
else {
|
|
260
|
+
if (ct.openContent) children.push(buildOpenContent(ct.openContent, childCtx));
|
|
261
|
+
if (ct.group) children.push(buildGroupRef(ct.group, childCtx));
|
|
262
|
+
if (ct.all) children.push(buildAll(ct.all, childCtx));
|
|
263
|
+
if (ct.choice) children.push(buildExplicitGroup(ct.choice, "choice", childCtx));
|
|
264
|
+
if (ct.sequence) children.push(buildExplicitGroup(ct.sequence, "sequence", childCtx));
|
|
265
|
+
if (ct.attribute) for (const attr of ct.attribute) children.push(buildLocalAttribute(attr, childCtx));
|
|
266
|
+
if (ct.attributeGroup) for (const ag of ct.attributeGroup) children.push(buildAttributeGroupRef(ag, childCtx));
|
|
267
|
+
if (ct.anyAttribute) children.push(buildAnyAttribute(ct.anyAttribute, childCtx));
|
|
268
|
+
if (ct.assert) for (const a of ct.assert) children.push(buildAssertion(a, childCtx));
|
|
269
|
+
}
|
|
270
|
+
return buildElement$1(`${ctx.prefix}:complexType`, attrs, children, ctx);
|
|
271
|
+
}
|
|
272
|
+
function buildTopLevelSimpleType(st, ctx) {
|
|
273
|
+
const attrs = [];
|
|
274
|
+
addAttr(attrs, "id", st.id);
|
|
275
|
+
addAttr(attrs, "name", st.name);
|
|
276
|
+
addAttr(attrs, "final", st.final);
|
|
277
|
+
return buildSimpleTypeContent(st, attrs, ctx);
|
|
278
|
+
}
|
|
279
|
+
function buildLocalSimpleType(st, ctx) {
|
|
280
|
+
const attrs = [];
|
|
281
|
+
addAttr(attrs, "id", st.id);
|
|
282
|
+
return buildSimpleTypeContent(st, attrs, ctx);
|
|
283
|
+
}
|
|
284
|
+
function buildSimpleTypeContent(st, attrs, ctx) {
|
|
285
|
+
const children = [];
|
|
286
|
+
const childCtx = {
|
|
287
|
+
...ctx,
|
|
288
|
+
level: ctx.level + 1
|
|
289
|
+
};
|
|
290
|
+
if (st.annotation) children.push(buildAnnotation(st.annotation, childCtx));
|
|
291
|
+
if (st.restriction) children.push(buildSimpleTypeRestriction(st.restriction, childCtx));
|
|
292
|
+
else if (st.list) children.push(buildList(st.list, childCtx));
|
|
293
|
+
else if (st.union) children.push(buildUnion(st.union, childCtx));
|
|
294
|
+
return buildElement$1(`${ctx.prefix}:simpleType`, attrs, children, ctx);
|
|
295
|
+
}
|
|
296
|
+
function buildSimpleTypeRestriction(r, ctx) {
|
|
297
|
+
const attrs = [];
|
|
298
|
+
addAttr(attrs, "id", r.id);
|
|
299
|
+
addAttr(attrs, "base", r.base);
|
|
300
|
+
const children = [];
|
|
301
|
+
const childCtx = {
|
|
302
|
+
...ctx,
|
|
303
|
+
level: ctx.level + 1
|
|
304
|
+
};
|
|
305
|
+
if (r.annotation) children.push(buildAnnotation(r.annotation, childCtx));
|
|
306
|
+
if (r.simpleType) children.push(buildLocalSimpleType(r.simpleType, childCtx));
|
|
307
|
+
buildFacets(r, children, childCtx);
|
|
308
|
+
return buildElement$1(`${ctx.prefix}:restriction`, attrs, children, ctx);
|
|
309
|
+
}
|
|
310
|
+
function buildFacets(r, children, ctx) {
|
|
311
|
+
if (r.minExclusive) for (const f of r.minExclusive) children.push(buildFacet(f, "minExclusive", ctx));
|
|
312
|
+
if (r.minInclusive) for (const f of r.minInclusive) children.push(buildFacet(f, "minInclusive", ctx));
|
|
313
|
+
if (r.maxExclusive) for (const f of r.maxExclusive) children.push(buildFacet(f, "maxExclusive", ctx));
|
|
314
|
+
if (r.maxInclusive) for (const f of r.maxInclusive) children.push(buildFacet(f, "maxInclusive", ctx));
|
|
315
|
+
if (r.totalDigits) for (const f of r.totalDigits) children.push(buildFacet(f, "totalDigits", ctx));
|
|
316
|
+
if (r.fractionDigits) for (const f of r.fractionDigits) children.push(buildFacet(f, "fractionDigits", ctx));
|
|
317
|
+
if (r.length) for (const f of r.length) children.push(buildFacet(f, "length", ctx));
|
|
318
|
+
if (r.minLength) for (const f of r.minLength) children.push(buildFacet(f, "minLength", ctx));
|
|
319
|
+
if (r.maxLength) for (const f of r.maxLength) children.push(buildFacet(f, "maxLength", ctx));
|
|
320
|
+
if (r.enumeration) for (const f of r.enumeration) children.push(buildFacet(f, "enumeration", ctx));
|
|
321
|
+
if (r.whiteSpace) for (const f of r.whiteSpace) children.push(buildFacet(f, "whiteSpace", ctx));
|
|
322
|
+
if (r.pattern) for (const p of r.pattern) children.push(buildPattern(p, ctx));
|
|
323
|
+
if (r.assertion) for (const a of r.assertion) children.push(buildAssertion(a, ctx));
|
|
324
|
+
if (r.explicitTimezone) for (const f of r.explicitTimezone) children.push(buildFacet(f, "explicitTimezone", ctx));
|
|
325
|
+
}
|
|
326
|
+
function buildFacet(f, name, ctx) {
|
|
327
|
+
const attrs = [];
|
|
328
|
+
addAttr(attrs, "id", f.id);
|
|
329
|
+
addAttr(attrs, "value", f.value);
|
|
330
|
+
addBoolAttr(attrs, "fixed", f.fixed);
|
|
331
|
+
const children = [];
|
|
332
|
+
if (f.annotation) children.push(buildAnnotation(f.annotation, {
|
|
333
|
+
...ctx,
|
|
334
|
+
level: ctx.level + 1
|
|
335
|
+
}));
|
|
336
|
+
return buildElement$1(`${ctx.prefix}:${name}`, attrs, children, ctx);
|
|
337
|
+
}
|
|
338
|
+
function buildPattern(p, ctx) {
|
|
339
|
+
const attrs = [];
|
|
340
|
+
addAttr(attrs, "id", p.id);
|
|
341
|
+
addAttr(attrs, "value", p.value);
|
|
342
|
+
const children = [];
|
|
343
|
+
if (p.annotation) children.push(buildAnnotation(p.annotation, {
|
|
344
|
+
...ctx,
|
|
345
|
+
level: ctx.level + 1
|
|
346
|
+
}));
|
|
347
|
+
return buildElement$1(`${ctx.prefix}:pattern`, attrs, children, ctx);
|
|
348
|
+
}
|
|
349
|
+
function buildList(l, ctx) {
|
|
350
|
+
const attrs = [];
|
|
351
|
+
addAttr(attrs, "id", l.id);
|
|
352
|
+
addAttr(attrs, "itemType", l.itemType);
|
|
353
|
+
const children = [];
|
|
354
|
+
const childCtx = {
|
|
355
|
+
...ctx,
|
|
356
|
+
level: ctx.level + 1
|
|
357
|
+
};
|
|
358
|
+
if (l.annotation) children.push(buildAnnotation(l.annotation, childCtx));
|
|
359
|
+
if (l.simpleType) children.push(buildLocalSimpleType(l.simpleType, childCtx));
|
|
360
|
+
return buildElement$1(`${ctx.prefix}:list`, attrs, children, ctx);
|
|
361
|
+
}
|
|
362
|
+
function buildUnion(u, ctx) {
|
|
363
|
+
const attrs = [];
|
|
364
|
+
addAttr(attrs, "id", u.id);
|
|
365
|
+
addAttr(attrs, "memberTypes", u.memberTypes);
|
|
366
|
+
const children = [];
|
|
367
|
+
const childCtx = {
|
|
368
|
+
...ctx,
|
|
369
|
+
level: ctx.level + 1
|
|
370
|
+
};
|
|
371
|
+
if (u.annotation) children.push(buildAnnotation(u.annotation, childCtx));
|
|
372
|
+
if (u.simpleType) for (const st of u.simpleType) children.push(buildLocalSimpleType(st, childCtx));
|
|
373
|
+
return buildElement$1(`${ctx.prefix}:union`, attrs, children, ctx);
|
|
374
|
+
}
|
|
375
|
+
function buildComplexContent(cc, ctx) {
|
|
376
|
+
const attrs = [];
|
|
377
|
+
addAttr(attrs, "id", cc.id);
|
|
378
|
+
addBoolAttr(attrs, "mixed", cc.mixed);
|
|
379
|
+
const children = [];
|
|
380
|
+
const childCtx = {
|
|
381
|
+
...ctx,
|
|
382
|
+
level: ctx.level + 1
|
|
383
|
+
};
|
|
384
|
+
if (cc.annotation) children.push(buildAnnotation(cc.annotation, childCtx));
|
|
385
|
+
if (cc.restriction) children.push(buildComplexContentRestriction(cc.restriction, childCtx));
|
|
386
|
+
else if (cc.extension) children.push(buildComplexContentExtension(cc.extension, childCtx));
|
|
387
|
+
return buildElement$1(`${ctx.prefix}:complexContent`, attrs, children, ctx);
|
|
388
|
+
}
|
|
389
|
+
function buildSimpleContent(sc, ctx) {
|
|
390
|
+
const attrs = [];
|
|
391
|
+
addAttr(attrs, "id", sc.id);
|
|
392
|
+
const children = [];
|
|
393
|
+
const childCtx = {
|
|
394
|
+
...ctx,
|
|
395
|
+
level: ctx.level + 1
|
|
396
|
+
};
|
|
397
|
+
if (sc.annotation) children.push(buildAnnotation(sc.annotation, childCtx));
|
|
398
|
+
if (sc.restriction) children.push(buildSimpleContentRestriction(sc.restriction, childCtx));
|
|
399
|
+
else if (sc.extension) children.push(buildSimpleContentExtension(sc.extension, childCtx));
|
|
400
|
+
return buildElement$1(`${ctx.prefix}:simpleContent`, attrs, children, ctx);
|
|
401
|
+
}
|
|
402
|
+
function buildComplexContentRestriction(r, ctx) {
|
|
403
|
+
const attrs = [];
|
|
404
|
+
addAttr(attrs, "id", r.id);
|
|
405
|
+
addAttr(attrs, "base", r.base);
|
|
406
|
+
const children = [];
|
|
407
|
+
const childCtx = {
|
|
408
|
+
...ctx,
|
|
409
|
+
level: ctx.level + 1
|
|
410
|
+
};
|
|
411
|
+
if (r.annotation) children.push(buildAnnotation(r.annotation, childCtx));
|
|
412
|
+
if (r.openContent) children.push(buildOpenContent(r.openContent, childCtx));
|
|
413
|
+
if (r.group) children.push(buildGroupRef(r.group, childCtx));
|
|
414
|
+
if (r.all) children.push(buildAll(r.all, childCtx));
|
|
415
|
+
if (r.choice) children.push(buildExplicitGroup(r.choice, "choice", childCtx));
|
|
416
|
+
if (r.sequence) children.push(buildExplicitGroup(r.sequence, "sequence", childCtx));
|
|
417
|
+
if (r.attribute) for (const attr of r.attribute) children.push(buildLocalAttribute(attr, childCtx));
|
|
418
|
+
if (r.attributeGroup) for (const ag of r.attributeGroup) children.push(buildAttributeGroupRef(ag, childCtx));
|
|
419
|
+
if (r.anyAttribute) children.push(buildAnyAttribute(r.anyAttribute, childCtx));
|
|
420
|
+
if (r.assert) for (const a of r.assert) children.push(buildAssertion(a, childCtx));
|
|
421
|
+
return buildElement$1(`${ctx.prefix}:restriction`, attrs, children, ctx);
|
|
422
|
+
}
|
|
423
|
+
function buildComplexContentExtension(e, ctx) {
|
|
424
|
+
const attrs = [];
|
|
425
|
+
addAttr(attrs, "id", e.id);
|
|
426
|
+
addAttr(attrs, "base", e.base);
|
|
427
|
+
const children = [];
|
|
428
|
+
const childCtx = {
|
|
429
|
+
...ctx,
|
|
430
|
+
level: ctx.level + 1
|
|
431
|
+
};
|
|
432
|
+
if (e.annotation) children.push(buildAnnotation(e.annotation, childCtx));
|
|
433
|
+
if (e.openContent) children.push(buildOpenContent(e.openContent, childCtx));
|
|
434
|
+
if (e.group) children.push(buildGroupRef(e.group, childCtx));
|
|
435
|
+
if (e.all) children.push(buildAll(e.all, childCtx));
|
|
436
|
+
if (e.choice) children.push(buildExplicitGroup(e.choice, "choice", childCtx));
|
|
437
|
+
if (e.sequence) children.push(buildExplicitGroup(e.sequence, "sequence", childCtx));
|
|
438
|
+
if (e.attribute) for (const attr of e.attribute) children.push(buildLocalAttribute(attr, childCtx));
|
|
439
|
+
if (e.attributeGroup) for (const ag of e.attributeGroup) children.push(buildAttributeGroupRef(ag, childCtx));
|
|
440
|
+
if (e.anyAttribute) children.push(buildAnyAttribute(e.anyAttribute, childCtx));
|
|
441
|
+
if (e.assert) for (const a of e.assert) children.push(buildAssertion(a, childCtx));
|
|
442
|
+
return buildElement$1(`${ctx.prefix}:extension`, attrs, children, ctx);
|
|
443
|
+
}
|
|
444
|
+
function buildSimpleContentRestriction(r, ctx) {
|
|
445
|
+
const attrs = [];
|
|
446
|
+
addAttr(attrs, "id", r.id);
|
|
447
|
+
addAttr(attrs, "base", r.base);
|
|
448
|
+
const children = [];
|
|
449
|
+
const childCtx = {
|
|
450
|
+
...ctx,
|
|
451
|
+
level: ctx.level + 1
|
|
452
|
+
};
|
|
453
|
+
if (r.annotation) children.push(buildAnnotation(r.annotation, childCtx));
|
|
454
|
+
if (r.simpleType) children.push(buildLocalSimpleType(r.simpleType, childCtx));
|
|
455
|
+
buildFacets(r, children, childCtx);
|
|
456
|
+
if (r.attribute) for (const attr of r.attribute) children.push(buildLocalAttribute(attr, childCtx));
|
|
457
|
+
if (r.attributeGroup) for (const ag of r.attributeGroup) children.push(buildAttributeGroupRef(ag, childCtx));
|
|
458
|
+
if (r.anyAttribute) children.push(buildAnyAttribute(r.anyAttribute, childCtx));
|
|
459
|
+
if (r.assert) for (const a of r.assert) children.push(buildAssertion(a, childCtx));
|
|
460
|
+
return buildElement$1(`${ctx.prefix}:restriction`, attrs, children, ctx);
|
|
461
|
+
}
|
|
462
|
+
function buildSimpleContentExtension(e, ctx) {
|
|
463
|
+
const attrs = [];
|
|
464
|
+
addAttr(attrs, "id", e.id);
|
|
465
|
+
addAttr(attrs, "base", e.base);
|
|
466
|
+
const children = [];
|
|
467
|
+
const childCtx = {
|
|
468
|
+
...ctx,
|
|
469
|
+
level: ctx.level + 1
|
|
470
|
+
};
|
|
471
|
+
if (e.annotation) children.push(buildAnnotation(e.annotation, childCtx));
|
|
472
|
+
if (e.attribute) for (const attr of e.attribute) children.push(buildLocalAttribute(attr, childCtx));
|
|
473
|
+
if (e.attributeGroup) for (const ag of e.attributeGroup) children.push(buildAttributeGroupRef(ag, childCtx));
|
|
474
|
+
if (e.anyAttribute) children.push(buildAnyAttribute(e.anyAttribute, childCtx));
|
|
475
|
+
if (e.assert) for (const a of e.assert) children.push(buildAssertion(a, childCtx));
|
|
476
|
+
return buildElement$1(`${ctx.prefix}:extension`, attrs, children, ctx);
|
|
477
|
+
}
|
|
478
|
+
function buildExplicitGroup(g, name, ctx) {
|
|
479
|
+
const attrs = [];
|
|
480
|
+
addAttr(attrs, "id", g.id);
|
|
481
|
+
addOccursAttr(attrs, "minOccurs", g.minOccurs);
|
|
482
|
+
addOccursAttr(attrs, "maxOccurs", g.maxOccurs);
|
|
483
|
+
const children = [];
|
|
484
|
+
const childCtx = {
|
|
485
|
+
...ctx,
|
|
486
|
+
level: ctx.level + 1
|
|
487
|
+
};
|
|
488
|
+
if (g.annotation) children.push(buildAnnotation(g.annotation, childCtx));
|
|
489
|
+
if (g.element) for (const el of g.element) children.push(buildLocalElement(el, childCtx));
|
|
490
|
+
if (g.group) for (const grp of g.group) children.push(buildGroupRef(grp, childCtx));
|
|
491
|
+
if (g.choice) for (const c of g.choice) children.push(buildExplicitGroup(c, "choice", childCtx));
|
|
492
|
+
if (g.sequence) for (const s of g.sequence) children.push(buildExplicitGroup(s, "sequence", childCtx));
|
|
493
|
+
if (g.any) for (const a of g.any) children.push(buildAny(a, childCtx));
|
|
494
|
+
return buildElement$1(`${ctx.prefix}:${name}`, attrs, children, ctx);
|
|
495
|
+
}
|
|
496
|
+
function buildAll(a, ctx) {
|
|
497
|
+
const attrs = [];
|
|
498
|
+
addAttr(attrs, "id", a.id);
|
|
499
|
+
addOccursAttr(attrs, "minOccurs", a.minOccurs);
|
|
500
|
+
addOccursAttr(attrs, "maxOccurs", a.maxOccurs);
|
|
501
|
+
const children = [];
|
|
502
|
+
const childCtx = {
|
|
503
|
+
...ctx,
|
|
504
|
+
level: ctx.level + 1
|
|
505
|
+
};
|
|
506
|
+
if (a.annotation) children.push(buildAnnotation(a.annotation, childCtx));
|
|
507
|
+
if (a.element) for (const el of a.element) children.push(buildLocalElement(el, childCtx));
|
|
508
|
+
if (a.any) for (const any of a.any) children.push(buildAny(any, childCtx));
|
|
509
|
+
if (a.group) for (const grp of a.group) children.push(buildGroupRef(grp, childCtx));
|
|
510
|
+
return buildElement$1(`${ctx.prefix}:all`, attrs, children, ctx);
|
|
511
|
+
}
|
|
512
|
+
function buildNamedGroup(g, ctx) {
|
|
513
|
+
const attrs = [];
|
|
514
|
+
addAttr(attrs, "id", g.id);
|
|
515
|
+
addAttr(attrs, "name", g.name);
|
|
516
|
+
const children = [];
|
|
517
|
+
const childCtx = {
|
|
518
|
+
...ctx,
|
|
519
|
+
level: ctx.level + 1
|
|
520
|
+
};
|
|
521
|
+
if (g.annotation) children.push(buildAnnotation(g.annotation, childCtx));
|
|
522
|
+
if (g.all) children.push(buildAll(g.all, childCtx));
|
|
523
|
+
if (g.choice) children.push(buildExplicitGroup(g.choice, "choice", childCtx));
|
|
524
|
+
if (g.sequence) children.push(buildExplicitGroup(g.sequence, "sequence", childCtx));
|
|
525
|
+
return buildElement$1(`${ctx.prefix}:group`, attrs, children, ctx);
|
|
526
|
+
}
|
|
527
|
+
function buildGroupRef(g, ctx) {
|
|
528
|
+
const attrs = [];
|
|
529
|
+
addAttr(attrs, "id", g.id);
|
|
530
|
+
addAttr(attrs, "ref", g.ref);
|
|
531
|
+
addOccursAttr(attrs, "minOccurs", g.minOccurs);
|
|
532
|
+
addOccursAttr(attrs, "maxOccurs", g.maxOccurs);
|
|
533
|
+
const children = [];
|
|
534
|
+
if (g.annotation) children.push(buildAnnotation(g.annotation, {
|
|
535
|
+
...ctx,
|
|
536
|
+
level: ctx.level + 1
|
|
537
|
+
}));
|
|
538
|
+
return buildElement$1(`${ctx.prefix}:group`, attrs, children, ctx);
|
|
539
|
+
}
|
|
540
|
+
function buildNamedAttributeGroup(ag, ctx) {
|
|
541
|
+
const attrs = [];
|
|
542
|
+
addAttr(attrs, "id", ag.id);
|
|
543
|
+
addAttr(attrs, "name", ag.name);
|
|
544
|
+
const children = [];
|
|
545
|
+
const childCtx = {
|
|
546
|
+
...ctx,
|
|
547
|
+
level: ctx.level + 1
|
|
548
|
+
};
|
|
549
|
+
if (ag.annotation) children.push(buildAnnotation(ag.annotation, childCtx));
|
|
550
|
+
if (ag.attribute) for (const attr of ag.attribute) children.push(buildLocalAttribute(attr, childCtx));
|
|
551
|
+
if (ag.attributeGroup) for (const agr of ag.attributeGroup) children.push(buildAttributeGroupRef(agr, childCtx));
|
|
552
|
+
if (ag.anyAttribute) children.push(buildAnyAttribute(ag.anyAttribute, childCtx));
|
|
553
|
+
return buildElement$1(`${ctx.prefix}:attributeGroup`, attrs, children, ctx);
|
|
554
|
+
}
|
|
555
|
+
function buildAttributeGroupRef(ag, ctx) {
|
|
556
|
+
const attrs = [];
|
|
557
|
+
addAttr(attrs, "id", ag.id);
|
|
558
|
+
addAttr(attrs, "ref", ag.ref);
|
|
559
|
+
const children = [];
|
|
560
|
+
if (ag.annotation) children.push(buildAnnotation(ag.annotation, {
|
|
561
|
+
...ctx,
|
|
562
|
+
level: ctx.level + 1
|
|
563
|
+
}));
|
|
564
|
+
return buildElement$1(`${ctx.prefix}:attributeGroup`, attrs, children, ctx);
|
|
565
|
+
}
|
|
566
|
+
function buildAny(a, ctx) {
|
|
567
|
+
const attrs = [];
|
|
568
|
+
addAttr(attrs, "id", a.id);
|
|
569
|
+
addOccursAttr(attrs, "minOccurs", a.minOccurs);
|
|
570
|
+
addOccursAttr(attrs, "maxOccurs", a.maxOccurs);
|
|
571
|
+
addAttr(attrs, "namespace", a.namespace);
|
|
572
|
+
addAttr(attrs, "processContents", a.processContents);
|
|
573
|
+
addAttr(attrs, "notNamespace", a.notNamespace);
|
|
574
|
+
addAttr(attrs, "notQName", a.notQName);
|
|
575
|
+
const children = [];
|
|
576
|
+
if (a.annotation) children.push(buildAnnotation(a.annotation, {
|
|
577
|
+
...ctx,
|
|
578
|
+
level: ctx.level + 1
|
|
579
|
+
}));
|
|
580
|
+
return buildElement$1(`${ctx.prefix}:any`, attrs, children, ctx);
|
|
581
|
+
}
|
|
582
|
+
function buildAnyAttribute(aa, ctx) {
|
|
583
|
+
const attrs = [];
|
|
584
|
+
addAttr(attrs, "id", aa.id);
|
|
585
|
+
addAttr(attrs, "namespace", aa.namespace);
|
|
586
|
+
addAttr(attrs, "processContents", aa.processContents);
|
|
587
|
+
addAttr(attrs, "notNamespace", aa.notNamespace);
|
|
588
|
+
addAttr(attrs, "notQName", aa.notQName);
|
|
589
|
+
const children = [];
|
|
590
|
+
if (aa.annotation) children.push(buildAnnotation(aa.annotation, {
|
|
591
|
+
...ctx,
|
|
592
|
+
level: ctx.level + 1
|
|
593
|
+
}));
|
|
594
|
+
return buildElement$1(`${ctx.prefix}:anyAttribute`, attrs, children, ctx);
|
|
595
|
+
}
|
|
596
|
+
function buildUnique(u, ctx) {
|
|
597
|
+
const attrs = [];
|
|
598
|
+
addAttr(attrs, "id", u.id);
|
|
599
|
+
addAttr(attrs, "name", u.name);
|
|
600
|
+
addAttr(attrs, "ref", u.ref);
|
|
601
|
+
const children = [];
|
|
602
|
+
const childCtx = {
|
|
603
|
+
...ctx,
|
|
604
|
+
level: ctx.level + 1
|
|
605
|
+
};
|
|
606
|
+
if (u.annotation) children.push(buildAnnotation(u.annotation, childCtx));
|
|
607
|
+
if (u.selector) children.push(buildSelector(u.selector, childCtx));
|
|
608
|
+
if (u.field) for (const f of u.field) children.push(buildField$1(f, childCtx));
|
|
609
|
+
return buildElement$1(`${ctx.prefix}:unique`, attrs, children, ctx);
|
|
610
|
+
}
|
|
611
|
+
function buildKey(k, ctx) {
|
|
612
|
+
const attrs = [];
|
|
613
|
+
addAttr(attrs, "id", k.id);
|
|
614
|
+
addAttr(attrs, "name", k.name);
|
|
615
|
+
addAttr(attrs, "ref", k.ref);
|
|
616
|
+
const children = [];
|
|
617
|
+
const childCtx = {
|
|
618
|
+
...ctx,
|
|
619
|
+
level: ctx.level + 1
|
|
620
|
+
};
|
|
621
|
+
if (k.annotation) children.push(buildAnnotation(k.annotation, childCtx));
|
|
622
|
+
if (k.selector) children.push(buildSelector(k.selector, childCtx));
|
|
623
|
+
if (k.field) for (const f of k.field) children.push(buildField$1(f, childCtx));
|
|
624
|
+
return buildElement$1(`${ctx.prefix}:key`, attrs, children, ctx);
|
|
625
|
+
}
|
|
626
|
+
function buildKeyref(kr, ctx) {
|
|
627
|
+
const attrs = [];
|
|
628
|
+
addAttr(attrs, "id", kr.id);
|
|
629
|
+
addAttr(attrs, "name", kr.name);
|
|
630
|
+
addAttr(attrs, "ref", kr.ref);
|
|
631
|
+
addAttr(attrs, "refer", kr.refer);
|
|
632
|
+
const children = [];
|
|
633
|
+
const childCtx = {
|
|
634
|
+
...ctx,
|
|
635
|
+
level: ctx.level + 1
|
|
636
|
+
};
|
|
637
|
+
if (kr.annotation) children.push(buildAnnotation(kr.annotation, childCtx));
|
|
638
|
+
if (kr.selector) children.push(buildSelector(kr.selector, childCtx));
|
|
639
|
+
if (kr.field) for (const f of kr.field) children.push(buildField$1(f, childCtx));
|
|
640
|
+
return buildElement$1(`${ctx.prefix}:keyref`, attrs, children, ctx);
|
|
641
|
+
}
|
|
642
|
+
function buildSelector(s, ctx) {
|
|
643
|
+
const attrs = [];
|
|
644
|
+
addAttr(attrs, "id", s.id);
|
|
645
|
+
addAttr(attrs, "xpath", s.xpath);
|
|
646
|
+
addAttr(attrs, "xpathDefaultNamespace", s.xpathDefaultNamespace);
|
|
647
|
+
const children = [];
|
|
648
|
+
if (s.annotation) children.push(buildAnnotation(s.annotation, {
|
|
649
|
+
...ctx,
|
|
650
|
+
level: ctx.level + 1
|
|
651
|
+
}));
|
|
652
|
+
return buildElement$1(`${ctx.prefix}:selector`, attrs, children, ctx);
|
|
653
|
+
}
|
|
654
|
+
function buildField$1(f, ctx) {
|
|
655
|
+
const attrs = [];
|
|
656
|
+
addAttr(attrs, "id", f.id);
|
|
657
|
+
addAttr(attrs, "xpath", f.xpath);
|
|
658
|
+
addAttr(attrs, "xpathDefaultNamespace", f.xpathDefaultNamespace);
|
|
659
|
+
const children = [];
|
|
660
|
+
if (f.annotation) children.push(buildAnnotation(f.annotation, {
|
|
661
|
+
...ctx,
|
|
662
|
+
level: ctx.level + 1
|
|
663
|
+
}));
|
|
664
|
+
return buildElement$1(`${ctx.prefix}:field`, attrs, children, ctx);
|
|
665
|
+
}
|
|
666
|
+
function buildOpenContent(oc, ctx) {
|
|
667
|
+
const attrs = [];
|
|
668
|
+
addAttr(attrs, "id", oc.id);
|
|
669
|
+
addAttr(attrs, "mode", oc.mode);
|
|
670
|
+
const children = [];
|
|
671
|
+
const childCtx = {
|
|
672
|
+
...ctx,
|
|
673
|
+
level: ctx.level + 1
|
|
674
|
+
};
|
|
675
|
+
if (oc.annotation) children.push(buildAnnotation(oc.annotation, childCtx));
|
|
676
|
+
if (oc.any) children.push(buildAny(oc.any, childCtx));
|
|
677
|
+
return buildElement$1(`${ctx.prefix}:openContent`, attrs, children, ctx);
|
|
678
|
+
}
|
|
679
|
+
function buildDefaultOpenContent(doc, ctx) {
|
|
680
|
+
const attrs = [];
|
|
681
|
+
addAttr(attrs, "id", doc.id);
|
|
682
|
+
addBoolAttr(attrs, "appliesToEmpty", doc.appliesToEmpty);
|
|
683
|
+
addAttr(attrs, "mode", doc.mode);
|
|
684
|
+
const children = [];
|
|
685
|
+
const childCtx = {
|
|
686
|
+
...ctx,
|
|
687
|
+
level: ctx.level + 1
|
|
688
|
+
};
|
|
689
|
+
if (doc.annotation) children.push(buildAnnotation(doc.annotation, childCtx));
|
|
690
|
+
children.push(buildAny(doc.any, childCtx));
|
|
691
|
+
return buildElement$1(`${ctx.prefix}:defaultOpenContent`, attrs, children, ctx);
|
|
692
|
+
}
|
|
693
|
+
function buildAssertion(a, ctx) {
|
|
694
|
+
const attrs = [];
|
|
695
|
+
addAttr(attrs, "id", a.id);
|
|
696
|
+
addAttr(attrs, "test", a.test);
|
|
697
|
+
addAttr(attrs, "xpathDefaultNamespace", a.xpathDefaultNamespace);
|
|
698
|
+
const children = [];
|
|
699
|
+
if (a.annotation) children.push(buildAnnotation(a.annotation, {
|
|
700
|
+
...ctx,
|
|
701
|
+
level: ctx.level + 1
|
|
702
|
+
}));
|
|
703
|
+
return buildElement$1(`${ctx.prefix}:assert`, attrs, children, ctx);
|
|
704
|
+
}
|
|
705
|
+
function buildAlternative(alt, ctx) {
|
|
706
|
+
const attrs = [];
|
|
707
|
+
addAttr(attrs, "id", alt.id);
|
|
708
|
+
addAttr(attrs, "test", alt.test);
|
|
709
|
+
addAttr(attrs, "type", alt.type);
|
|
710
|
+
addAttr(attrs, "xpathDefaultNamespace", alt.xpathDefaultNamespace);
|
|
711
|
+
const children = [];
|
|
712
|
+
const childCtx = {
|
|
713
|
+
...ctx,
|
|
714
|
+
level: ctx.level + 1
|
|
715
|
+
};
|
|
716
|
+
if (alt.annotation) children.push(buildAnnotation(alt.annotation, childCtx));
|
|
717
|
+
if (alt.simpleType) children.push(buildLocalSimpleType(alt.simpleType, childCtx));
|
|
718
|
+
if (alt.complexType) children.push(buildLocalComplexType(alt.complexType, childCtx));
|
|
719
|
+
return buildElement$1(`${ctx.prefix}:alternative`, attrs, children, ctx);
|
|
720
|
+
}
|
|
721
|
+
function buildNotation(n, ctx) {
|
|
722
|
+
const attrs = [];
|
|
723
|
+
addAttr(attrs, "id", n.id);
|
|
724
|
+
addAttr(attrs, "name", n.name);
|
|
725
|
+
addAttr(attrs, "public", n.public);
|
|
726
|
+
addAttr(attrs, "system", n.system);
|
|
727
|
+
const children = [];
|
|
728
|
+
if (n.annotation) children.push(buildAnnotation(n.annotation, {
|
|
729
|
+
...ctx,
|
|
730
|
+
level: ctx.level + 1
|
|
731
|
+
}));
|
|
732
|
+
return buildElement$1(`${ctx.prefix}:notation`, attrs, children, ctx);
|
|
733
|
+
}
|
|
734
|
+
function addAttr(attrs, name, value) {
|
|
735
|
+
if (value !== void 0) attrs.push(`${name}="${escapeXml(value)}"`);
|
|
736
|
+
}
|
|
737
|
+
function addBoolAttr(attrs, name, value) {
|
|
738
|
+
if (value !== void 0) attrs.push(`${name}="${value}"`);
|
|
739
|
+
}
|
|
740
|
+
function addOccursAttr(attrs, name, value) {
|
|
741
|
+
if (value !== void 0) attrs.push(`${name}="${value}"`);
|
|
742
|
+
}
|
|
743
|
+
function escapeXml(str) {
|
|
744
|
+
return str.replaceAll(/&/g, "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\"", """).replaceAll("'", "'");
|
|
745
|
+
}
|
|
746
|
+
function buildElement$1(tag, attrs, children, ctx) {
|
|
747
|
+
const indent = ctx.pretty ? ctx.indent.repeat(ctx.level) : "";
|
|
748
|
+
const attrStr = attrs.length > 0 ? " " + attrs.join(" ") : "";
|
|
749
|
+
if (children.length === 0) return `${indent}<${tag}${attrStr}/>`;
|
|
750
|
+
const nl = ctx.pretty ? "\n" : "";
|
|
751
|
+
return `${indent}<${tag}${attrStr}>${nl}${children.join(nl)}${nl}${indent}</${tag}>`;
|
|
752
|
+
}
|
|
753
|
+
function buildElementWithText(tag, attrs, text, ctx) {
|
|
754
|
+
return `${ctx.pretty ? ctx.indent.repeat(ctx.level) : ""}<${tag}${attrs.length > 0 ? " " + attrs.join(" ") : ""}>${escapeXml(text)}</${tag}>`;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
//#endregion
|
|
758
|
+
//#region src/xsd/helpers.ts
|
|
759
|
+
/**
|
|
760
|
+
* Resolve $imports for a schema by matching import schemaLocation to $filename.
|
|
761
|
+
*
|
|
762
|
+
* @param schema - The schema to resolve imports for
|
|
763
|
+
* @param availableSchemas - Array of schemas that may be imported
|
|
764
|
+
* @returns A new schema object with $imports populated
|
|
765
|
+
*
|
|
766
|
+
* @example
|
|
767
|
+
* ```typescript
|
|
768
|
+
* const orderSchema = parseXsd(orderXsd);
|
|
769
|
+
* const commonSchema = { ...parseXsd(commonXsd), $filename: 'common.xsd' };
|
|
770
|
+
*
|
|
771
|
+
* // orderSchema has: import: [{ schemaLocation: 'common.xsd', ... }]
|
|
772
|
+
* const resolved = resolveImports(orderSchema, [commonSchema]);
|
|
773
|
+
* // resolved.$imports = [commonSchema]
|
|
774
|
+
* ```
|
|
775
|
+
*/
|
|
776
|
+
function resolveImports(schema, availableSchemas) {
|
|
777
|
+
const imports = [];
|
|
778
|
+
if (schema.import) {
|
|
779
|
+
for (const imp of schema.import) if (imp.schemaLocation) {
|
|
780
|
+
const found = availableSchemas.find((s) => s.$filename === imp.schemaLocation);
|
|
781
|
+
if (found) imports.push(found);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
return {
|
|
785
|
+
...schema,
|
|
786
|
+
$imports: imports
|
|
787
|
+
};
|
|
788
|
+
}
|
|
789
|
+
/**
|
|
790
|
+
* Resolve $imports for multiple schemas, linking them together.
|
|
791
|
+
*
|
|
792
|
+
* @param schemas - Array of schemas to link together
|
|
793
|
+
* @returns Array of schemas with $imports populated
|
|
794
|
+
*
|
|
795
|
+
* @example
|
|
796
|
+
* ```typescript
|
|
797
|
+
* const schemas = [
|
|
798
|
+
* { ...parseXsd(orderXsd), $filename: 'order.xsd' },
|
|
799
|
+
* { ...parseXsd(commonXsd), $filename: 'common.xsd' },
|
|
800
|
+
* ];
|
|
801
|
+
* const linked = linkSchemas(schemas);
|
|
802
|
+
* // Each schema now has $imports resolved
|
|
803
|
+
* ```
|
|
804
|
+
*/
|
|
805
|
+
function linkSchemas(schemas) {
|
|
806
|
+
return schemas.map((schema) => resolveImports(schema, schemas));
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
//#endregion
|
|
810
|
+
//#region src/walker/index.ts
|
|
811
|
+
/**
|
|
812
|
+
* Walk all complexTypes in a schema and its $imports/$includes (depth-first).
|
|
813
|
+
*
|
|
814
|
+
* @param schema - Root schema to start from
|
|
815
|
+
* @param options - Walk options (e.g., includesOnly to skip $imports)
|
|
816
|
+
* @yields ComplexType with the schema it was found in
|
|
817
|
+
*
|
|
818
|
+
* @example
|
|
819
|
+
* ```typescript
|
|
820
|
+
* function findComplexType(name: string, schema: SchemaLike) {
|
|
821
|
+
* for (const { ct, schema: s } of walkComplexTypes(schema)) {
|
|
822
|
+
* if (ct.name === name) return { type: ct, schema: s };
|
|
823
|
+
* }
|
|
824
|
+
* }
|
|
825
|
+
* ```
|
|
826
|
+
*/
|
|
827
|
+
function* walkComplexTypes(schema, options = {}) {
|
|
828
|
+
const complexTypes = schema.complexType;
|
|
829
|
+
if (complexTypes) {
|
|
830
|
+
if (Array.isArray(complexTypes)) for (const ct of complexTypes) yield {
|
|
831
|
+
ct,
|
|
832
|
+
schema
|
|
833
|
+
};
|
|
834
|
+
else for (const [name, ct] of Object.entries(complexTypes)) yield {
|
|
835
|
+
ct: {
|
|
836
|
+
...ct,
|
|
837
|
+
name
|
|
838
|
+
},
|
|
839
|
+
schema
|
|
840
|
+
};
|
|
841
|
+
}
|
|
842
|
+
if (schema.redefine) {
|
|
843
|
+
for (const redef of schema.redefine) if (redef.complexType) for (const ct of redef.complexType) yield {
|
|
844
|
+
ct,
|
|
845
|
+
schema
|
|
846
|
+
};
|
|
847
|
+
}
|
|
848
|
+
if (schema.override) {
|
|
849
|
+
for (const ovr of schema.override) if (ovr.complexType) for (const ct of ovr.complexType) yield {
|
|
850
|
+
ct,
|
|
851
|
+
schema
|
|
852
|
+
};
|
|
853
|
+
}
|
|
854
|
+
if (schema.$includes) for (const included of schema.$includes) yield* walkComplexTypes(included, options);
|
|
855
|
+
if (!options.includesOnly && schema.$imports) for (const imported of schema.$imports) yield* walkComplexTypes(imported, options);
|
|
856
|
+
}
|
|
857
|
+
/**
|
|
858
|
+
* Walk all simpleTypes in a schema and its $imports/$includes.
|
|
859
|
+
*/
|
|
860
|
+
function* walkSimpleTypes(schema, options = {}) {
|
|
861
|
+
const simpleTypes = schema.simpleType;
|
|
862
|
+
if (simpleTypes) {
|
|
863
|
+
if (Array.isArray(simpleTypes)) for (const st of simpleTypes) yield {
|
|
864
|
+
st,
|
|
865
|
+
schema
|
|
866
|
+
};
|
|
867
|
+
else for (const [name, st] of Object.entries(simpleTypes)) yield {
|
|
868
|
+
st: {
|
|
869
|
+
...st,
|
|
870
|
+
name
|
|
871
|
+
},
|
|
872
|
+
schema
|
|
873
|
+
};
|
|
874
|
+
}
|
|
875
|
+
if (schema.redefine) {
|
|
876
|
+
for (const redef of schema.redefine) if (redef.simpleType) for (const st of redef.simpleType) yield {
|
|
877
|
+
st,
|
|
878
|
+
schema
|
|
879
|
+
};
|
|
880
|
+
}
|
|
881
|
+
if (schema.override) {
|
|
882
|
+
for (const ovr of schema.override) if (ovr.simpleType) for (const st of ovr.simpleType) yield {
|
|
883
|
+
st,
|
|
884
|
+
schema
|
|
885
|
+
};
|
|
886
|
+
}
|
|
887
|
+
if (schema.$includes) for (const included of schema.$includes) yield* walkSimpleTypes(included, options);
|
|
888
|
+
if (!options.includesOnly && schema.$imports) for (const imported of schema.$imports) yield* walkSimpleTypes(imported, options);
|
|
889
|
+
}
|
|
890
|
+
/**
|
|
891
|
+
* Walk all top-level elements in a schema and its $imports/$includes.
|
|
892
|
+
*/
|
|
893
|
+
function* walkTopLevelElements(schema, options = {}) {
|
|
894
|
+
if (schema.element) for (const element of schema.element) yield {
|
|
895
|
+
element,
|
|
896
|
+
schema
|
|
897
|
+
};
|
|
898
|
+
if (schema.$includes) for (const included of schema.$includes) yield* walkTopLevelElements(included, options);
|
|
899
|
+
if (!options.includesOnly && schema.$imports) for (const imported of schema.$imports) yield* walkTopLevelElements(imported, options);
|
|
900
|
+
}
|
|
901
|
+
/**
|
|
902
|
+
* Find a complexType by name, searching schema and $imports.
|
|
903
|
+
* Returns both the type AND the schema it was found in (important for inheritance).
|
|
904
|
+
*/
|
|
905
|
+
function findComplexType(name, schema) {
|
|
906
|
+
for (const entry of walkComplexTypes(schema)) if (entry.ct.name === name) return entry;
|
|
907
|
+
}
|
|
908
|
+
/**
|
|
909
|
+
* Find a simpleType by name, searching schema and $imports.
|
|
910
|
+
*/
|
|
911
|
+
function findSimpleType(name, schema) {
|
|
912
|
+
for (const entry of walkSimpleTypes(schema)) if (entry.st.name === name) return entry;
|
|
913
|
+
}
|
|
914
|
+
/**
|
|
915
|
+
* Find a top-level element by name, searching schema and $imports.
|
|
916
|
+
*/
|
|
917
|
+
function findElement(name, schema) {
|
|
918
|
+
for (const entry of walkTopLevelElements(schema)) if (entry.element.name === name) return entry;
|
|
919
|
+
}
|
|
920
|
+
/**
|
|
921
|
+
* Walk all elements in a complexType, handling:
|
|
922
|
+
* - sequence, choice, all groups
|
|
923
|
+
* - Nested groups (recursive)
|
|
924
|
+
* - complexContent/extension inheritance
|
|
925
|
+
* - Group references
|
|
926
|
+
*
|
|
927
|
+
* @param ct - ComplexType to walk
|
|
928
|
+
* @param schema - Schema context (for resolving base types and group refs)
|
|
929
|
+
* @yields Elements with metadata (optional, array, source)
|
|
930
|
+
*/
|
|
931
|
+
function* walkElements(ct, schema) {
|
|
932
|
+
if (ct.complexContent?.extension) {
|
|
933
|
+
const ext = ct.complexContent.extension;
|
|
934
|
+
if (ext.base) {
|
|
935
|
+
const baseEntry = findComplexType(stripNsPrefix(ext.base), schema);
|
|
936
|
+
if (baseEntry) yield* walkElements(baseEntry.ct, baseEntry.schema);
|
|
937
|
+
}
|
|
938
|
+
yield* walkGroup(ext.sequence, "sequence", schema);
|
|
939
|
+
yield* walkGroup(ext.choice, "choice", schema);
|
|
940
|
+
yield* walkGroup(ext.all, "all", schema);
|
|
941
|
+
if (ext.group?.ref) yield* walkGroupRef(ext.group.ref, schema);
|
|
942
|
+
return;
|
|
943
|
+
}
|
|
944
|
+
if (ct.complexContent?.restriction) {
|
|
945
|
+
const rest = ct.complexContent.restriction;
|
|
946
|
+
yield* walkGroup(rest.sequence, "sequence", schema);
|
|
947
|
+
yield* walkGroup(rest.choice, "choice", schema);
|
|
948
|
+
yield* walkGroup(rest.all, "all", schema);
|
|
949
|
+
if (rest.group?.ref) yield* walkGroupRef(rest.group.ref, schema);
|
|
950
|
+
return;
|
|
951
|
+
}
|
|
952
|
+
yield* walkGroup(ct.sequence, "sequence", schema);
|
|
953
|
+
yield* walkGroup(ct.choice, "choice", schema);
|
|
954
|
+
yield* walkGroup(ct.all, "all", schema);
|
|
955
|
+
if (ct.group?.ref) yield* walkGroupRef(ct.group.ref, schema);
|
|
956
|
+
}
|
|
957
|
+
/**
|
|
958
|
+
* Walk elements in a group (sequence/choice/all), handling nested groups.
|
|
959
|
+
*/
|
|
960
|
+
function* walkGroup(group, source, schema, parentOptional = false, parentArray = false) {
|
|
961
|
+
if (!group) return;
|
|
962
|
+
const groupOptional = parentOptional || group.minOccurs === 0 || group.minOccurs === "0";
|
|
963
|
+
const groupArray = parentArray || isArray(group);
|
|
964
|
+
const choiceOptional = source === "choice";
|
|
965
|
+
if (group.element) for (const element of group.element) {
|
|
966
|
+
const optional = choiceOptional || groupOptional || element.minOccurs === 0 || element.minOccurs === "0";
|
|
967
|
+
const array = groupArray || isArray(element);
|
|
968
|
+
if (element.ref) {
|
|
969
|
+
const refName = stripNsPrefix(element.ref);
|
|
970
|
+
const refEntry = findElement(refName, schema);
|
|
971
|
+
if (refEntry && isAbstractElement(refEntry.element)) {
|
|
972
|
+
const substitutes = findSubstitutes(refName, schema);
|
|
973
|
+
if (substitutes.length > 0) {
|
|
974
|
+
for (const sub of substitutes) yield {
|
|
975
|
+
element: sub,
|
|
976
|
+
optional,
|
|
977
|
+
array,
|
|
978
|
+
source,
|
|
979
|
+
schema
|
|
980
|
+
};
|
|
981
|
+
continue;
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
yield {
|
|
986
|
+
element,
|
|
987
|
+
optional,
|
|
988
|
+
array,
|
|
989
|
+
source,
|
|
990
|
+
schema
|
|
991
|
+
};
|
|
992
|
+
}
|
|
993
|
+
if (group.sequence) {
|
|
994
|
+
const sequences = Array.isArray(group.sequence) ? group.sequence : [group.sequence];
|
|
995
|
+
for (const nested of sequences) yield* walkGroup(nested, "sequence", schema, groupOptional, groupArray);
|
|
996
|
+
}
|
|
997
|
+
if (group.choice) {
|
|
998
|
+
const choices = Array.isArray(group.choice) ? group.choice : [group.choice];
|
|
999
|
+
for (const nested of choices) yield* walkGroup(nested, "choice", schema, true, groupArray || isArray(nested));
|
|
1000
|
+
}
|
|
1001
|
+
if (group.group) {
|
|
1002
|
+
const refs = Array.isArray(group.group) ? group.group : [group.group];
|
|
1003
|
+
for (const ref of refs) if (ref.ref) yield* walkGroupRef(ref.ref, schema, groupOptional || choiceOptional, groupArray || isArray(ref));
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
/**
|
|
1007
|
+
* Walk elements from a group reference (xs:group ref="...").
|
|
1008
|
+
*/
|
|
1009
|
+
function* walkGroupRef(ref, schema, parentOptional = false, parentArray = false) {
|
|
1010
|
+
const group = findGroup(stripNsPrefix(ref), schema);
|
|
1011
|
+
if (group) {
|
|
1012
|
+
if (group.sequence) yield* walkGroup(group.sequence, "sequence", schema, parentOptional, parentArray);
|
|
1013
|
+
if (group.choice) yield* walkGroup(group.choice, "choice", schema, true, parentArray);
|
|
1014
|
+
if (group.all) yield* walkGroup(group.all, "all", schema, parentOptional, parentArray);
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
/**
|
|
1018
|
+
* Walk all attributes in a complexType, handling:
|
|
1019
|
+
* - Direct attributes
|
|
1020
|
+
* - complexContent/extension attributes
|
|
1021
|
+
* - simpleContent/extension attributes
|
|
1022
|
+
* - Inherited attributes from base type
|
|
1023
|
+
* - AttributeGroup references
|
|
1024
|
+
*/
|
|
1025
|
+
function* walkAttributes(ct, schema) {
|
|
1026
|
+
if (ct.complexContent?.extension) {
|
|
1027
|
+
const ext = ct.complexContent.extension;
|
|
1028
|
+
if (ext.base) {
|
|
1029
|
+
const baseEntry = findComplexType(stripNsPrefix(ext.base), schema);
|
|
1030
|
+
if (baseEntry) yield* walkAttributes(baseEntry.ct, baseEntry.schema);
|
|
1031
|
+
}
|
|
1032
|
+
if (ext.attribute) for (const attr of ext.attribute) {
|
|
1033
|
+
const resolved = resolveAttribute(attr, schema);
|
|
1034
|
+
if (resolved) yield {
|
|
1035
|
+
attribute: resolved,
|
|
1036
|
+
required: resolved.use === "required",
|
|
1037
|
+
schema
|
|
1038
|
+
};
|
|
1039
|
+
}
|
|
1040
|
+
yield* walkAttributeGroupRefs(ext.attributeGroup, schema);
|
|
1041
|
+
return;
|
|
1042
|
+
}
|
|
1043
|
+
if (ct.simpleContent?.extension) {
|
|
1044
|
+
const ext = ct.simpleContent.extension;
|
|
1045
|
+
if (ext.attribute) for (const attr of ext.attribute) {
|
|
1046
|
+
const resolved = resolveAttribute(attr, schema);
|
|
1047
|
+
if (resolved) yield {
|
|
1048
|
+
attribute: resolved,
|
|
1049
|
+
required: resolved.use === "required",
|
|
1050
|
+
schema
|
|
1051
|
+
};
|
|
1052
|
+
}
|
|
1053
|
+
yield* walkAttributeGroupRefs(ext.attributeGroup, schema);
|
|
1054
|
+
return;
|
|
1055
|
+
}
|
|
1056
|
+
if (ct.attribute) for (const attr of ct.attribute) {
|
|
1057
|
+
const resolved = resolveAttribute(attr, schema);
|
|
1058
|
+
if (resolved) yield {
|
|
1059
|
+
attribute: resolved,
|
|
1060
|
+
required: resolved.use === "required",
|
|
1061
|
+
schema
|
|
1062
|
+
};
|
|
1063
|
+
}
|
|
1064
|
+
yield* walkAttributeGroupRefs(ct.attributeGroup, schema);
|
|
1065
|
+
}
|
|
1066
|
+
/**
|
|
1067
|
+
* Walk attributes from attributeGroup references.
|
|
1068
|
+
*/
|
|
1069
|
+
function* walkAttributeGroupRefs(refs, schema) {
|
|
1070
|
+
if (!refs) return;
|
|
1071
|
+
for (const ref of refs) {
|
|
1072
|
+
const refObj = ref;
|
|
1073
|
+
if (refObj.ref) {
|
|
1074
|
+
const group = findAttributeGroup(stripNsPrefix(refObj.ref), schema);
|
|
1075
|
+
if (group?.attribute) for (const attribute of group.attribute) yield {
|
|
1076
|
+
attribute,
|
|
1077
|
+
required: attribute.use === "required",
|
|
1078
|
+
schema
|
|
1079
|
+
};
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
/**
|
|
1084
|
+
* Find a named group (xs:group) by name.
|
|
1085
|
+
*/
|
|
1086
|
+
function findGroup(name, schema) {
|
|
1087
|
+
if (schema.group) {
|
|
1088
|
+
for (const g of schema.group) if (g.name === name) return g;
|
|
1089
|
+
}
|
|
1090
|
+
if (schema.$includes) for (const included of schema.$includes) {
|
|
1091
|
+
const found = findGroup(name, included);
|
|
1092
|
+
if (found) return found;
|
|
1093
|
+
}
|
|
1094
|
+
if (schema.$imports) for (const imported of schema.$imports) {
|
|
1095
|
+
const found = findGroup(name, imported);
|
|
1096
|
+
if (found) return found;
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
/**
|
|
1100
|
+
* Find a top-level attribute by name.
|
|
1101
|
+
* Searches current schema and $imports.
|
|
1102
|
+
*/
|
|
1103
|
+
function findAttribute(name, schema) {
|
|
1104
|
+
const schemaWithAttrs = schema;
|
|
1105
|
+
if (schemaWithAttrs.attribute) {
|
|
1106
|
+
for (const attr of schemaWithAttrs.attribute) if (attr.name === name) return attr;
|
|
1107
|
+
}
|
|
1108
|
+
if (schema.$includes) for (const included of schema.$includes) {
|
|
1109
|
+
const found = findAttribute(name, included);
|
|
1110
|
+
if (found) return found;
|
|
1111
|
+
}
|
|
1112
|
+
if (schema.$imports) for (const imported of schema.$imports) {
|
|
1113
|
+
const found = findAttribute(name, imported);
|
|
1114
|
+
if (found) return found;
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
/**
|
|
1118
|
+
* Resolve an attribute - handles both direct attributes and refs.
|
|
1119
|
+
* Returns the resolved attribute with its name.
|
|
1120
|
+
*/
|
|
1121
|
+
function resolveAttribute(attribute, schema) {
|
|
1122
|
+
if (attribute.ref) {
|
|
1123
|
+
const refName = stripNsPrefix(attribute.ref);
|
|
1124
|
+
const resolved = findAttribute(refName, schema);
|
|
1125
|
+
if (resolved) return {
|
|
1126
|
+
...resolved,
|
|
1127
|
+
use: attribute.use ?? resolved.use
|
|
1128
|
+
};
|
|
1129
|
+
return {
|
|
1130
|
+
name: refName,
|
|
1131
|
+
type: "xs:string",
|
|
1132
|
+
use: attribute.use
|
|
1133
|
+
};
|
|
1134
|
+
}
|
|
1135
|
+
return attribute;
|
|
1136
|
+
}
|
|
1137
|
+
/**
|
|
1138
|
+
* Find an attributeGroup by name.
|
|
1139
|
+
*/
|
|
1140
|
+
function findAttributeGroup(name, schema) {
|
|
1141
|
+
if (schema.attributeGroup) {
|
|
1142
|
+
for (const g of schema.attributeGroup) if (g.name === name) return g;
|
|
1143
|
+
}
|
|
1144
|
+
if (schema.$includes) for (const included of schema.$includes) {
|
|
1145
|
+
const found = findAttributeGroup(name, included);
|
|
1146
|
+
if (found) return found;
|
|
1147
|
+
}
|
|
1148
|
+
if (schema.$imports) for (const imported of schema.$imports) {
|
|
1149
|
+
const found = findAttributeGroup(name, imported);
|
|
1150
|
+
if (found) return found;
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
/**
|
|
1154
|
+
* Strip namespace prefix from a QName (e.g., "tns:PersonType" -> "PersonType")
|
|
1155
|
+
*/
|
|
1156
|
+
function stripNsPrefix(name) {
|
|
1157
|
+
const colonIndex = name.indexOf(":");
|
|
1158
|
+
return colonIndex >= 0 ? name.slice(colonIndex + 1) : name;
|
|
1159
|
+
}
|
|
1160
|
+
/**
|
|
1161
|
+
* Check if element/group has maxOccurs > 1 (is array)
|
|
1162
|
+
*/
|
|
1163
|
+
function isArray(item) {
|
|
1164
|
+
if (item.maxOccurs === "unbounded") return true;
|
|
1165
|
+
if (typeof item.maxOccurs === "number") return item.maxOccurs > 1;
|
|
1166
|
+
if (typeof item.maxOccurs === "string") {
|
|
1167
|
+
if (item.maxOccurs === "unbounded") return true;
|
|
1168
|
+
const num = Number.parseInt(item.maxOccurs, 10);
|
|
1169
|
+
return !Number.isNaN(num) && num > 1;
|
|
1170
|
+
}
|
|
1171
|
+
return false;
|
|
1172
|
+
}
|
|
1173
|
+
/**
|
|
1174
|
+
* Check if an element is abstract
|
|
1175
|
+
*/
|
|
1176
|
+
function isAbstractElement(element) {
|
|
1177
|
+
return element.abstract === true || element.abstract === "true";
|
|
1178
|
+
}
|
|
1179
|
+
/**
|
|
1180
|
+
* Find all elements that substitute for a given abstract element.
|
|
1181
|
+
* This handles XSD substitution groups where concrete elements can
|
|
1182
|
+
* substitute for an abstract element.
|
|
1183
|
+
*/
|
|
1184
|
+
function findSubstitutes(abstractElementName, schema) {
|
|
1185
|
+
const substitutes = [];
|
|
1186
|
+
for (const { element } of walkTopLevelElements(schema)) {
|
|
1187
|
+
const subGroup = element.substitutionGroup;
|
|
1188
|
+
if (subGroup) {
|
|
1189
|
+
if (stripNsPrefix(subGroup) === abstractElementName) substitutes.push(element);
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
return substitutes;
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
//#endregion
|
|
1196
|
+
//#region src/xml/parse.ts
|
|
1197
|
+
/**
|
|
1198
|
+
* XML Parser for W3C Schema
|
|
1199
|
+
*
|
|
1200
|
+
* Parse XML string to typed JavaScript object using W3C-compliant Schema definition.
|
|
1201
|
+
* Uses the walker module for schema traversal.
|
|
1202
|
+
*/
|
|
1203
|
+
/**
|
|
1204
|
+
* Find all elements that substitute for a given abstract element
|
|
1205
|
+
* Searches current schema and all $imports
|
|
1206
|
+
*/
|
|
1207
|
+
function findSubstitutingElements(abstractElementName, schema) {
|
|
1208
|
+
const results = [];
|
|
1209
|
+
const checkSchema = (s) => {
|
|
1210
|
+
const elements = s.element;
|
|
1211
|
+
if (!elements) return;
|
|
1212
|
+
for (const el of elements) if (el.substitutionGroup) {
|
|
1213
|
+
if (stripNsPrefix(el.substitutionGroup) === abstractElementName) results.push({
|
|
1214
|
+
element: el,
|
|
1215
|
+
schema: s
|
|
1216
|
+
});
|
|
1217
|
+
}
|
|
1218
|
+
};
|
|
1219
|
+
checkSchema(schema);
|
|
1220
|
+
const imports = schema.$imports;
|
|
1221
|
+
if (imports) for (const imported of imports) {
|
|
1222
|
+
checkSchema(imported);
|
|
1223
|
+
const nestedResults = findSubstitutingElements(abstractElementName, imported);
|
|
1224
|
+
results.push(...nestedResults);
|
|
1225
|
+
}
|
|
1226
|
+
return results;
|
|
1227
|
+
}
|
|
1228
|
+
/**
|
|
1229
|
+
* Check if an element is abstract
|
|
1230
|
+
* Searches current schema and all $imports
|
|
1231
|
+
*/
|
|
1232
|
+
function isAbstractElement$1(elementName, schema) {
|
|
1233
|
+
const elements = schema.element;
|
|
1234
|
+
if (elements) {
|
|
1235
|
+
for (const el of elements) if (el.name === elementName && el.abstract === true) return true;
|
|
1236
|
+
}
|
|
1237
|
+
const imports = schema.$imports;
|
|
1238
|
+
if (imports) {
|
|
1239
|
+
for (const imported of imports) if (isAbstractElement$1(elementName, imported)) return true;
|
|
1240
|
+
}
|
|
1241
|
+
return false;
|
|
1242
|
+
}
|
|
1243
|
+
/**
|
|
1244
|
+
* Parse XML string to typed object using schema definition
|
|
1245
|
+
*/
|
|
1246
|
+
function parse(schema, xml) {
|
|
1247
|
+
const root = new DOMParser().parseFromString(xml, "text/xml")?.documentElement;
|
|
1248
|
+
if (!root) throw new Error("Invalid XML: missing root element");
|
|
1249
|
+
const rootLocalName = getLocalName(root);
|
|
1250
|
+
const elementEntry = findElementByName(schema, rootLocalName);
|
|
1251
|
+
if (!elementEntry) throw new Error(`Schema missing element declaration for: ${rootLocalName}`);
|
|
1252
|
+
const inlineComplexType = elementEntry.element.complexType;
|
|
1253
|
+
if (inlineComplexType) {
|
|
1254
|
+
const content = parseElement(root, inlineComplexType, elementEntry.schema, schema);
|
|
1255
|
+
return { [rootLocalName]: content };
|
|
1256
|
+
}
|
|
1257
|
+
const typeName = stripNsPrefix(elementEntry.element.type || elementEntry.element.name || "");
|
|
1258
|
+
const typeEntry = findComplexType(typeName, schema);
|
|
1259
|
+
if (!typeEntry) throw new Error(`Schema missing complexType for: ${typeName}`);
|
|
1260
|
+
const content = parseElement(root, typeEntry.ct, typeEntry.schema, schema);
|
|
1261
|
+
return { [rootLocalName]: content };
|
|
1262
|
+
}
|
|
1263
|
+
/**
|
|
1264
|
+
* Find element declaration by name (case-insensitive fallback)
|
|
1265
|
+
*/
|
|
1266
|
+
function findElementByName(schema, name) {
|
|
1267
|
+
const exact = findElement(name, schema);
|
|
1268
|
+
if (exact) return exact;
|
|
1269
|
+
const elements = schema.element;
|
|
1270
|
+
if (elements) {
|
|
1271
|
+
const lowerName = name.toLowerCase();
|
|
1272
|
+
const found = elements.find((el) => el.name?.toLowerCase() === lowerName);
|
|
1273
|
+
if (found) return {
|
|
1274
|
+
element: found,
|
|
1275
|
+
schema
|
|
1276
|
+
};
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
/**
|
|
1280
|
+
* Parse a single element using its complexType definition
|
|
1281
|
+
* Uses walker to iterate elements and attributes (handles inheritance automatically)
|
|
1282
|
+
* @param node - The XML element to parse
|
|
1283
|
+
* @param typeDef - The complexType definition for this element
|
|
1284
|
+
* @param schema - The schema where typeDef is defined (for type resolution)
|
|
1285
|
+
* @param rootSchema - The root schema (for substitution group lookups)
|
|
1286
|
+
*/
|
|
1287
|
+
function parseElement(node, typeDef, schema, rootSchema) {
|
|
1288
|
+
const result = {};
|
|
1289
|
+
if (typeDef.simpleContent?.extension) return parseSimpleContent(node, typeDef, schema, rootSchema);
|
|
1290
|
+
for (const { attribute } of walkAttributes(typeDef, schema)) {
|
|
1291
|
+
if (!attribute.name) continue;
|
|
1292
|
+
const value = getAttributeValue(node, attribute.name);
|
|
1293
|
+
if (value !== null) result[attribute.name] = convertValue(value, attribute.type || "string");
|
|
1294
|
+
else if (attribute.default !== void 0) result[attribute.name] = convertValue(String(attribute.default), attribute.type || "string");
|
|
1295
|
+
}
|
|
1296
|
+
for (const { element, array } of walkElements(typeDef, schema)) {
|
|
1297
|
+
const resolved = resolveElementInfo$1(element, schema);
|
|
1298
|
+
if (!resolved) continue;
|
|
1299
|
+
if (isAbstractElement$1(resolved.name, rootSchema)) {
|
|
1300
|
+
const substitutes = findSubstitutingElements(resolved.name, rootSchema);
|
|
1301
|
+
const allChildren = getAllChildElements(node);
|
|
1302
|
+
for (const child of allChildren) {
|
|
1303
|
+
const childName = getLocalName(child);
|
|
1304
|
+
const substitute = substitutes.find((s) => s.element.name === childName);
|
|
1305
|
+
if (substitute && substitute.element.name) {
|
|
1306
|
+
const subTypeName = substitute.element.type ? stripNsPrefix(substitute.element.type) : void 0;
|
|
1307
|
+
result[substitute.element.name] = parseChildValue(child, subTypeName, substitute.schema, rootSchema);
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
} else {
|
|
1311
|
+
const children = getChildElements(node, resolved.name);
|
|
1312
|
+
if (array || children.length > 1) {
|
|
1313
|
+
const values = children.map((child) => parseChildValue(child, resolved.typeName, schema, rootSchema));
|
|
1314
|
+
if (values.length > 0) result[resolved.name] = values;
|
|
1315
|
+
} else if (children.length === 1) result[resolved.name] = parseChildValue(children[0], resolved.typeName, schema, rootSchema);
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
return result;
|
|
1319
|
+
}
|
|
1320
|
+
/**
|
|
1321
|
+
* Parse simpleContent (text content with attributes)
|
|
1322
|
+
*/
|
|
1323
|
+
function parseSimpleContent(node, typeDef, _schema, _rootSchema) {
|
|
1324
|
+
const result = {};
|
|
1325
|
+
const simpleContent = typeDef.simpleContent;
|
|
1326
|
+
if (!simpleContent?.extension) return result;
|
|
1327
|
+
const ext = simpleContent.extension;
|
|
1328
|
+
result.$value = convertValue(getTextContent(node), ext.base ? stripNsPrefix(ext.base) : "string");
|
|
1329
|
+
if (ext.attribute) for (const attrDef of ext.attribute) {
|
|
1330
|
+
if (!attrDef.name) continue;
|
|
1331
|
+
const value = getAttributeValue(node, attrDef.name);
|
|
1332
|
+
if (value !== null) result[attrDef.name] = convertValue(value, attrDef.type || "string");
|
|
1333
|
+
else if (attrDef.default !== void 0) result[attrDef.name] = convertValue(String(attrDef.default), attrDef.type || "string");
|
|
1334
|
+
}
|
|
1335
|
+
return result;
|
|
1336
|
+
}
|
|
1337
|
+
/**
|
|
1338
|
+
* Resolve element info (name and type), handling ref
|
|
1339
|
+
*/
|
|
1340
|
+
function resolveElementInfo$1(element, schema) {
|
|
1341
|
+
if (element.name) return {
|
|
1342
|
+
name: element.name,
|
|
1343
|
+
typeName: element.type ? stripNsPrefix(element.type) : void 0
|
|
1344
|
+
};
|
|
1345
|
+
if (element.ref) {
|
|
1346
|
+
const refName = stripNsPrefix(element.ref);
|
|
1347
|
+
const refElement = findElement(refName, schema);
|
|
1348
|
+
if (refElement) return {
|
|
1349
|
+
name: refElement.element.name ?? refName,
|
|
1350
|
+
typeName: refElement.element.type ? stripNsPrefix(refElement.element.type) : void 0
|
|
1351
|
+
};
|
|
1352
|
+
return {
|
|
1353
|
+
name: refName,
|
|
1354
|
+
typeName: void 0
|
|
1355
|
+
};
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
/**
|
|
1359
|
+
* Parse a child element's value (either complex type or simple value)
|
|
1360
|
+
*/
|
|
1361
|
+
function parseChildValue(child, typeName, schema, rootSchema) {
|
|
1362
|
+
const nestedType = typeName ? findComplexType(typeName, schema) : void 0;
|
|
1363
|
+
if (nestedType) return parseElement(child, nestedType.ct, nestedType.schema, rootSchema);
|
|
1364
|
+
return convertValue(getTextContent(child) || "", typeName || "string");
|
|
1365
|
+
}
|
|
1366
|
+
/**
|
|
1367
|
+
* Convert string value to typed value based on XSD type
|
|
1368
|
+
*/
|
|
1369
|
+
function convertValue(value, type) {
|
|
1370
|
+
switch (stripNsPrefix(type)) {
|
|
1371
|
+
case "int":
|
|
1372
|
+
case "integer":
|
|
1373
|
+
case "decimal":
|
|
1374
|
+
case "float":
|
|
1375
|
+
case "double":
|
|
1376
|
+
case "short":
|
|
1377
|
+
case "long":
|
|
1378
|
+
case "byte":
|
|
1379
|
+
case "unsignedInt":
|
|
1380
|
+
case "unsignedShort":
|
|
1381
|
+
case "unsignedLong":
|
|
1382
|
+
case "unsignedByte":
|
|
1383
|
+
case "positiveInteger":
|
|
1384
|
+
case "negativeInteger":
|
|
1385
|
+
case "nonPositiveInteger":
|
|
1386
|
+
case "nonNegativeInteger": return Number(value);
|
|
1387
|
+
case "boolean": return value === "true" || value === "1";
|
|
1388
|
+
case "date":
|
|
1389
|
+
case "dateTime": return value;
|
|
1390
|
+
default: return value;
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
//#endregion
|
|
1395
|
+
//#region src/xml/build-utils.ts
|
|
1396
|
+
/**
|
|
1397
|
+
* Get namespace prefix from schema $xmlns declarations
|
|
1398
|
+
*/
|
|
1399
|
+
function getSchemaPrefix(schema) {
|
|
1400
|
+
if (!schema.$xmlns || !schema.targetNamespace) return void 0;
|
|
1401
|
+
for (const [prefix, uri] of Object.entries(schema.$xmlns)) if (uri === schema.targetNamespace && prefix) return prefix;
|
|
1402
|
+
}
|
|
1403
|
+
/**
|
|
1404
|
+
* Create XML document with namespace
|
|
1405
|
+
*/
|
|
1406
|
+
function createXmlDocument(schema) {
|
|
1407
|
+
const impl = new DOMImplementation();
|
|
1408
|
+
const ns = schema.targetNamespace || null;
|
|
1409
|
+
return impl.createDocument(ns, "", null);
|
|
1410
|
+
}
|
|
1411
|
+
/**
|
|
1412
|
+
* Collect namespace declarations from a schema and its $imports/$includes recursively.
|
|
1413
|
+
*
|
|
1414
|
+
* Gathers all $xmlns prefix→URI mappings from the schema tree.
|
|
1415
|
+
* Unused declarations are cleaned up later by stripUnusedNamespaces()
|
|
1416
|
+
* after the XML tree is built — that approach is generic and doesn't
|
|
1417
|
+
* require any domain-specific knowledge.
|
|
1418
|
+
*/
|
|
1419
|
+
function collectAllNamespaces(schema, collected = /* @__PURE__ */ new Map(), visited = /* @__PURE__ */ new Set()) {
|
|
1420
|
+
if (visited.has(schema)) return collected;
|
|
1421
|
+
visited.add(schema);
|
|
1422
|
+
if (schema.$xmlns) {
|
|
1423
|
+
for (const [pfx, uri] of Object.entries(schema.$xmlns)) if (!collected.has(pfx)) collected.set(pfx, uri);
|
|
1424
|
+
}
|
|
1425
|
+
const imports = schema.$imports;
|
|
1426
|
+
if (imports) for (const imported of imports) collectAllNamespaces(imported, collected, visited);
|
|
1427
|
+
const includes = schema.$includes;
|
|
1428
|
+
if (includes) for (const included of includes) collectAllNamespaces(included, collected, visited);
|
|
1429
|
+
return collected;
|
|
1430
|
+
}
|
|
1431
|
+
/**
|
|
1432
|
+
* Create root element with namespace declarations
|
|
1433
|
+
*
|
|
1434
|
+
* When elementFormDefault="unqualified", the root element should NOT have
|
|
1435
|
+
* a namespace prefix. This is important for formats like abapGit where
|
|
1436
|
+
* the root element (abapGit) is unqualified but child elements may have prefixes.
|
|
1437
|
+
*/
|
|
1438
|
+
function createRootElement(doc, elementName, schema, prefix) {
|
|
1439
|
+
const ns = schema.targetNamespace || null;
|
|
1440
|
+
const usePrefix = schema.elementFormDefault === "unqualified" ? void 0 : prefix;
|
|
1441
|
+
const rootTag = usePrefix ? `${usePrefix}:${elementName}` : elementName;
|
|
1442
|
+
const root = doc.createElement(rootTag);
|
|
1443
|
+
if (ns && prefix) root.setAttribute(`xmlns:${prefix}`, ns);
|
|
1444
|
+
else if (ns && !prefix) root.setAttribute("xmlns", ns);
|
|
1445
|
+
const allNamespaces = collectAllNamespaces(schema);
|
|
1446
|
+
for (const [pfx, uri] of allNamespaces) if (pfx && pfx !== prefix) root.setAttribute(`xmlns:${pfx}`, uri);
|
|
1447
|
+
else if (!pfx) root.setAttribute("xmlns", uri);
|
|
1448
|
+
return root;
|
|
1449
|
+
}
|
|
1450
|
+
/**
|
|
1451
|
+
* Remove xmlns declarations from the root element for prefixes that are
|
|
1452
|
+
* not actually used anywhere in the document tree.
|
|
1453
|
+
*
|
|
1454
|
+
* This prevents emitting unused namespace declarations (e.g. xmlns:abapsource,
|
|
1455
|
+
* xmlns:abapoo) that come from the schema's $imports chain but aren't
|
|
1456
|
+
* referenced by any element or attribute in the built XML.
|
|
1457
|
+
*
|
|
1458
|
+
* The prefix that maps to the schema's own targetNamespace is always
|
|
1459
|
+
* preserved — even when elementFormDefault="unqualified" causes the root
|
|
1460
|
+
* element to be emitted without a prefix, the xmlns declaration is still
|
|
1461
|
+
* required for the document to be in the correct namespace.
|
|
1462
|
+
*/
|
|
1463
|
+
/**
|
|
1464
|
+
* Add namespace prefix from a qualified name to the set (if present).
|
|
1465
|
+
*/
|
|
1466
|
+
function addPrefixFromName(name, usedPrefixes) {
|
|
1467
|
+
const colon = name.indexOf(":");
|
|
1468
|
+
if (colon > 0) usedPrefixes.add(name.substring(0, colon));
|
|
1469
|
+
}
|
|
1470
|
+
/**
|
|
1471
|
+
* Collect namespace prefixes referenced by attributes on a single element
|
|
1472
|
+
* (xmlns declarations are skipped — they declare rather than use prefixes).
|
|
1473
|
+
*/
|
|
1474
|
+
function collectPrefixesFromAttributes(node, usedPrefixes) {
|
|
1475
|
+
if (!node.attributes) return;
|
|
1476
|
+
for (const attr of Array.from(node.attributes)) if (!attr.name.startsWith("xmlns:") && attr.name !== "xmlns") addPrefixFromName(attr.name, usedPrefixes);
|
|
1477
|
+
}
|
|
1478
|
+
/**
|
|
1479
|
+
* Collect prefixes used by elements and attributes in the tree (recursive walk).
|
|
1480
|
+
*/
|
|
1481
|
+
function collectUsedPrefixes(node, usedPrefixes) {
|
|
1482
|
+
addPrefixFromName(node.tagName, usedPrefixes);
|
|
1483
|
+
collectPrefixesFromAttributes(node, usedPrefixes);
|
|
1484
|
+
if (node.childNodes) {
|
|
1485
|
+
for (const child of Array.from(node.childNodes)) if (child.nodeType === 1) collectUsedPrefixes(child, usedPrefixes);
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
/**
|
|
1489
|
+
* Collect xmlns:prefix attribute names on the root element whose prefix
|
|
1490
|
+
* is not in the used-prefixes set.
|
|
1491
|
+
*/
|
|
1492
|
+
function findUnusedXmlnsAttrs(root, usedPrefixes) {
|
|
1493
|
+
const toRemove = [];
|
|
1494
|
+
if (!root.attributes) return toRemove;
|
|
1495
|
+
for (const attr of Array.from(root.attributes)) if (attr.name.startsWith("xmlns:")) {
|
|
1496
|
+
const pfx = attr.name.substring(6);
|
|
1497
|
+
if (!usedPrefixes.has(pfx)) toRemove.push(attr.name);
|
|
1498
|
+
}
|
|
1499
|
+
return toRemove;
|
|
1500
|
+
}
|
|
1501
|
+
function stripUnusedNamespaces(root, schema) {
|
|
1502
|
+
const usedPrefixes = /* @__PURE__ */ new Set();
|
|
1503
|
+
if (schema?.targetNamespace && schema.$xmlns) {
|
|
1504
|
+
for (const [pfx, uri] of Object.entries(schema.$xmlns)) if (pfx && uri === schema.targetNamespace) usedPrefixes.add(pfx);
|
|
1505
|
+
}
|
|
1506
|
+
collectUsedPrefixes(root, usedPrefixes);
|
|
1507
|
+
for (const name of findUnusedXmlnsAttrs(root, usedPrefixes)) root.removeAttribute(name);
|
|
1508
|
+
}
|
|
1509
|
+
/**
|
|
1510
|
+
* Format value for XML output
|
|
1511
|
+
*/
|
|
1512
|
+
function formatValue(value, type) {
|
|
1513
|
+
if (value instanceof Date) return stripNsPrefix(type) === "date" ? value.toISOString().split("T")[0] : value.toISOString();
|
|
1514
|
+
if (typeof value === "boolean") return value ? "true" : "false";
|
|
1515
|
+
return String(value);
|
|
1516
|
+
}
|
|
1517
|
+
/**
|
|
1518
|
+
* Simple XML formatter (basic indentation)
|
|
1519
|
+
*
|
|
1520
|
+
* Keeps text content inline: <tag>text</tag>
|
|
1521
|
+
* Only adds newlines for nested elements
|
|
1522
|
+
*/
|
|
1523
|
+
function formatXml(xml) {
|
|
1524
|
+
let formatted = "";
|
|
1525
|
+
let indent = 0;
|
|
1526
|
+
const parts = [];
|
|
1527
|
+
let pos = 0;
|
|
1528
|
+
while (pos < xml.length) if (xml.charCodeAt(pos) === 60) {
|
|
1529
|
+
const end = xml.indexOf(">", pos + 1);
|
|
1530
|
+
if (end === -1) {
|
|
1531
|
+
parts.push(xml.slice(pos));
|
|
1532
|
+
break;
|
|
1533
|
+
}
|
|
1534
|
+
parts.push(xml.slice(pos, end + 1));
|
|
1535
|
+
pos = end + 1;
|
|
1536
|
+
} else {
|
|
1537
|
+
const next = xml.indexOf("<", pos);
|
|
1538
|
+
if (next === -1) {
|
|
1539
|
+
parts.push(xml.slice(pos));
|
|
1540
|
+
break;
|
|
1541
|
+
}
|
|
1542
|
+
if (next > pos) parts.push(xml.slice(pos, next));
|
|
1543
|
+
pos = next;
|
|
1544
|
+
}
|
|
1545
|
+
let lastWasText = false;
|
|
1546
|
+
for (let i = 0; i < parts.length; i++) {
|
|
1547
|
+
const part = parts[i];
|
|
1548
|
+
const nextPart = parts[i + 1];
|
|
1549
|
+
if (part.startsWith("<?")) {
|
|
1550
|
+
formatted += part + "\n";
|
|
1551
|
+
lastWasText = false;
|
|
1552
|
+
} else if (part.startsWith("</")) {
|
|
1553
|
+
indent = Math.max(0, indent - 1);
|
|
1554
|
+
if (lastWasText) formatted += part + "\n";
|
|
1555
|
+
else formatted += " ".repeat(indent) + part + "\n";
|
|
1556
|
+
lastWasText = false;
|
|
1557
|
+
} else if (part.startsWith("<") && part.endsWith("/>")) {
|
|
1558
|
+
formatted += " ".repeat(indent) + part + "\n";
|
|
1559
|
+
lastWasText = false;
|
|
1560
|
+
} else if (part.startsWith("<")) {
|
|
1561
|
+
formatted += " ".repeat(indent) + part;
|
|
1562
|
+
if (!part.includes("</")) indent++;
|
|
1563
|
+
if (nextPart && !nextPart.startsWith("<")) {} else formatted += "\n";
|
|
1564
|
+
lastWasText = false;
|
|
1565
|
+
} else {
|
|
1566
|
+
const trimmed = part.trim();
|
|
1567
|
+
if (trimmed) {
|
|
1568
|
+
formatted += trimmed;
|
|
1569
|
+
lastWasText = true;
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
return formatted.trim();
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
//#endregion
|
|
1577
|
+
//#region src/xml/build.ts
|
|
1578
|
+
/**
|
|
1579
|
+
* XML Builder for W3C Schema (Walker-based implementation)
|
|
1580
|
+
*
|
|
1581
|
+
* Build XML string from typed JavaScript object using W3C-compliant Schema definition.
|
|
1582
|
+
* Uses the walker module for schema traversal.
|
|
1583
|
+
*/
|
|
1584
|
+
/**
|
|
1585
|
+
* Collect all namespace prefixes from a schema and its $imports chain
|
|
1586
|
+
*/
|
|
1587
|
+
function collectAllXmlns(schema, visited = /* @__PURE__ */ new Set()) {
|
|
1588
|
+
if (visited.has(schema)) return {};
|
|
1589
|
+
visited.add(schema);
|
|
1590
|
+
const result = {};
|
|
1591
|
+
const xmlns = schema.$xmlns;
|
|
1592
|
+
if (xmlns) Object.assign(result, xmlns);
|
|
1593
|
+
const imports = schema.$imports;
|
|
1594
|
+
if (imports) for (const imported of imports) Object.assign(result, collectAllXmlns(imported, visited));
|
|
1595
|
+
return result;
|
|
1596
|
+
}
|
|
1597
|
+
/**
|
|
1598
|
+
* Get the namespace prefix for a schema's targetNamespace from the root schema's $xmlns
|
|
1599
|
+
* and all imported schemas' $xmlns (for inherited attributes)
|
|
1600
|
+
*/
|
|
1601
|
+
function getPrefixForSchema(schema, rootSchema) {
|
|
1602
|
+
const targetNs = schema.targetNamespace;
|
|
1603
|
+
if (!targetNs) return void 0;
|
|
1604
|
+
const allXmlns = collectAllXmlns(rootSchema);
|
|
1605
|
+
for (const [prefix, ns] of Object.entries(allXmlns)) if (ns === targetNs) return prefix;
|
|
1606
|
+
}
|
|
1607
|
+
/**
|
|
1608
|
+
* Build XML string from typed object using schema definition
|
|
1609
|
+
*/
|
|
1610
|
+
function build(schema, data, options = {}) {
|
|
1611
|
+
const { xmlDecl = true, encoding = "utf-8", pretty = false } = options;
|
|
1612
|
+
const prefix = options.prefix ?? getSchemaPrefix(schema);
|
|
1613
|
+
const doc = createXmlDocument(schema);
|
|
1614
|
+
let elementDecl;
|
|
1615
|
+
let elementSchema = schema;
|
|
1616
|
+
let elementData = data;
|
|
1617
|
+
if (options.rootElement) {
|
|
1618
|
+
const found = findElement(options.rootElement, schema);
|
|
1619
|
+
if (!found) throw new Error(`Element '${options.rootElement}' not found in schema`);
|
|
1620
|
+
elementDecl = found.element;
|
|
1621
|
+
elementSchema = found.schema;
|
|
1622
|
+
if (elementData[options.rootElement] !== void 0) elementData = elementData[options.rootElement];
|
|
1623
|
+
} else {
|
|
1624
|
+
const dataKeys = Object.keys(elementData);
|
|
1625
|
+
if (dataKeys.length === 1) {
|
|
1626
|
+
const potentialElementName = dataKeys[0];
|
|
1627
|
+
const found = findElement(potentialElementName, schema);
|
|
1628
|
+
if (found) {
|
|
1629
|
+
elementDecl = found.element;
|
|
1630
|
+
elementSchema = found.schema;
|
|
1631
|
+
elementData = elementData[potentialElementName];
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
if (!elementDecl) {
|
|
1635
|
+
elementDecl = findMatchingElement(elementData, schema);
|
|
1636
|
+
if (!elementDecl) throw new Error("Schema has no element declarations");
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
let rootType;
|
|
1640
|
+
let rootSchema = elementSchema;
|
|
1641
|
+
if (elementDecl.complexType) rootType = elementDecl.complexType;
|
|
1642
|
+
else if (elementDecl.type) {
|
|
1643
|
+
const typeName = stripNsPrefix(elementDecl.type);
|
|
1644
|
+
const rootTypeEntry = findComplexType(typeName, elementSchema);
|
|
1645
|
+
if (!rootTypeEntry) throw new Error(`Schema missing complexType for: ${typeName}`);
|
|
1646
|
+
rootType = rootTypeEntry.ct;
|
|
1647
|
+
rootSchema = rootTypeEntry.schema;
|
|
1648
|
+
} else throw new Error(`Element ${elementDecl.name} has no type or inline complexType`);
|
|
1649
|
+
const elementName = elementDecl.name ?? elementDecl.ref;
|
|
1650
|
+
if (!elementName) throw new Error("Element declaration has no name or ref");
|
|
1651
|
+
const root = createRootElement(doc, elementName, schema, prefix);
|
|
1652
|
+
buildElement(doc, root, elementData, rootType, rootSchema, schema, prefix);
|
|
1653
|
+
stripUnusedNamespaces(root, schema);
|
|
1654
|
+
if (!root.hasChildNodes()) root.appendChild(doc.createTextNode(""));
|
|
1655
|
+
doc.appendChild(root);
|
|
1656
|
+
let xml = new XMLSerializer().serializeToString(doc);
|
|
1657
|
+
if (xmlDecl) xml = `<?xml version="1.0" encoding="${encoding}"?>\n${xml}`;
|
|
1658
|
+
if (pretty) xml = formatXml(xml);
|
|
1659
|
+
return xml;
|
|
1660
|
+
}
|
|
1661
|
+
/**
|
|
1662
|
+
* Find the element declaration that best matches the data structure.
|
|
1663
|
+
* Searches in the main schema first, then in $imports.
|
|
1664
|
+
*/
|
|
1665
|
+
function findMatchingElement(data, schema) {
|
|
1666
|
+
const dataKeys = new Set(Object.keys(data));
|
|
1667
|
+
let bestMatch;
|
|
1668
|
+
let bestScore = -1;
|
|
1669
|
+
const scoreElement = (element, searchSchema) => {
|
|
1670
|
+
let ct;
|
|
1671
|
+
let ctSchema = searchSchema;
|
|
1672
|
+
if (element.complexType) ct = element.complexType;
|
|
1673
|
+
else if (element.type) {
|
|
1674
|
+
const typeName = stripNsPrefix(element.type);
|
|
1675
|
+
const typeEntry = findComplexType(typeName, searchSchema);
|
|
1676
|
+
if (typeEntry) {
|
|
1677
|
+
ct = typeEntry.ct;
|
|
1678
|
+
ctSchema = typeEntry.schema;
|
|
1679
|
+
}
|
|
1680
|
+
}
|
|
1681
|
+
if (!ct) return 0;
|
|
1682
|
+
const typeFields = /* @__PURE__ */ new Set();
|
|
1683
|
+
for (const { element: el } of walkElements(ct, ctSchema)) if (el.name) typeFields.add(el.name);
|
|
1684
|
+
for (const { attribute } of walkAttributes(ct, ctSchema)) if (attribute.name) typeFields.add(attribute.name);
|
|
1685
|
+
let score = 0;
|
|
1686
|
+
dataKeys.forEach((key) => {
|
|
1687
|
+
if (typeFields.has(key)) score++;
|
|
1688
|
+
});
|
|
1689
|
+
return score;
|
|
1690
|
+
};
|
|
1691
|
+
const elements = schema.element;
|
|
1692
|
+
if (elements && elements.length > 0) for (const element of elements) {
|
|
1693
|
+
const score = scoreElement(element, schema);
|
|
1694
|
+
if (score > bestScore) {
|
|
1695
|
+
bestScore = score;
|
|
1696
|
+
bestMatch = element;
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
const imports = schema.$imports;
|
|
1700
|
+
if (imports) for (const importedSchema of imports) {
|
|
1701
|
+
const importedElements = importedSchema.element;
|
|
1702
|
+
if (!importedElements) continue;
|
|
1703
|
+
for (const element of importedElements) {
|
|
1704
|
+
const score = scoreElement(element, importedSchema);
|
|
1705
|
+
if (score > bestScore) {
|
|
1706
|
+
bestScore = score;
|
|
1707
|
+
bestMatch = element;
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1711
|
+
if (!bestMatch && elements && elements.length > 0) return elements[0];
|
|
1712
|
+
return bestMatch;
|
|
1713
|
+
}
|
|
1714
|
+
/**
|
|
1715
|
+
* Build element content using its complexType definition
|
|
1716
|
+
* Uses walker to iterate elements and attributes (handles inheritance automatically)
|
|
1717
|
+
* @param rootSchema - The original schema passed to build(), used for substitution group lookup
|
|
1718
|
+
*/
|
|
1719
|
+
function buildElement(doc, node, data, typeDef, schema, rootSchema, prefix) {
|
|
1720
|
+
for (const { attribute, schema: attrSchema } of walkAttributes(typeDef, schema)) {
|
|
1721
|
+
if (!attribute.name) continue;
|
|
1722
|
+
const value = data[attribute.name];
|
|
1723
|
+
if (value !== void 0 && value !== null) {
|
|
1724
|
+
const attributeFormDefault = attrSchema.attributeFormDefault;
|
|
1725
|
+
const attrForm = attribute.form;
|
|
1726
|
+
let attrName = attribute.name;
|
|
1727
|
+
if (attrForm === "qualified" || attrForm !== "unqualified" && attributeFormDefault === "qualified") {
|
|
1728
|
+
const attrPrefix = getPrefixForSchema(attrSchema, rootSchema);
|
|
1729
|
+
if (attrPrefix) attrName = `${attrPrefix}:${attribute.name}`;
|
|
1730
|
+
}
|
|
1731
|
+
node.setAttribute(attrName, formatValue(value, attribute.type || "string"));
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1734
|
+
for (const { element, schema: elementDefSchema } of walkElements(typeDef, schema)) {
|
|
1735
|
+
if (element.ref) {
|
|
1736
|
+
const refName = stripNsPrefix(element.ref);
|
|
1737
|
+
const refElement = findElement(refName, elementDefSchema);
|
|
1738
|
+
if (refElement && refElement.element.abstract) {
|
|
1739
|
+
const substitutes = findSubstitutes$1(refName, rootSchema);
|
|
1740
|
+
for (const substitute of substitutes) {
|
|
1741
|
+
const subName = substitute.element.name;
|
|
1742
|
+
if (!subName) continue;
|
|
1743
|
+
const value = data[subName];
|
|
1744
|
+
if (value != null) buildField(doc, node, value, subName, substitute.element.type ? stripNsPrefix(substitute.element.type) : void 0, substitute.schema, rootSchema, prefix);
|
|
1745
|
+
}
|
|
1746
|
+
continue;
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
const resolved = resolveElementInfo(element, elementDefSchema);
|
|
1750
|
+
if (!resolved) continue;
|
|
1751
|
+
const value = data[resolved.dataKey];
|
|
1752
|
+
if (value != null) buildFieldWithTagName(doc, node, value, resolved.tagName, resolved.typeName, resolved.inlineComplexType, resolved.elementSchema, rootSchema, prefix, resolved.form);
|
|
1753
|
+
}
|
|
1754
|
+
}
|
|
1755
|
+
/**
|
|
1756
|
+
* Resolve element info (name and type), handling ref
|
|
1757
|
+
*
|
|
1758
|
+
* Returns:
|
|
1759
|
+
* - tagName: The XML tag name to use (may include prefix like "asx:abap")
|
|
1760
|
+
* - dataKey: The key to look up in data object (local name without prefix)
|
|
1761
|
+
* - typeName: The type name for building nested content (if type attribute)
|
|
1762
|
+
* - inlineComplexType: The inline complexType definition (if present)
|
|
1763
|
+
* - elementSchema: The schema where the element was found
|
|
1764
|
+
* - form: Per-element form override ("qualified" or "unqualified")
|
|
1765
|
+
*/
|
|
1766
|
+
function resolveElementInfo(element, schema) {
|
|
1767
|
+
if (element.name) return {
|
|
1768
|
+
tagName: element.name,
|
|
1769
|
+
dataKey: element.name,
|
|
1770
|
+
typeName: element.type ? stripNsPrefix(element.type) : void 0,
|
|
1771
|
+
inlineComplexType: element.complexType,
|
|
1772
|
+
elementSchema: schema,
|
|
1773
|
+
form: element.form
|
|
1774
|
+
};
|
|
1775
|
+
if (element.ref) {
|
|
1776
|
+
const refName = stripNsPrefix(element.ref);
|
|
1777
|
+
const refElement = findElement(refName, schema);
|
|
1778
|
+
if (refElement) return {
|
|
1779
|
+
tagName: element.ref,
|
|
1780
|
+
dataKey: refElement.element.name ?? refName,
|
|
1781
|
+
typeName: refElement.element.type ? stripNsPrefix(refElement.element.type) : void 0,
|
|
1782
|
+
inlineComplexType: refElement.element.complexType,
|
|
1783
|
+
elementSchema: refElement.schema,
|
|
1784
|
+
form: void 0
|
|
1785
|
+
};
|
|
1786
|
+
return {
|
|
1787
|
+
tagName: element.ref,
|
|
1788
|
+
dataKey: refName,
|
|
1789
|
+
typeName: void 0,
|
|
1790
|
+
inlineComplexType: void 0,
|
|
1791
|
+
elementSchema: schema,
|
|
1792
|
+
form: void 0
|
|
1793
|
+
};
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1796
|
+
/**
|
|
1797
|
+
* Build a field (child element)
|
|
1798
|
+
*
|
|
1799
|
+
* Respects elementFormDefault:
|
|
1800
|
+
* - "qualified": local elements get namespace prefix
|
|
1801
|
+
* - "unqualified" (default): local elements do NOT get namespace prefix
|
|
1802
|
+
*/
|
|
1803
|
+
function buildField(doc, parent, value, elementName, typeName, schema, rootSchema, prefix) {
|
|
1804
|
+
const nestedType = typeName ? findComplexType(typeName, schema) : void 0;
|
|
1805
|
+
const usePrefix = rootSchema.elementFormDefault === "qualified" ? prefix : void 0;
|
|
1806
|
+
const tagName = usePrefix ? `${usePrefix}:${elementName}` : elementName;
|
|
1807
|
+
if (Array.isArray(value)) for (const item of value) {
|
|
1808
|
+
const child = doc.createElement(tagName);
|
|
1809
|
+
if (nestedType) buildElement(doc, child, item, nestedType.ct, nestedType.schema, rootSchema, prefix);
|
|
1810
|
+
else {
|
|
1811
|
+
const text = formatValue(item, typeName || "string");
|
|
1812
|
+
if (text) child.appendChild(doc.createTextNode(text));
|
|
1813
|
+
}
|
|
1814
|
+
parent.appendChild(child);
|
|
1815
|
+
}
|
|
1816
|
+
else {
|
|
1817
|
+
const child = doc.createElement(tagName);
|
|
1818
|
+
if (nestedType) buildElement(doc, child, value, nestedType.ct, nestedType.schema, rootSchema, prefix);
|
|
1819
|
+
else {
|
|
1820
|
+
const text = formatValue(value, typeName || "string");
|
|
1821
|
+
if (text) child.appendChild(doc.createTextNode(text));
|
|
1822
|
+
}
|
|
1823
|
+
parent.appendChild(child);
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
/**
|
|
1827
|
+
* Build a field with an explicit tag name (used for element refs with prefix)
|
|
1828
|
+
*
|
|
1829
|
+
* Handles three cases:
|
|
1830
|
+
* 1. Element refs with prefix (e.g., ref="asx:abap") - use tagName directly
|
|
1831
|
+
* 2. Elements with form="unqualified" - never use prefix
|
|
1832
|
+
* 3. Direct elements - apply elementFormDefault logic
|
|
1833
|
+
*/
|
|
1834
|
+
function buildFieldWithTagName(doc, parent, value, tagName, typeName, inlineComplexType, elementSchema, rootSchema, prefix, elementForm) {
|
|
1835
|
+
let nestedType;
|
|
1836
|
+
if (inlineComplexType) nestedType = {
|
|
1837
|
+
ct: inlineComplexType,
|
|
1838
|
+
schema: elementSchema
|
|
1839
|
+
};
|
|
1840
|
+
else if (typeName) nestedType = findComplexType(typeName, elementSchema);
|
|
1841
|
+
let actualTagName = tagName;
|
|
1842
|
+
if (!tagName.includes(":")) {
|
|
1843
|
+
let usePrefix;
|
|
1844
|
+
if (elementForm === "unqualified") usePrefix = void 0;
|
|
1845
|
+
else if (elementForm === "qualified") usePrefix = getPrefixForSchema(elementSchema, rootSchema) ?? prefix;
|
|
1846
|
+
else usePrefix = (elementSchema.elementFormDefault ?? rootSchema.elementFormDefault) === "qualified" ? getPrefixForSchema(elementSchema, rootSchema) ?? prefix : void 0;
|
|
1847
|
+
actualTagName = usePrefix ? `${usePrefix}:${tagName}` : tagName;
|
|
1848
|
+
}
|
|
1849
|
+
if (Array.isArray(value)) for (const item of value) {
|
|
1850
|
+
const child = doc.createElement(actualTagName);
|
|
1851
|
+
if (nestedType) buildElement(doc, child, item, nestedType.ct, nestedType.schema, rootSchema, prefix);
|
|
1852
|
+
else {
|
|
1853
|
+
const text = formatValue(item, typeName || "string");
|
|
1854
|
+
if (text) child.appendChild(doc.createTextNode(text));
|
|
1855
|
+
}
|
|
1856
|
+
parent.appendChild(child);
|
|
1857
|
+
}
|
|
1858
|
+
else {
|
|
1859
|
+
const child = doc.createElement(actualTagName);
|
|
1860
|
+
if (nestedType) buildElement(doc, child, value, nestedType.ct, nestedType.schema, rootSchema, prefix);
|
|
1861
|
+
else {
|
|
1862
|
+
const text = formatValue(value, typeName || "string");
|
|
1863
|
+
if (text) child.appendChild(doc.createTextNode(text));
|
|
1864
|
+
}
|
|
1865
|
+
parent.appendChild(child);
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
/**
|
|
1869
|
+
* Find all elements that substitute for a given abstract element name.
|
|
1870
|
+
* Searches in the main schema and all $imports.
|
|
1871
|
+
*/
|
|
1872
|
+
function findSubstitutes$1(abstractElementName, schema) {
|
|
1873
|
+
const substitutes = [];
|
|
1874
|
+
const searchSchema = (s) => {
|
|
1875
|
+
const elements = s.element;
|
|
1876
|
+
if (!elements) return;
|
|
1877
|
+
for (const el of elements) if (el.substitutionGroup) {
|
|
1878
|
+
if (stripNsPrefix(el.substitutionGroup) === abstractElementName) substitutes.push({
|
|
1879
|
+
element: el,
|
|
1880
|
+
schema: s
|
|
1881
|
+
});
|
|
1882
|
+
}
|
|
1883
|
+
};
|
|
1884
|
+
searchSchema(schema);
|
|
1885
|
+
const imports = schema.$imports;
|
|
1886
|
+
if (imports) for (const imported of imports) searchSchema(imported);
|
|
1887
|
+
return substitutes;
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1890
|
+
//#endregion
|
|
1891
|
+
//#region src/xml/typed.ts
|
|
1892
|
+
/**
|
|
1893
|
+
* Create a typed schema wrapper
|
|
1894
|
+
*
|
|
1895
|
+
* @param schema - Raw schema literal (with `as const`)
|
|
1896
|
+
* @returns Typed schema with parse/build methods
|
|
1897
|
+
*
|
|
1898
|
+
* @example
|
|
1899
|
+
* ```typescript
|
|
1900
|
+
* // Infer type from schema
|
|
1901
|
+
* const personSchema = typedSchema(rawPersonSchema);
|
|
1902
|
+
* const person = personSchema.parse(xml);
|
|
1903
|
+
*
|
|
1904
|
+
* // Or with explicit type
|
|
1905
|
+
* const personSchema = typedSchema<PersonType>(rawPersonSchema);
|
|
1906
|
+
* ```
|
|
1907
|
+
*/
|
|
1908
|
+
function typedSchema(schema) {
|
|
1909
|
+
return {
|
|
1910
|
+
_type: null,
|
|
1911
|
+
schema,
|
|
1912
|
+
parse(xml) {
|
|
1913
|
+
return parse(schema, xml);
|
|
1914
|
+
},
|
|
1915
|
+
build(data, options) {
|
|
1916
|
+
return build(schema, data, options);
|
|
1917
|
+
}
|
|
1918
|
+
};
|
|
1919
|
+
}
|
|
1920
|
+
|
|
1921
|
+
//#endregion
|
|
1922
|
+
export { SchemaResolver, SchemaTraverser, build as buildXml, buildXsd, createSchemaLoader, defaultLoader, defineConfig, deriveRootTypeName, findComplexType, findElement, findSimpleType, findSubstitutes, generateInterfaces, generateSchemaFile, generateSchemaLiteral, getSubstitutes, isAbstractElement, linkSchema, linkSchemas, loadAndLinkSchema, loadSchema, parseXsd as parse, parseXsd, parseSchemaContent, parse as parseXml, resolveImports, resolveSchema, resolveSchemaTypes, runCodegen, stripNsPrefix, typedSchema, walkAttributes, walkComplexTypes, walkElements, walkSimpleTypes, walkTopLevelElements };
|
|
1923
|
+
//# sourceMappingURL=index.mjs.map
|