Skip to content

Commit 6245c11

Browse files
<xsl:key> (#101)
* `<xsl:key>` basic implementation. * - Implementing `<xsl:key>` * - Refactorings and cleanup * Updating Node version in PR build.
1 parent 3916d7e commit 6245c11

File tree

12 files changed

+358
-147
lines changed

12 files changed

+358
-147
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
- uses: actions/checkout@v2
1717
- uses: actions/setup-node@v2-beta
1818
with:
19-
node-version: '16'
19+
node-version: '20'
2020
- uses: ArtiomTr/jest-coverage-report-action@v2
2121
id: coverage
2222
with:

.vscode/launch.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@
1515
"--runInBand",
1616
"--testTimeout=100000000"
1717
],
18-
"smartStep": true,
19-
"skipFiles": ["<node_internals>/**", "node_modules/**"],
18+
"smartStep": true,
19+
"skipFiles": [
20+
"<node_internals>/**",
21+
"node_modules/**"
22+
],
2023
"console": "integratedTerminal",
2124
"internalConsoleOptions": "neverOpen"
2225
},
@@ -31,6 +34,9 @@
3134
"args": [
3235
"${file}"
3336
],
37+
"env": {
38+
"TS_NODE_PROJECT": "${workspaceRoot}/tsconfig.debug.json"
39+
},
3440
"console": "integratedTerminal",
3541
"internalConsoleOptions": "neverOpen"
3642
}

src/xpath/expr-context.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export class ExprContext {
5151
xsltVersion: '1.0' | '2.0' | '3.0';
5252

5353
variables: { [name: string]: NodeValue };
54+
keys: { [name: string]: { [key: string]: NodeValue } };
5455
knownNamespaces: { [alias: string]: string };
5556

5657
caseInsensitive: any;
@@ -110,6 +111,7 @@ export class ExprContext {
110111
this.outputPosition = opt_outputPosition || 0;
111112

112113
this.variables = opt_variables || {};
114+
this.keys = opt_parent?.keys || {};
113115
this.knownNamespaces = opt_knownNamespaces || {};
114116

115117
this.parent = opt_parent || null;
@@ -196,7 +198,7 @@ export class ExprContext {
196198
);
197199
}
198200

199-
setVariable(name?: any, value?: any) {
201+
setVariable(name?: string, value?: NodeValue | string) {
200202
if (
201203
value instanceof StringValue ||
202204
value instanceof BooleanValue ||
@@ -206,11 +208,12 @@ export class ExprContext {
206208
this.variables[name] = value;
207209
return;
208210
}
211+
209212
if ('true' === value) {
210213
this.variables[name] = new BooleanValue(true);
211214
} else if ('false' === value) {
212215
this.variables[name] = new BooleanValue(false);
213-
} else if (TOK_NUMBER.re.test(value)) {
216+
} else if (TOK_NUMBER.re.test(String(value))) {
214217
this.variables[name] = new NumberValue(value);
215218
} else {
216219
// DGF What if it's null?

src/xpath/expressions/function-call-expr.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ import {
3232
ceiling,
3333
round,
3434
current,
35-
formatNumber
35+
formatNumber,
36+
key
3637
} from '../functions';
3738
import { extCardinal, extIf, extJoin } from '../functions/non-standard';
3839
import { lowerCase, _replace, upperCase } from '../functions/standard-20';
@@ -56,6 +57,7 @@ export class FunctionCallExpr extends Expression {
5657
floor,
5758
'generate-id': generateId,
5859
id,
60+
key,
5961
lang,
6062
last,
6163
'local-name': localName,

src/xpath/expressions/location-expr.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export class LocationExpr extends Expression {
1919
this.xPath = xPath;
2020
}
2121

22-
appendStep(s) {
22+
appendStep(s: StepExpr) {
2323
const combinedStep = this._combineSteps(this.steps[this.steps.length - 1], s);
2424
if (combinedStep) {
2525
this.steps[this.steps.length - 1] = combinedStep;
@@ -28,7 +28,7 @@ export class LocationExpr extends Expression {
2828
}
2929
}
3030

31-
prependStep(s) {
31+
prependStep(s: StepExpr) {
3232
const combinedStep = this._combineSteps(s, this.steps[0]);
3333
if (combinedStep) {
3434
this.steps[0] = combinedStep;
@@ -38,7 +38,7 @@ export class LocationExpr extends Expression {
3838
}
3939

4040
// DGF try to combine two steps into one step (perf enhancement)
41-
_combineSteps(prevStep, nextStep) {
41+
private _combineSteps(prevStep: any, nextStep: any) {
4242
if (!prevStep) return null;
4343
if (!nextStep) return null;
4444
const hasPredicates = prevStep.predicates && prevStep.predicates.length > 0;

src/xpath/functions/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
export * from './non-standard';
22
export * from './standard';
3+
export * from './standard-20';
4+
export * from './xslt-specific';
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { ExprContext } from "../expr-context";
2+
import { Expression } from "../expressions/expression";
3+
import { NodeValue, StringValue } from "../values";
4+
import { assert } from "./internal-functions";
5+
6+
export function key(context: ExprContext): NodeValue {
7+
assert(this.args.length === 2);
8+
const keyNameStringValue: StringValue = (this.args[0] as Expression).evaluate(context);
9+
const keyValueStringValue: StringValue = (this.args[1] as Expression).evaluate(context);
10+
const keyName = keyNameStringValue.stringValue();
11+
const keyValue = keyValueStringValue.stringValue();
12+
const nodeSet = context.keys[keyName][keyValue];
13+
return nodeSet;
14+
}

src/xpath/values/node-set-value.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export class NodeSetValue implements NodeValue {
55
value: XNode[];
66
type: string;
77

8-
constructor(value: any) {
8+
constructor(value: XNode[]) {
99
this.value = value;
1010
this.type = 'node-set';
1111
}

0 commit comments

Comments
 (0)