xslt-processor 4.7.0 → 4.8.0
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/index.d.mts +99 -0
- package/index.d.ts +99 -0
- package/index.js +307 -1
- package/index.js.map +1 -1
- package/index.mjs +307 -1
- package/index.mjs.map +1 -1
- package/package.json +1 -1
- package/umd/xslt-processor.global.js +5 -5
- package/umd/xslt-processor.global.js.map +1 -1
package/index.d.mts
CHANGED
|
@@ -278,6 +278,14 @@ declare class ExprContext {
|
|
|
278
278
|
* Contains the key value of the current group being processed.
|
|
279
279
|
*/
|
|
280
280
|
currentGroupingKey?: any;
|
|
281
|
+
/**
|
|
282
|
+
* User-defined XSLT functions from xsl:function declarations.
|
|
283
|
+
* Maps QName (namespace:localname) to function definition info.
|
|
284
|
+
*/
|
|
285
|
+
userDefinedFunctions?: Map<string, {
|
|
286
|
+
functionDef: XNode;
|
|
287
|
+
executor: (context: ExprContext, functionDef: XNode, args: any[]) => any;
|
|
288
|
+
}>;
|
|
281
289
|
/**
|
|
282
290
|
* Constructor -- gets the node, its position, the node set it
|
|
283
291
|
* belongs to, and a parent context as arguments. The parent context
|
|
@@ -790,6 +798,16 @@ declare class Xslt {
|
|
|
790
798
|
* Keys are attribute set names, values are arrays of xsl:attribute nodes.
|
|
791
799
|
*/
|
|
792
800
|
attributeSets: Map<string, XNode[]>;
|
|
801
|
+
/**
|
|
802
|
+
* Map of user-defined functions from xsl:function declarations.
|
|
803
|
+
* Keys are QNames (namespace:localname), values are the function definition nodes.
|
|
804
|
+
*/
|
|
805
|
+
userDefinedFunctions: Map<string, XNode>;
|
|
806
|
+
/**
|
|
807
|
+
* Result documents created by xsl:result-document.
|
|
808
|
+
* Keys are the href URIs, values are the serialized output strings.
|
|
809
|
+
*/
|
|
810
|
+
resultDocuments: Map<string, string>;
|
|
793
811
|
/**
|
|
794
812
|
* Stack of stylesheet metadata for tracking import hierarchy.
|
|
795
813
|
* Used by apply-imports to find templates from imported stylesheets.
|
|
@@ -1343,6 +1361,74 @@ declare class Xslt {
|
|
|
1343
1361
|
* Sets up the context with the current text and regex groups.
|
|
1344
1362
|
*/
|
|
1345
1363
|
private processAnalyzeStringContent;
|
|
1364
|
+
/**
|
|
1365
|
+
* Implements `xsl:function` (XSLT 2.0).
|
|
1366
|
+
*
|
|
1367
|
+
* Declares a stylesheet function that can be called from XPath expressions.
|
|
1368
|
+
* Functions are collected during stylesheet initialization and made available
|
|
1369
|
+
* to the XPath evaluator.
|
|
1370
|
+
*
|
|
1371
|
+
* @param context The expression context.
|
|
1372
|
+
* @param template The xsl:function element.
|
|
1373
|
+
*/
|
|
1374
|
+
protected xsltFunction(context: ExprContext, template: XNode): void;
|
|
1375
|
+
/**
|
|
1376
|
+
* Execute a user-defined xsl:function.
|
|
1377
|
+
* Called when a function from userDefinedFunctions is invoked from XPath.
|
|
1378
|
+
*
|
|
1379
|
+
* @param context The expression context.
|
|
1380
|
+
* @param functionDef The xsl:function node.
|
|
1381
|
+
* @param args The evaluated arguments passed to the function.
|
|
1382
|
+
* @returns The result of the function execution.
|
|
1383
|
+
*/
|
|
1384
|
+
protected executeUserDefinedFunction(context: ExprContext, functionDef: XNode, args: any[]): Promise<any>;
|
|
1385
|
+
/**
|
|
1386
|
+
* Synchronously execute a user-defined xsl:function.
|
|
1387
|
+
* This is used when functions are called from XPath expressions.
|
|
1388
|
+
* Limited to functions that don't require async operations in their body.
|
|
1389
|
+
*
|
|
1390
|
+
* @param context The expression context.
|
|
1391
|
+
* @param functionDef The xsl:function node.
|
|
1392
|
+
* @param args The evaluated arguments passed to the function.
|
|
1393
|
+
* @returns The result of the function execution.
|
|
1394
|
+
*/
|
|
1395
|
+
executeUserDefinedFunctionSync(context: ExprContext, functionDef: XNode, args: any[]): any;
|
|
1396
|
+
/**
|
|
1397
|
+
* Implements `xsl:result-document` (XSLT 2.0).
|
|
1398
|
+
*
|
|
1399
|
+
* Creates a secondary output document. The output is stored in the
|
|
1400
|
+
* resultDocuments map, accessible via getResultDocuments().
|
|
1401
|
+
*
|
|
1402
|
+
* @param context The expression context.
|
|
1403
|
+
* @param template The xsl:result-document element.
|
|
1404
|
+
*/
|
|
1405
|
+
protected xsltResultDocument(context: ExprContext, template: XNode): Promise<void>;
|
|
1406
|
+
/**
|
|
1407
|
+
* Get all result documents created by xsl:result-document.
|
|
1408
|
+
* @returns A map of href URIs to serialized output strings.
|
|
1409
|
+
*/
|
|
1410
|
+
getResultDocuments(): Map<string, string>;
|
|
1411
|
+
/**
|
|
1412
|
+
* Implements `xsl:perform-sort` (XSLT 2.0).
|
|
1413
|
+
*
|
|
1414
|
+
* Sorts a sequence of items without iteration. The sorted sequence
|
|
1415
|
+
* is available via xsl:sequence or other sequence-consuming instructions.
|
|
1416
|
+
*
|
|
1417
|
+
* @param context The expression context.
|
|
1418
|
+
* @param template The xsl:perform-sort element.
|
|
1419
|
+
* @param output The output node.
|
|
1420
|
+
*/
|
|
1421
|
+
protected xsltPerformSort(context: ExprContext, template: XNode, output?: XNode): Promise<void>;
|
|
1422
|
+
/**
|
|
1423
|
+
* Implements `xsl:namespace` (XSLT 2.0).
|
|
1424
|
+
*
|
|
1425
|
+
* Creates a namespace node in the result tree.
|
|
1426
|
+
*
|
|
1427
|
+
* @param context The expression context.
|
|
1428
|
+
* @param template The xsl:namespace element.
|
|
1429
|
+
* @param output The output node.
|
|
1430
|
+
*/
|
|
1431
|
+
protected xsltNamespace(context: ExprContext, template: XNode, output?: XNode): Promise<void>;
|
|
1346
1432
|
/**
|
|
1347
1433
|
* Evaluates a variable or parameter and set it in the current input
|
|
1348
1434
|
* context. Implements `xsl:variable`, `xsl:param`, and `xsl:with-param`.
|
|
@@ -1454,6 +1540,19 @@ declare class Xslt {
|
|
|
1454
1540
|
* @param stylesheetElement The stylesheet or transform element.
|
|
1455
1541
|
*/
|
|
1456
1542
|
private collectAttributeSets;
|
|
1543
|
+
/**
|
|
1544
|
+
* Collect all user-defined function definitions from the stylesheet.
|
|
1545
|
+
* Called at stylesheet initialization time.
|
|
1546
|
+
* @param stylesheetElement The stylesheet or transform element.
|
|
1547
|
+
* @param context The expression context.
|
|
1548
|
+
*/
|
|
1549
|
+
private collectUserDefinedFunctions;
|
|
1550
|
+
/**
|
|
1551
|
+
* Register user-defined functions in the expression context.
|
|
1552
|
+
* This makes them available to XPath expressions.
|
|
1553
|
+
* @param context The expression context.
|
|
1554
|
+
*/
|
|
1555
|
+
private registerUserDefinedFunctionsInContext;
|
|
1457
1556
|
/**
|
|
1458
1557
|
* Apply one or more attribute sets to an element.
|
|
1459
1558
|
* Parses space-separated attribute set names and applies them.
|
package/index.d.ts
CHANGED
|
@@ -278,6 +278,14 @@ declare class ExprContext {
|
|
|
278
278
|
* Contains the key value of the current group being processed.
|
|
279
279
|
*/
|
|
280
280
|
currentGroupingKey?: any;
|
|
281
|
+
/**
|
|
282
|
+
* User-defined XSLT functions from xsl:function declarations.
|
|
283
|
+
* Maps QName (namespace:localname) to function definition info.
|
|
284
|
+
*/
|
|
285
|
+
userDefinedFunctions?: Map<string, {
|
|
286
|
+
functionDef: XNode;
|
|
287
|
+
executor: (context: ExprContext, functionDef: XNode, args: any[]) => any;
|
|
288
|
+
}>;
|
|
281
289
|
/**
|
|
282
290
|
* Constructor -- gets the node, its position, the node set it
|
|
283
291
|
* belongs to, and a parent context as arguments. The parent context
|
|
@@ -790,6 +798,16 @@ declare class Xslt {
|
|
|
790
798
|
* Keys are attribute set names, values are arrays of xsl:attribute nodes.
|
|
791
799
|
*/
|
|
792
800
|
attributeSets: Map<string, XNode[]>;
|
|
801
|
+
/**
|
|
802
|
+
* Map of user-defined functions from xsl:function declarations.
|
|
803
|
+
* Keys are QNames (namespace:localname), values are the function definition nodes.
|
|
804
|
+
*/
|
|
805
|
+
userDefinedFunctions: Map<string, XNode>;
|
|
806
|
+
/**
|
|
807
|
+
* Result documents created by xsl:result-document.
|
|
808
|
+
* Keys are the href URIs, values are the serialized output strings.
|
|
809
|
+
*/
|
|
810
|
+
resultDocuments: Map<string, string>;
|
|
793
811
|
/**
|
|
794
812
|
* Stack of stylesheet metadata for tracking import hierarchy.
|
|
795
813
|
* Used by apply-imports to find templates from imported stylesheets.
|
|
@@ -1343,6 +1361,74 @@ declare class Xslt {
|
|
|
1343
1361
|
* Sets up the context with the current text and regex groups.
|
|
1344
1362
|
*/
|
|
1345
1363
|
private processAnalyzeStringContent;
|
|
1364
|
+
/**
|
|
1365
|
+
* Implements `xsl:function` (XSLT 2.0).
|
|
1366
|
+
*
|
|
1367
|
+
* Declares a stylesheet function that can be called from XPath expressions.
|
|
1368
|
+
* Functions are collected during stylesheet initialization and made available
|
|
1369
|
+
* to the XPath evaluator.
|
|
1370
|
+
*
|
|
1371
|
+
* @param context The expression context.
|
|
1372
|
+
* @param template The xsl:function element.
|
|
1373
|
+
*/
|
|
1374
|
+
protected xsltFunction(context: ExprContext, template: XNode): void;
|
|
1375
|
+
/**
|
|
1376
|
+
* Execute a user-defined xsl:function.
|
|
1377
|
+
* Called when a function from userDefinedFunctions is invoked from XPath.
|
|
1378
|
+
*
|
|
1379
|
+
* @param context The expression context.
|
|
1380
|
+
* @param functionDef The xsl:function node.
|
|
1381
|
+
* @param args The evaluated arguments passed to the function.
|
|
1382
|
+
* @returns The result of the function execution.
|
|
1383
|
+
*/
|
|
1384
|
+
protected executeUserDefinedFunction(context: ExprContext, functionDef: XNode, args: any[]): Promise<any>;
|
|
1385
|
+
/**
|
|
1386
|
+
* Synchronously execute a user-defined xsl:function.
|
|
1387
|
+
* This is used when functions are called from XPath expressions.
|
|
1388
|
+
* Limited to functions that don't require async operations in their body.
|
|
1389
|
+
*
|
|
1390
|
+
* @param context The expression context.
|
|
1391
|
+
* @param functionDef The xsl:function node.
|
|
1392
|
+
* @param args The evaluated arguments passed to the function.
|
|
1393
|
+
* @returns The result of the function execution.
|
|
1394
|
+
*/
|
|
1395
|
+
executeUserDefinedFunctionSync(context: ExprContext, functionDef: XNode, args: any[]): any;
|
|
1396
|
+
/**
|
|
1397
|
+
* Implements `xsl:result-document` (XSLT 2.0).
|
|
1398
|
+
*
|
|
1399
|
+
* Creates a secondary output document. The output is stored in the
|
|
1400
|
+
* resultDocuments map, accessible via getResultDocuments().
|
|
1401
|
+
*
|
|
1402
|
+
* @param context The expression context.
|
|
1403
|
+
* @param template The xsl:result-document element.
|
|
1404
|
+
*/
|
|
1405
|
+
protected xsltResultDocument(context: ExprContext, template: XNode): Promise<void>;
|
|
1406
|
+
/**
|
|
1407
|
+
* Get all result documents created by xsl:result-document.
|
|
1408
|
+
* @returns A map of href URIs to serialized output strings.
|
|
1409
|
+
*/
|
|
1410
|
+
getResultDocuments(): Map<string, string>;
|
|
1411
|
+
/**
|
|
1412
|
+
* Implements `xsl:perform-sort` (XSLT 2.0).
|
|
1413
|
+
*
|
|
1414
|
+
* Sorts a sequence of items without iteration. The sorted sequence
|
|
1415
|
+
* is available via xsl:sequence or other sequence-consuming instructions.
|
|
1416
|
+
*
|
|
1417
|
+
* @param context The expression context.
|
|
1418
|
+
* @param template The xsl:perform-sort element.
|
|
1419
|
+
* @param output The output node.
|
|
1420
|
+
*/
|
|
1421
|
+
protected xsltPerformSort(context: ExprContext, template: XNode, output?: XNode): Promise<void>;
|
|
1422
|
+
/**
|
|
1423
|
+
* Implements `xsl:namespace` (XSLT 2.0).
|
|
1424
|
+
*
|
|
1425
|
+
* Creates a namespace node in the result tree.
|
|
1426
|
+
*
|
|
1427
|
+
* @param context The expression context.
|
|
1428
|
+
* @param template The xsl:namespace element.
|
|
1429
|
+
* @param output The output node.
|
|
1430
|
+
*/
|
|
1431
|
+
protected xsltNamespace(context: ExprContext, template: XNode, output?: XNode): Promise<void>;
|
|
1346
1432
|
/**
|
|
1347
1433
|
* Evaluates a variable or parameter and set it in the current input
|
|
1348
1434
|
* context. Implements `xsl:variable`, `xsl:param`, and `xsl:with-param`.
|
|
@@ -1454,6 +1540,19 @@ declare class Xslt {
|
|
|
1454
1540
|
* @param stylesheetElement The stylesheet or transform element.
|
|
1455
1541
|
*/
|
|
1456
1542
|
private collectAttributeSets;
|
|
1543
|
+
/**
|
|
1544
|
+
* Collect all user-defined function definitions from the stylesheet.
|
|
1545
|
+
* Called at stylesheet initialization time.
|
|
1546
|
+
* @param stylesheetElement The stylesheet or transform element.
|
|
1547
|
+
* @param context The expression context.
|
|
1548
|
+
*/
|
|
1549
|
+
private collectUserDefinedFunctions;
|
|
1550
|
+
/**
|
|
1551
|
+
* Register user-defined functions in the expression context.
|
|
1552
|
+
* This makes them available to XPath expressions.
|
|
1553
|
+
* @param context The expression context.
|
|
1554
|
+
*/
|
|
1555
|
+
private registerUserDefinedFunctionsInContext;
|
|
1457
1556
|
/**
|
|
1458
1557
|
* Apply one or more attribute sets to an element.
|
|
1459
1558
|
* Parses space-separated attribute set names and applies them.
|
package/index.js
CHANGED
|
@@ -6402,10 +6402,13 @@ var init_function_call_expression = __esm({
|
|
|
6402
6402
|
if (!this.name.includes(":")) {
|
|
6403
6403
|
return void 0;
|
|
6404
6404
|
}
|
|
6405
|
-
const [, localName] = this.name.split(":");
|
|
6405
|
+
const [prefix, localName] = this.name.split(":");
|
|
6406
6406
|
if (!localName) {
|
|
6407
6407
|
return void 0;
|
|
6408
6408
|
}
|
|
6409
|
+
if (prefix !== "xs") {
|
|
6410
|
+
return void 0;
|
|
6411
|
+
}
|
|
6409
6412
|
return getAtomicType(localName);
|
|
6410
6413
|
}
|
|
6411
6414
|
castConstructorValue(constructorType, value) {
|
|
@@ -9211,9 +9214,18 @@ var XPath20Parser = class extends XPathBaseParser {
|
|
|
9211
9214
|
return left;
|
|
9212
9215
|
}
|
|
9213
9216
|
parsePrimaryExpr() {
|
|
9217
|
+
var _a, _b;
|
|
9214
9218
|
if (this.check("RESERVED_WORD") && this.peek().lexeme === "if") {
|
|
9215
9219
|
return this.parseIfExpr();
|
|
9216
9220
|
}
|
|
9221
|
+
if (this.check("DOLLAR")) {
|
|
9222
|
+
this.advance();
|
|
9223
|
+
if (!this.isNameToken()) {
|
|
9224
|
+
throw new Error(`Expected variable name after $. Got: ${(_b = (_a = this.peek()) == null ? void 0 : _a.lexeme) != null ? _b : "EOF"}`);
|
|
9225
|
+
}
|
|
9226
|
+
const name = this.advance().lexeme;
|
|
9227
|
+
return new XPathVariableReference(name);
|
|
9228
|
+
}
|
|
9217
9229
|
return super.parsePrimaryExpr();
|
|
9218
9230
|
}
|
|
9219
9231
|
parseInstanceOfExpr() {
|
|
@@ -11935,6 +11947,20 @@ var NodeConverter = class {
|
|
|
11935
11947
|
}
|
|
11936
11948
|
return "";
|
|
11937
11949
|
};
|
|
11950
|
+
let ctx = exprContext;
|
|
11951
|
+
while (ctx) {
|
|
11952
|
+
if (ctx.userDefinedFunctions) {
|
|
11953
|
+
ctx.userDefinedFunctions.forEach((funcInfo, funcName) => {
|
|
11954
|
+
if (!functions[funcName]) {
|
|
11955
|
+
functions[funcName] = (_context, ...args) => {
|
|
11956
|
+
return funcInfo.executor(exprContext, funcInfo.functionDef, args);
|
|
11957
|
+
};
|
|
11958
|
+
}
|
|
11959
|
+
});
|
|
11960
|
+
break;
|
|
11961
|
+
}
|
|
11962
|
+
ctx = ctx.parent;
|
|
11963
|
+
}
|
|
11938
11964
|
return functions;
|
|
11939
11965
|
}
|
|
11940
11966
|
/**
|
|
@@ -13702,6 +13728,8 @@ var Xslt = class {
|
|
|
13702
13728
|
this.namespaceAliases = /* @__PURE__ */ new Map();
|
|
13703
13729
|
this.supportedExtensions = /* @__PURE__ */ new Set(["http://www.w3.org/1999/XSL/Transform"]);
|
|
13704
13730
|
this.attributeSets = /* @__PURE__ */ new Map();
|
|
13731
|
+
this.userDefinedFunctions = /* @__PURE__ */ new Map();
|
|
13732
|
+
this.resultDocuments = /* @__PURE__ */ new Map();
|
|
13705
13733
|
this.decimalFormatSettings = {
|
|
13706
13734
|
decimalSeparator: ".",
|
|
13707
13735
|
groupingSeparator: ",",
|
|
@@ -13856,6 +13884,9 @@ var Xslt = class {
|
|
|
13856
13884
|
case "for-each-group":
|
|
13857
13885
|
yield this.xsltForEachGroup(context, template, output);
|
|
13858
13886
|
break;
|
|
13887
|
+
case "function":
|
|
13888
|
+
this.xsltFunction(context, template);
|
|
13889
|
+
break;
|
|
13859
13890
|
case "iterate":
|
|
13860
13891
|
yield this.xsltIterate(context, template, output);
|
|
13861
13892
|
break;
|
|
@@ -13879,6 +13910,9 @@ var Xslt = class {
|
|
|
13879
13910
|
case "message":
|
|
13880
13911
|
yield this.xsltMessage(context, template);
|
|
13881
13912
|
break;
|
|
13913
|
+
case "namespace":
|
|
13914
|
+
yield this.xsltNamespace(context, template, output);
|
|
13915
|
+
break;
|
|
13882
13916
|
case "namespace-alias":
|
|
13883
13917
|
this.xsltNamespaceAlias(template);
|
|
13884
13918
|
break;
|
|
@@ -13917,9 +13951,15 @@ var Xslt = class {
|
|
|
13917
13951
|
case "preserve-space":
|
|
13918
13952
|
this.xsltPreserveSpace(template);
|
|
13919
13953
|
break;
|
|
13954
|
+
case "perform-sort":
|
|
13955
|
+
yield this.xsltPerformSort(context, template, output);
|
|
13956
|
+
break;
|
|
13920
13957
|
case "processing-instruction":
|
|
13921
13958
|
yield this.xsltProcessingInstruction(context, template, output);
|
|
13922
13959
|
break;
|
|
13960
|
+
case "result-document":
|
|
13961
|
+
yield this.xsltResultDocument(context, template);
|
|
13962
|
+
break;
|
|
13923
13963
|
case "sequence":
|
|
13924
13964
|
yield this.xsltSequence(context, template, output);
|
|
13925
13965
|
break;
|
|
@@ -15993,6 +16033,8 @@ var Xslt = class {
|
|
|
15993
16033
|
};
|
|
15994
16034
|
this.mapTemplatesFromStylesheet(template, mainStylesheetMetadata);
|
|
15995
16035
|
this.collectAttributeSets(template);
|
|
16036
|
+
this.collectUserDefinedFunctions(template, context);
|
|
16037
|
+
this.registerUserDefinedFunctionsInContext(context);
|
|
15996
16038
|
this.validateStylesheetAttributes(template, context);
|
|
15997
16039
|
let importsDone = false;
|
|
15998
16040
|
for (const child of template.childNodes) {
|
|
@@ -16296,6 +16338,237 @@ var Xslt = class {
|
|
|
16296
16338
|
yield this.xsltChildNodes(childContext, template, output);
|
|
16297
16339
|
});
|
|
16298
16340
|
}
|
|
16341
|
+
/**
|
|
16342
|
+
* Implements `xsl:function` (XSLT 2.0).
|
|
16343
|
+
*
|
|
16344
|
+
* Declares a stylesheet function that can be called from XPath expressions.
|
|
16345
|
+
* Functions are collected during stylesheet initialization and made available
|
|
16346
|
+
* to the XPath evaluator.
|
|
16347
|
+
*
|
|
16348
|
+
* @param context The expression context.
|
|
16349
|
+
* @param template The xsl:function element.
|
|
16350
|
+
*/
|
|
16351
|
+
xsltFunction(context, template) {
|
|
16352
|
+
const name = xmlGetAttribute(template, "name");
|
|
16353
|
+
const asAttr = xmlGetAttribute(template, "as");
|
|
16354
|
+
const overrideAttr = xmlGetAttribute(template, "override");
|
|
16355
|
+
if (!name) {
|
|
16356
|
+
throw new Error('<xsl:function> requires a "name" attribute.');
|
|
16357
|
+
}
|
|
16358
|
+
if (!name.includes(":")) {
|
|
16359
|
+
throw new Error(`<xsl:function> name "${name}" must be in a namespace (use a prefixed name like "my:functionName").`);
|
|
16360
|
+
}
|
|
16361
|
+
const override = overrideAttr === "yes" || overrideAttr === "true";
|
|
16362
|
+
if (this.userDefinedFunctions.has(name) && !override) {
|
|
16363
|
+
return;
|
|
16364
|
+
}
|
|
16365
|
+
this.userDefinedFunctions.set(name, template);
|
|
16366
|
+
}
|
|
16367
|
+
/**
|
|
16368
|
+
* Execute a user-defined xsl:function.
|
|
16369
|
+
* Called when a function from userDefinedFunctions is invoked from XPath.
|
|
16370
|
+
*
|
|
16371
|
+
* @param context The expression context.
|
|
16372
|
+
* @param functionDef The xsl:function node.
|
|
16373
|
+
* @param args The evaluated arguments passed to the function.
|
|
16374
|
+
* @returns The result of the function execution.
|
|
16375
|
+
*/
|
|
16376
|
+
executeUserDefinedFunction(context, functionDef, args) {
|
|
16377
|
+
return __async(this, null, function* () {
|
|
16378
|
+
return this.executeUserDefinedFunctionSync(context, functionDef, args);
|
|
16379
|
+
});
|
|
16380
|
+
}
|
|
16381
|
+
/**
|
|
16382
|
+
* Synchronously execute a user-defined xsl:function.
|
|
16383
|
+
* This is used when functions are called from XPath expressions.
|
|
16384
|
+
* Limited to functions that don't require async operations in their body.
|
|
16385
|
+
*
|
|
16386
|
+
* @param context The expression context.
|
|
16387
|
+
* @param functionDef The xsl:function node.
|
|
16388
|
+
* @param args The evaluated arguments passed to the function.
|
|
16389
|
+
* @returns The result of the function execution.
|
|
16390
|
+
*/
|
|
16391
|
+
executeUserDefinedFunctionSync(context, functionDef, args) {
|
|
16392
|
+
const functionContext = context.clone();
|
|
16393
|
+
functionContext.variables = __spreadValues({}, context.variables);
|
|
16394
|
+
const params = [];
|
|
16395
|
+
for (const child of functionDef.childNodes) {
|
|
16396
|
+
if (child.nodeType === DOM_ELEMENT_NODE && this.isXsltElement(child, "param")) {
|
|
16397
|
+
params.push(child);
|
|
16398
|
+
}
|
|
16399
|
+
}
|
|
16400
|
+
for (let i = 0; i < params.length; i++) {
|
|
16401
|
+
const paramName = xmlGetAttribute(params[i], "name");
|
|
16402
|
+
if (paramName) {
|
|
16403
|
+
if (i < args.length) {
|
|
16404
|
+
const argValue = args[i];
|
|
16405
|
+
if (argValue && typeof argValue === "object" && "stringValue" in argValue) {
|
|
16406
|
+
functionContext.setVariable(paramName, argValue);
|
|
16407
|
+
} else if (Array.isArray(argValue)) {
|
|
16408
|
+
functionContext.setVariable(paramName, new NodeSetValue(argValue));
|
|
16409
|
+
} else if (typeof argValue === "number") {
|
|
16410
|
+
functionContext.setVariable(paramName, new NumberValue(argValue));
|
|
16411
|
+
} else if (typeof argValue === "boolean") {
|
|
16412
|
+
functionContext.setVariable(paramName, new BooleanValue(argValue));
|
|
16413
|
+
} else {
|
|
16414
|
+
functionContext.setVariable(paramName, new StringValue(String(argValue != null ? argValue : "")));
|
|
16415
|
+
}
|
|
16416
|
+
} else {
|
|
16417
|
+
const selectExpr = xmlGetAttribute(params[i], "select");
|
|
16418
|
+
if (selectExpr) {
|
|
16419
|
+
const defaultValue = this.xPath.xPathEval(selectExpr, functionContext);
|
|
16420
|
+
functionContext.setVariable(paramName, defaultValue);
|
|
16421
|
+
} else {
|
|
16422
|
+
functionContext.setVariable(paramName, new StringValue(""));
|
|
16423
|
+
}
|
|
16424
|
+
}
|
|
16425
|
+
}
|
|
16426
|
+
}
|
|
16427
|
+
for (const child of functionDef.childNodes) {
|
|
16428
|
+
if (child.nodeType === DOM_ELEMENT_NODE) {
|
|
16429
|
+
if (this.isXsltElement(child, "sequence")) {
|
|
16430
|
+
const select = xmlGetAttribute(child, "select");
|
|
16431
|
+
if (select) {
|
|
16432
|
+
const result = this.xPath.xPathEval(select, functionContext);
|
|
16433
|
+
if (result.type === "number") {
|
|
16434
|
+
return result.numberValue();
|
|
16435
|
+
} else if (result.type === "boolean") {
|
|
16436
|
+
return result.booleanValue();
|
|
16437
|
+
} else if (result.type === "node-set") {
|
|
16438
|
+
return result.nodeSetValue();
|
|
16439
|
+
} else {
|
|
16440
|
+
return result.stringValue();
|
|
16441
|
+
}
|
|
16442
|
+
}
|
|
16443
|
+
} else if (this.isXsltElement(child, "value-of")) {
|
|
16444
|
+
const select = xmlGetAttribute(child, "select");
|
|
16445
|
+
if (select) {
|
|
16446
|
+
return this.xPath.xPathEval(select, functionContext).stringValue();
|
|
16447
|
+
}
|
|
16448
|
+
}
|
|
16449
|
+
}
|
|
16450
|
+
}
|
|
16451
|
+
return "";
|
|
16452
|
+
}
|
|
16453
|
+
/**
|
|
16454
|
+
* Implements `xsl:result-document` (XSLT 2.0).
|
|
16455
|
+
*
|
|
16456
|
+
* Creates a secondary output document. The output is stored in the
|
|
16457
|
+
* resultDocuments map, accessible via getResultDocuments().
|
|
16458
|
+
*
|
|
16459
|
+
* @param context The expression context.
|
|
16460
|
+
* @param template The xsl:result-document element.
|
|
16461
|
+
*/
|
|
16462
|
+
xsltResultDocument(context, template) {
|
|
16463
|
+
return __async(this, null, function* () {
|
|
16464
|
+
const hrefExpr = xmlGetAttribute(template, "href") || "";
|
|
16465
|
+
const methodAttr = xmlGetAttribute(template, "method") || this.outputMethod || "xml";
|
|
16466
|
+
const omitXmlDeclaration = xmlGetAttribute(template, "omit-xml-declaration") || this.outputOmitXmlDeclaration;
|
|
16467
|
+
const href = this.xsltAttributeValue(hrefExpr, context);
|
|
16468
|
+
if (!href) {
|
|
16469
|
+
throw new Error('<xsl:result-document> requires a non-empty "href" attribute.');
|
|
16470
|
+
}
|
|
16471
|
+
if (this.resultDocuments.has(href)) {
|
|
16472
|
+
throw new Error(`<xsl:result-document>: A document has already been created with href="${href}".`);
|
|
16473
|
+
}
|
|
16474
|
+
const resultDocument = new XDocument();
|
|
16475
|
+
yield this.xsltChildNodes(context, template, resultDocument);
|
|
16476
|
+
const serialized = xmlTransformedText(resultDocument, {
|
|
16477
|
+
cData: this.options.cData,
|
|
16478
|
+
escape: this.options.escape,
|
|
16479
|
+
selfClosingTags: this.options.selfClosingTags,
|
|
16480
|
+
outputMethod: methodAttr,
|
|
16481
|
+
outputVersion: this.outputVersion,
|
|
16482
|
+
itemSeparator: this.itemSeparator
|
|
16483
|
+
});
|
|
16484
|
+
this.resultDocuments.set(href, serialized);
|
|
16485
|
+
});
|
|
16486
|
+
}
|
|
16487
|
+
/**
|
|
16488
|
+
* Get all result documents created by xsl:result-document.
|
|
16489
|
+
* @returns A map of href URIs to serialized output strings.
|
|
16490
|
+
*/
|
|
16491
|
+
getResultDocuments() {
|
|
16492
|
+
return this.resultDocuments;
|
|
16493
|
+
}
|
|
16494
|
+
/**
|
|
16495
|
+
* Implements `xsl:perform-sort` (XSLT 2.0).
|
|
16496
|
+
*
|
|
16497
|
+
* Sorts a sequence of items without iteration. The sorted sequence
|
|
16498
|
+
* is available via xsl:sequence or other sequence-consuming instructions.
|
|
16499
|
+
*
|
|
16500
|
+
* @param context The expression context.
|
|
16501
|
+
* @param template The xsl:perform-sort element.
|
|
16502
|
+
* @param output The output node.
|
|
16503
|
+
*/
|
|
16504
|
+
xsltPerformSort(context, template, output) {
|
|
16505
|
+
return __async(this, null, function* () {
|
|
16506
|
+
const select = xmlGetAttribute(template, "select");
|
|
16507
|
+
let items;
|
|
16508
|
+
if (select) {
|
|
16509
|
+
items = this.xPath.xPathEval(select, context).nodeSetValue();
|
|
16510
|
+
} else {
|
|
16511
|
+
const sequenceChildren = [];
|
|
16512
|
+
for (const child of template.childNodes) {
|
|
16513
|
+
if (child.nodeType === DOM_ELEMENT_NODE && !this.isXsltElement(child, "sort")) {
|
|
16514
|
+
sequenceChildren.push(child);
|
|
16515
|
+
}
|
|
16516
|
+
}
|
|
16517
|
+
const fragment = domCreateDocumentFragment(this.outputDocument);
|
|
16518
|
+
for (const child of sequenceChildren) {
|
|
16519
|
+
yield this.xsltProcessContext(context, child, fragment);
|
|
16520
|
+
}
|
|
16521
|
+
items = Array.from(fragment.childNodes);
|
|
16522
|
+
}
|
|
16523
|
+
if (items.length === 0) {
|
|
16524
|
+
return;
|
|
16525
|
+
}
|
|
16526
|
+
const sortContext = context.clone(items);
|
|
16527
|
+
this.xsltSort(sortContext, template);
|
|
16528
|
+
const destinationNode = output || this.outputDocument;
|
|
16529
|
+
for (const node of sortContext.nodeList) {
|
|
16530
|
+
this.xsltCopyOf(destinationNode, node);
|
|
16531
|
+
}
|
|
16532
|
+
});
|
|
16533
|
+
}
|
|
16534
|
+
/**
|
|
16535
|
+
* Implements `xsl:namespace` (XSLT 2.0).
|
|
16536
|
+
*
|
|
16537
|
+
* Creates a namespace node in the result tree.
|
|
16538
|
+
*
|
|
16539
|
+
* @param context The expression context.
|
|
16540
|
+
* @param template The xsl:namespace element.
|
|
16541
|
+
* @param output The output node.
|
|
16542
|
+
*/
|
|
16543
|
+
xsltNamespace(context, template, output) {
|
|
16544
|
+
return __async(this, null, function* () {
|
|
16545
|
+
const nameExpr = xmlGetAttribute(template, "name");
|
|
16546
|
+
const selectExpr = xmlGetAttribute(template, "select");
|
|
16547
|
+
if (!nameExpr && nameExpr !== "") {
|
|
16548
|
+
throw new Error('<xsl:namespace> requires a "name" attribute.');
|
|
16549
|
+
}
|
|
16550
|
+
const prefix = this.xsltAttributeValue(nameExpr, context);
|
|
16551
|
+
let namespaceUri;
|
|
16552
|
+
if (selectExpr) {
|
|
16553
|
+
namespaceUri = this.xPath.xPathEval(selectExpr, context).stringValue();
|
|
16554
|
+
} else {
|
|
16555
|
+
const fragment = domCreateDocumentFragment(this.outputDocument);
|
|
16556
|
+
yield this.xsltChildNodes(context, template, fragment);
|
|
16557
|
+
namespaceUri = xmlValue(fragment);
|
|
16558
|
+
}
|
|
16559
|
+
if (!namespaceUri) {
|
|
16560
|
+
throw new Error("<xsl:namespace> requires a non-empty namespace URI.");
|
|
16561
|
+
}
|
|
16562
|
+
const destinationNode = output || this.outputDocument;
|
|
16563
|
+
if (destinationNode.nodeType === DOM_ELEMENT_NODE) {
|
|
16564
|
+
if (prefix) {
|
|
16565
|
+
domSetAttribute(destinationNode, `xmlns:${prefix}`, namespaceUri);
|
|
16566
|
+
} else {
|
|
16567
|
+
domSetAttribute(destinationNode, "xmlns", namespaceUri);
|
|
16568
|
+
}
|
|
16569
|
+
}
|
|
16570
|
+
});
|
|
16571
|
+
}
|
|
16299
16572
|
/**
|
|
16300
16573
|
* Evaluates a variable or parameter and set it in the current input
|
|
16301
16574
|
* context. Implements `xsl:variable`, `xsl:param`, and `xsl:with-param`.
|
|
@@ -16652,6 +16925,39 @@ var Xslt = class {
|
|
|
16652
16925
|
}
|
|
16653
16926
|
}
|
|
16654
16927
|
}
|
|
16928
|
+
/**
|
|
16929
|
+
* Collect all user-defined function definitions from the stylesheet.
|
|
16930
|
+
* Called at stylesheet initialization time.
|
|
16931
|
+
* @param stylesheetElement The stylesheet or transform element.
|
|
16932
|
+
* @param context The expression context.
|
|
16933
|
+
*/
|
|
16934
|
+
collectUserDefinedFunctions(stylesheetElement, context) {
|
|
16935
|
+
for (const child of stylesheetElement.childNodes) {
|
|
16936
|
+
if (child.nodeType === DOM_ELEMENT_NODE && this.isXsltElement(child, "function")) {
|
|
16937
|
+
this.xsltFunction(context, child);
|
|
16938
|
+
}
|
|
16939
|
+
}
|
|
16940
|
+
}
|
|
16941
|
+
/**
|
|
16942
|
+
* Register user-defined functions in the expression context.
|
|
16943
|
+
* This makes them available to XPath expressions.
|
|
16944
|
+
* @param context The expression context.
|
|
16945
|
+
*/
|
|
16946
|
+
registerUserDefinedFunctionsInContext(context) {
|
|
16947
|
+
if (this.userDefinedFunctions.size === 0) {
|
|
16948
|
+
return;
|
|
16949
|
+
}
|
|
16950
|
+
const functionsMap = /* @__PURE__ */ new Map();
|
|
16951
|
+
this.userDefinedFunctions.forEach((functionDef, name) => {
|
|
16952
|
+
functionsMap.set(name, {
|
|
16953
|
+
functionDef,
|
|
16954
|
+
executor: (ctx, funcDef, args) => {
|
|
16955
|
+
return this.executeUserDefinedFunctionSync(ctx, funcDef, args);
|
|
16956
|
+
}
|
|
16957
|
+
});
|
|
16958
|
+
});
|
|
16959
|
+
context.userDefinedFunctions = functionsMap;
|
|
16960
|
+
}
|
|
16655
16961
|
/**
|
|
16656
16962
|
* Apply one or more attribute sets to an element.
|
|
16657
16963
|
* Parses space-separated attribute set names and applies them.
|