@tradik/xslt3 0.0.0-stage → 1.0.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/LICENSE.md +28 -0
- package/README.md +98 -2
- package/package.json +43 -4
- package/src/errors.js +20 -0
- package/src/functions/aggregates.js +144 -0
- package/src/functions/arraySort.js +33 -0
- package/src/functions/arrays.js +181 -0
- package/src/functions/attributeTypes.js +58 -0
- package/src/functions/baseUris.js +82 -0
- package/src/functions/collations.js +127 -0
- package/src/functions/collections.js +84 -0
- package/src/functions/context.js +83 -0
- package/src/functions/core.js +167 -0
- package/src/functions/datetime.js +203 -0
- package/src/functions/deepEqual.js +132 -0
- package/src/functions/diagnostics.js +88 -0
- package/src/functions/focus.js +34 -0
- package/src/functions/format/dateComponents.js +176 -0
- package/src/functions/format/datePicture.js +115 -0
- package/src/functions/format/decimalFormat.js +65 -0
- package/src/functions/format/digitPattern.js +145 -0
- package/src/functions/format/formatDateTime.js +204 -0
- package/src/functions/format/formatInteger.js +109 -0
- package/src/functions/format/formatNumber.js +165 -0
- package/src/functions/format/fractionFormat.js +80 -0
- package/src/functions/format/germanWords.js +89 -0
- package/src/functions/format/numberLanguages.js +41 -0
- package/src/functions/format/numberPicture.js +202 -0
- package/src/functions/format/numberWords.js +155 -0
- package/src/functions/format/place.js +74 -0
- package/src/functions/format/timezoneFormat.js +89 -0
- package/src/functions/higherOrder.js +106 -0
- package/src/functions/ids.js +127 -0
- package/src/functions/json/index.js +17 -0
- package/src/functions/json/jsonChars.js +110 -0
- package/src/functions/json/jsonParser.js +203 -0
- package/src/functions/json/jsonStrings.js +116 -0
- package/src/functions/json/jsonToXml.js +116 -0
- package/src/functions/json/parseJson.js +119 -0
- package/src/functions/json/xmlRepresentation.js +103 -0
- package/src/functions/json/xmlToJson.js +147 -0
- package/src/functions/library.js +47 -0
- package/src/functions/mapArrayEqual.js +41 -0
- package/src/functions/maps.js +152 -0
- package/src/functions/math.js +73 -0
- package/src/functions/nodePaths.js +181 -0
- package/src/functions/nodes.js +199 -0
- package/src/functions/numeric.js +148 -0
- package/src/functions/options.js +58 -0
- package/src/functions/parseIetfDate.js +104 -0
- package/src/functions/parseXml.js +77 -0
- package/src/functions/qnames.js +68 -0
- package/src/functions/random.js +128 -0
- package/src/functions/regex/analyzeString.js +144 -0
- package/src/functions/regex/charClass.js +112 -0
- package/src/functions/regex/compile.js +81 -0
- package/src/functions/regex/escapes.js +109 -0
- package/src/functions/regex/parser.js +169 -0
- package/src/functions/regex/reader.js +37 -0
- package/src/functions/regex/regexFunctions.js +140 -0
- package/src/functions/regex/translate.js +102 -0
- package/src/functions/regex/unicodeBlocks.js +194 -0
- package/src/functions/registry.js +140 -0
- package/src/functions/sequences.js +173 -0
- package/src/functions/serializeFunction.js +53 -0
- package/src/functions/signatures.js +105 -0
- package/src/functions/sort.js +102 -0
- package/src/functions/stringMatch.js +45 -0
- package/src/functions/strings.js +194 -0
- package/src/functions/stringsCore.js +66 -0
- package/src/functions/support.js +106 -0
- package/src/functions/textDecoding.js +117 -0
- package/src/functions/ucaCollation.js +127 -0
- package/src/functions/unparsedText.js +71 -0
- package/src/functions/uri.js +166 -0
- package/src/functions/xqueryModule.js +24 -0
- package/src/index.js +38 -0
- package/src/items/array.js +84 -0
- package/src/items/function.js +45 -0
- package/src/items/map.js +120 -0
- package/src/items/mapKey.js +82 -0
- package/src/serialize/index.js +129 -0
- package/src/serialize/markup/content.js +74 -0
- package/src/serialize/markup/dialect.js +178 -0
- package/src/serialize/markup/htmlData.js +70 -0
- package/src/serialize/markup/namespaces.js +145 -0
- package/src/serialize/markup/prolog.js +91 -0
- package/src/serialize/markup/writer.js +183 -0
- package/src/serialize/methods/adaptive.js +131 -0
- package/src/serialize/methods/json.js +158 -0
- package/src/serialize/methods/text.js +43 -0
- package/src/serialize/output/buffer.js +48 -0
- package/src/serialize/output/encoding.js +146 -0
- package/src/serialize/output/expander.js +204 -0
- package/src/serialize/params/fromElement.js +141 -0
- package/src/serialize/params/fromMap.js +128 -0
- package/src/serialize/params/names.js +69 -0
- package/src/serialize/params/settings.js +153 -0
- package/src/serialize/params/values.js +163 -0
- package/src/serialize/sequence.js +111 -0
- package/src/xdm/arithmetic.js +155 -0
- package/src/xdm/atomic.js +142 -0
- package/src/xdm/binary.js +92 -0
- package/src/xdm/calendar.js +71 -0
- package/src/xdm/cast.js +176 -0
- package/src/xdm/compare.js +192 -0
- package/src/xdm/datetime.js +206 -0
- package/src/xdm/decimal.js +200 -0
- package/src/xdm/duration.js +128 -0
- package/src/xdm/generalCompare.js +152 -0
- package/src/xdm/index.js +47 -0
- package/src/xdm/lexical.js +126 -0
- package/src/xdm/nodes.js +170 -0
- package/src/xdm/numeric.js +122 -0
- package/src/xdm/qname.js +65 -0
- package/src/xdm/strings.js +52 -0
- package/src/xdm/temporalArithmetic.js +180 -0
- package/src/xdm/timeline.js +68 -0
- package/src/xdm/types.js +178 -0
- package/src/xpath/eval/atomics.js +45 -0
- package/src/xpath/eval/axes.js +212 -0
- package/src/xpath/eval/calls.js +168 -0
- package/src/xpath/eval/coercion.js +146 -0
- package/src/xpath/eval/compiler.js +71 -0
- package/src/xpath/eval/constructors.js +129 -0
- package/src/xpath/eval/decimalFormats.js +93 -0
- package/src/xpath/eval/descendantMemo.js +77 -0
- package/src/xpath/eval/documentOrder.js +142 -0
- package/src/xpath/eval/domNodes.js +174 -0
- package/src/xpath/eval/dynamicCall.js +27 -0
- package/src/xpath/eval/dynamicContext.js +161 -0
- package/src/xpath/eval/flow.js +115 -0
- package/src/xpath/eval/functionItems.js +194 -0
- package/src/xpath/eval/groupedChildren.js +88 -0
- package/src/xpath/eval/inline.js +71 -0
- package/src/xpath/eval/namespaceNodes.js +90 -0
- package/src/xpath/eval/nodeTests.js +164 -0
- package/src/xpath/eval/operators.js +190 -0
- package/src/xpath/eval/paths.js +163 -0
- package/src/xpath/eval/positional.js +81 -0
- package/src/xpath/eval/predicates.js +56 -0
- package/src/xpath/eval/primary.js +99 -0
- package/src/xpath/eval/resources.js +149 -0
- package/src/xpath/eval/scope.js +108 -0
- package/src/xpath/eval/sequenceType.js +193 -0
- package/src/xpath/eval/staticContext.js +142 -0
- package/src/xpath/eval/steps.js +98 -0
- package/src/xpath/eval/subtype.js +154 -0
- package/src/xpath/eval/typeExprs.js +147 -0
- package/src/xpath/eval/typeNames.js +101 -0
- package/src/xpath/eval/uris.js +21 -0
- package/src/xpath/eval/values.js +64 -0
- package/src/xpath/index.js +217 -0
- package/src/xpath/syntax/ast.js +130 -0
- package/src/xpath/syntax/chars.js +58 -0
- package/src/xpath/syntax/constructors.js +144 -0
- package/src/xpath/syntax/expressions.js +107 -0
- package/src/xpath/syntax/index.js +44 -0
- package/src/xpath/syntax/kindTests.js +134 -0
- package/src/xpath/syntax/lexer.js +220 -0
- package/src/xpath/syntax/operators.js +111 -0
- package/src/xpath/syntax/paths.js +102 -0
- package/src/xpath/syntax/postfix.js +91 -0
- package/src/xpath/syntax/primaries.js +149 -0
- package/src/xpath/syntax/steps.js +146 -0
- package/src/xpath/syntax/syntaxError.js +31 -0
- package/src/xpath/syntax/tokenStream.js +163 -0
- package/src/xpath/syntax/typeAst.js +76 -0
- package/src/xpath/syntax/typeOperators.js +127 -0
- package/src/xpath/syntax/types.js +158 -0
- package/src/xslt/api.js +153 -0
- package/src/xslt/compiler/acceptance.js +178 -0
- package/src/xslt/compiler/accumulatorDecl.js +146 -0
- package/src/xslt/compiler/attributeValues.js +174 -0
- package/src/xslt/compiler/attributes.js +211 -0
- package/src/xslt/compiler/avt.js +103 -0
- package/src/xslt/compiler/body.js +154 -0
- package/src/xslt/compiler/children.js +105 -0
- package/src/xslt/compiler/compatibility.js +130 -0
- package/src/xslt/compiler/components.js +179 -0
- package/src/xslt/compiler/contextItem.js +95 -0
- package/src/xslt/compiler/decimalFormats.js +132 -0
- package/src/xslt/compiler/declarationKinds.js +82 -0
- package/src/xslt/compiler/elementInfo.js +246 -0
- package/src/xslt/compiler/expressions.js +175 -0
- package/src/xslt/compiler/globalContextItem.js +92 -0
- package/src/xslt/compiler/globals.js +209 -0
- package/src/xslt/compiler/linker.js +134 -0
- package/src/xslt/compiler/miscDecl.js +171 -0
- package/src/xslt/compiler/modeDecl.js +88 -0
- package/src/xslt/compiler/moduleLoading.js +111 -0
- package/src/xslt/compiler/modules.js +158 -0
- package/src/xslt/compiler/outputDecl.js +209 -0
- package/src/xslt/compiler/overrideLinks.js +141 -0
- package/src/xslt/compiler/packageChecks.js +84 -0
- package/src/xslt/compiler/packageRegistry.js +95 -0
- package/src/xslt/compiler/packageTable.js +181 -0
- package/src/xslt/compiler/packageVersions.js +143 -0
- package/src/xslt/compiler/packages.js +138 -0
- package/src/xslt/compiler/registry.js +234 -0
- package/src/xslt/compiler/staticStage.js +197 -0
- package/src/xslt/compiler/staticVariables.js +93 -0
- package/src/xslt/compiler/stylesheet.js +205 -0
- package/src/xslt/compiler/tailPosition.js +74 -0
- package/src/xslt/compiler/templatesDecl.js +180 -0
- package/src/xslt/compiler/useAccumulators.js +76 -0
- package/src/xslt/compiler/useWhen.js +94 -0
- package/src/xslt/compiler/visibility.js +160 -0
- package/src/xslt/index.js +11 -0
- package/src/xslt/instructions/analyzeString.js +137 -0
- package/src/xslt/instructions/assert.js +72 -0
- package/src/xslt/instructions/attributeSets.js +115 -0
- package/src/xslt/instructions/conditional.js +99 -0
- package/src/xslt/instructions/control.js +123 -0
- package/src/xslt/instructions/copy.js +151 -0
- package/src/xslt/instructions/elements.js +161 -0
- package/src/xslt/instructions/evaluate.js +189 -0
- package/src/xslt/instructions/fork.js +35 -0
- package/src/xslt/instructions/grouping.js +106 -0
- package/src/xslt/instructions/index.js +94 -0
- package/src/xslt/instructions/iterate.js +182 -0
- package/src/xslt/instructions/literal.js +142 -0
- package/src/xslt/instructions/maps.js +72 -0
- package/src/xslt/instructions/merge.js +190 -0
- package/src/xslt/instructions/number.js +205 -0
- package/src/xslt/instructions/output.js +102 -0
- package/src/xslt/instructions/params.js +110 -0
- package/src/xslt/instructions/resultDocument.js +143 -0
- package/src/xslt/instructions/sort.js +114 -0
- package/src/xslt/instructions/sourceDocument.js +73 -0
- package/src/xslt/instructions/templates.js +153 -0
- package/src/xslt/instructions/text.js +151 -0
- package/src/xslt/instructions/try.js +186 -0
- package/src/xslt/instructions/variables.js +119 -0
- package/src/xslt/names.js +204 -0
- package/src/xslt/patterns/axisOrigins.js +121 -0
- package/src/xslt/patterns/compile.js +151 -0
- package/src/xslt/patterns/general.js +132 -0
- package/src/xslt/patterns/grammar.js +190 -0
- package/src/xslt/patterns/modes.js +153 -0
- package/src/xslt/patterns/paths.js +130 -0
- package/src/xslt/patterns/patternChecks.js +29 -0
- package/src/xslt/patterns/steps.js +162 -0
- package/src/xslt/processor.js +178 -0
- package/src/xslt/runtime/accumulatorFunctions.js +48 -0
- package/src/xslt/runtime/accumulators.js +174 -0
- package/src/xslt/runtime/apply.js +153 -0
- package/src/xslt/runtime/atomicKeys.js +36 -0
- package/src/xslt/runtime/availability.js +162 -0
- package/src/xslt/runtime/baseUri.js +64 -0
- package/src/xslt/runtime/compilerHook.js +27 -0
- package/src/xslt/runtime/conditional.js +110 -0
- package/src/xslt/runtime/context.js +106 -0
- package/src/xslt/runtime/copy.js +123 -0
- package/src/xslt/runtime/copyFunctions.js +71 -0
- package/src/xslt/runtime/copyOrigins.js +60 -0
- package/src/xslt/runtime/defaultMethod.js +42 -0
- package/src/xslt/runtime/documentContent.js +93 -0
- package/src/xslt/runtime/dynamicXPath.js +90 -0
- package/src/xslt/runtime/functionCache.js +65 -0
- package/src/xslt/runtime/functionCall.js +57 -0
- package/src/xslt/runtime/functions.js +191 -0
- package/src/xslt/runtime/groups.js +108 -0
- package/src/xslt/runtime/invocation.js +156 -0
- package/src/xslt/runtime/iteration.js +107 -0
- package/src/xslt/runtime/keys.js +141 -0
- package/src/xslt/runtime/lazy.js +97 -0
- package/src/xslt/runtime/locations.js +86 -0
- package/src/xslt/runtime/machine.js +137 -0
- package/src/xslt/runtime/merging.js +167 -0
- package/src/xslt/runtime/namespaceScope.js +141 -0
- package/src/xslt/runtime/numberFormat.js +89 -0
- package/src/xslt/runtime/numbering.js +168 -0
- package/src/xslt/runtime/params.js +59 -0
- package/src/xslt/runtime/properties.js +103 -0
- package/src/xslt/runtime/rawResults.js +82 -0
- package/src/xslt/runtime/sequenceReceiver.js +102 -0
- package/src/xslt/runtime/snapshot.js +66 -0
- package/src/xslt/runtime/sortKeys.js +119 -0
- package/src/xslt/runtime/streamAvailable.js +60 -0
- package/src/xslt/runtime/strip.js +102 -0
- package/src/xslt/runtime/transformFunction.js +169 -0
- package/src/xslt/runtime/transformation.js +168 -0
- package/src/xslt/runtime/transformationContext.js +85 -0
- package/src/xslt/runtime/treeReceiver.js +194 -0
- package/src/xslt/runtime/values.js +92 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static function resolution and the function items of known functions:
|
|
3
|
+
* library functions (see functions/registry.js), constructor functions of
|
|
4
|
+
* the atomic types, and F&O functions without an implementation yet.
|
|
5
|
+
*
|
|
6
|
+
* @module @tradik/xslt3/xpath/eval/functionItems
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { XPathError } from "../../errors.js";
|
|
10
|
+
import { isStandardFunction, NS } from "../../functions/signatures.js";
|
|
11
|
+
import { FunctionItem } from "../../items/function.js";
|
|
12
|
+
import { QNameValue } from "../../xdm/qname.js";
|
|
13
|
+
import { XS_NAMESPACE } from "../../xdm/types.js";
|
|
14
|
+
import { parseSequenceType } from "../syntax/types.js";
|
|
15
|
+
import { TokenStream } from "../syntax/tokenStream.js";
|
|
16
|
+
import { coerce } from "./coercion.js";
|
|
17
|
+
import { dynamicCallContext } from "./dynamicCall.js";
|
|
18
|
+
import { compileSequenceType } from "./sequenceType.js";
|
|
19
|
+
import { createStaticContext } from "./staticContext.js";
|
|
20
|
+
import { compileCastTarget, LIST_TYPES } from "./typeExprs.js";
|
|
21
|
+
|
|
22
|
+
/** Largest arity of a function reference to a variadic function. */
|
|
23
|
+
const MAX_ARITY = 1000000;
|
|
24
|
+
|
|
25
|
+
/** Static context in which definition types are read. */
|
|
26
|
+
const BUILT_IN_CONTEXT = createStaticContext({}, null);
|
|
27
|
+
|
|
28
|
+
/** @type {Map<string, object>} compiled sequence types by text */
|
|
29
|
+
const typeCache = new Map();
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @param {string} text - A sequence type in XPath syntax
|
|
33
|
+
* @returns {import("./sequenceType.js").SequenceType}
|
|
34
|
+
*/
|
|
35
|
+
export function sequenceTypeOf(text) {
|
|
36
|
+
let type = typeCache.get(text);
|
|
37
|
+
if (!type) {
|
|
38
|
+
const tokens = new TokenStream(text);
|
|
39
|
+
type = compileSequenceType(parseSequenceType(tokens), BUILT_IN_CONTEXT);
|
|
40
|
+
if (tokens.peek().type !== "eof") tokens.fail("Unexpected token");
|
|
41
|
+
typeCache.set(text, type);
|
|
42
|
+
}
|
|
43
|
+
return type;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Signature of a definition at an arity (variadic definitions repeat their
|
|
48
|
+
* last parameter).
|
|
49
|
+
* @param {import("../../functions/registry.js").FunctionDefinition} definition
|
|
50
|
+
* @param {number} arity
|
|
51
|
+
* @returns {{params: object[], returns: object}}
|
|
52
|
+
*/
|
|
53
|
+
export function definitionSignature(definition, arity) {
|
|
54
|
+
const texts = definition.params;
|
|
55
|
+
const params = [];
|
|
56
|
+
for (let i = 0; i < arity; i++) {
|
|
57
|
+
params.push(sequenceTypeOf(texts[Math.min(i, texts.length - 1)]));
|
|
58
|
+
}
|
|
59
|
+
return { params, returns: sequenceTypeOf(definition.returns) };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* A resolved static function: `call(args, ctx)` takes evaluated arguments
|
|
64
|
+
* and returns the result; `signature` gives the parameter types.
|
|
65
|
+
* @typedef {object} ResolvedFunction
|
|
66
|
+
* @property {QNameValue} name
|
|
67
|
+
* @property {number} arity
|
|
68
|
+
* @property {{params: object[], returns: object}} signature
|
|
69
|
+
* @property {boolean} focus - Depends on the focus
|
|
70
|
+
* @property {(args: Array<Array>, ctx: object) => Array} call
|
|
71
|
+
*/
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Builds the call of a library function.
|
|
75
|
+
* @returns {ResolvedFunction}
|
|
76
|
+
*/
|
|
77
|
+
function libraryFunction(definition, name, arity, sc) {
|
|
78
|
+
const signature = definitionSignature(definition, arity);
|
|
79
|
+
const options = signature.params.map((_, i) => ({
|
|
80
|
+
what: `argument ${i + 1} of ${name}()`,
|
|
81
|
+
compatible: sc.backwardsCompatible,
|
|
82
|
+
}));
|
|
83
|
+
const call = definition.focus
|
|
84
|
+
? (args, ctx) => {
|
|
85
|
+
const context = Object.create(ctx.dyn);
|
|
86
|
+
context.contextItem = ctx.item;
|
|
87
|
+
context.position = ctx.position;
|
|
88
|
+
context.size = ctx.size;
|
|
89
|
+
return definition.impl(
|
|
90
|
+
args.map((arg, i) => coerce(arg, signature.params[i], options[i])),
|
|
91
|
+
context,
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
: (args, ctx) =>
|
|
95
|
+
definition.impl(
|
|
96
|
+
args.map((arg, i) => coerce(arg, signature.params[i], options[i])),
|
|
97
|
+
ctx.dyn,
|
|
98
|
+
);
|
|
99
|
+
return { name, arity, signature, focus: Boolean(definition.focus), call };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Builds the call of a constructor function `xs:T($arg)`.
|
|
104
|
+
* @returns {ResolvedFunction|null} null when T has no constructor
|
|
105
|
+
*/
|
|
106
|
+
function constructorFunction(name, sc) {
|
|
107
|
+
let caster;
|
|
108
|
+
try {
|
|
109
|
+
caster = compileCastTarget(
|
|
110
|
+
{ prefix: null, uri: XS_NAMESPACE, local: name.localName },
|
|
111
|
+
sc,
|
|
112
|
+
);
|
|
113
|
+
} catch {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
const signature = {
|
|
117
|
+
params: [sequenceTypeOf("xs:anyAtomicType?")],
|
|
118
|
+
returns: sequenceTypeOf(
|
|
119
|
+
name.localName === "error"
|
|
120
|
+
? "empty-sequence()"
|
|
121
|
+
: LIST_TYPES[name.localName]
|
|
122
|
+
? `xs:${LIST_TYPES[name.localName]}*`
|
|
123
|
+
: `xs:${name.localName}?`,
|
|
124
|
+
),
|
|
125
|
+
};
|
|
126
|
+
const what = { what: `argument of ${name}()` };
|
|
127
|
+
const call = ([arg]) => {
|
|
128
|
+
const values = coerce(arg, signature.params[0], what);
|
|
129
|
+
return values.length === 0 ? [] : caster(values[0]);
|
|
130
|
+
};
|
|
131
|
+
return { name, arity: 1, signature, focus: false, call };
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Resolves a function by expanded name and arity.
|
|
136
|
+
* @param {string} uri
|
|
137
|
+
* @param {string} local
|
|
138
|
+
* @param {number} arity
|
|
139
|
+
* @param {import("./staticContext.js").StaticContext} sc
|
|
140
|
+
* @returns {ResolvedFunction}
|
|
141
|
+
* @throws {XPathError} XPST0017 when there is no such function
|
|
142
|
+
*/
|
|
143
|
+
export function resolveFunction(uri, local, arity, sc) {
|
|
144
|
+
if (arity > MAX_ARITY) {
|
|
145
|
+
throw new XPathError("FOAR0002", `Arity ${arity} is too large`);
|
|
146
|
+
}
|
|
147
|
+
const prefix = Object.keys(NS).find((key) => NS[key] === uri);
|
|
148
|
+
const name = new QNameValue(
|
|
149
|
+
uri,
|
|
150
|
+
local,
|
|
151
|
+
prefix ?? (uri === XS_NAMESPACE ? "xs" : ""),
|
|
152
|
+
);
|
|
153
|
+
const definition = sc.functions.lookup(uri, local, arity);
|
|
154
|
+
if (definition) return libraryFunction(definition, name, arity, sc);
|
|
155
|
+
const constructor =
|
|
156
|
+
uri === XS_NAMESPACE && arity === 1 ? constructorFunction(name, sc) : null;
|
|
157
|
+
if (constructor) return constructor;
|
|
158
|
+
if (isStandardFunction(uri, local, arity)) {
|
|
159
|
+
return {
|
|
160
|
+
name,
|
|
161
|
+
arity,
|
|
162
|
+
signature: null,
|
|
163
|
+
focus: false,
|
|
164
|
+
call: () => {
|
|
165
|
+
throw new XPathError(
|
|
166
|
+
"XPST0017",
|
|
167
|
+
`${local}#${arity} is not implemented`,
|
|
168
|
+
);
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
throw new XPathError(
|
|
173
|
+
"XPST0017",
|
|
174
|
+
`Unknown function Q{${uri}}${local}#${arity}`,
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* The function item of a resolved function; a focus-dependent function
|
|
180
|
+
* keeps the focus of `ctx`.
|
|
181
|
+
* @param {ResolvedFunction} resolved
|
|
182
|
+
* @param {import("./scope.js").Context} ctx
|
|
183
|
+
* @returns {FunctionItem}
|
|
184
|
+
*/
|
|
185
|
+
export function functionItemOf(resolved, ctx) {
|
|
186
|
+
if (resolved.signature === null) return resolved.call();
|
|
187
|
+
return new FunctionItem({
|
|
188
|
+
name: resolved.name,
|
|
189
|
+
arity: resolved.arity,
|
|
190
|
+
signature: resolved.signature,
|
|
191
|
+
invoke: (args) =>
|
|
192
|
+
resolved.call(args, { ...ctx, dyn: dynamicCallContext(ctx.dyn) }),
|
|
193
|
+
});
|
|
194
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `//T[P]` with a positional predicate (`//item[last()]`, `//x[1]`):
|
|
3
|
+
* `descendant-or-self::node()/child::T[P]`, which cannot become
|
|
4
|
+
* `descendant::T[P]` (see positional.js) because P sees the position of a
|
|
5
|
+
* node among the T children of its parent.
|
|
6
|
+
*
|
|
7
|
+
* Instead of applying `child::T[P]` to every node of the tree (one context
|
|
8
|
+
* and one child walk per node, text nodes included), one descendant walk
|
|
9
|
+
* collects the T nodes, grouped by parent in document order; P filters
|
|
10
|
+
* each group as it would filter the children of that parent. A parent
|
|
11
|
+
* without T children gives nothing in both evaluations.
|
|
12
|
+
*
|
|
13
|
+
* @module @tradik/xslt3/xpath/eval/groupedChildren
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { XPathError } from "../../errors.js";
|
|
17
|
+
import { isNode } from "../../xdm/atomic.js";
|
|
18
|
+
import { axisNodes } from "./descendantMemo.js";
|
|
19
|
+
import { parentOf } from "./domNodes.js";
|
|
20
|
+
import { compileNodeTest } from "./nodeTests.js";
|
|
21
|
+
import { compilePredicate } from "./predicates.js";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Whether a step is `descendant-or-self::node()` and the next one a child
|
|
25
|
+
* step: the pair `groupedChildren` evaluates (when the descendant shortcut
|
|
26
|
+
* of paths.js does not apply).
|
|
27
|
+
* @param {object} step
|
|
28
|
+
* @param {object|undefined} next
|
|
29
|
+
* @returns {boolean}
|
|
30
|
+
*/
|
|
31
|
+
export const isGroupedChildren = (step, next) =>
|
|
32
|
+
step.type === "AxisStep" &&
|
|
33
|
+
step.axis === "descendant-or-self" &&
|
|
34
|
+
step.nodeTest.type === "AnyKindTest" &&
|
|
35
|
+
step.predicates.length === 0 &&
|
|
36
|
+
next?.type === "AxisStep" &&
|
|
37
|
+
next.axis === "child";
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Compiles the child step of a `descendant-or-self::node()/child::T[P]`
|
|
41
|
+
* pair.
|
|
42
|
+
* @param {object} step - The child AxisStep
|
|
43
|
+
* @param {import("./scope.js").Scope} scope
|
|
44
|
+
* @param {Function} compile
|
|
45
|
+
* @returns {(input: Array, ctx: object) => Node[]} the nodes selected from
|
|
46
|
+
* the input nodes, in document order without duplicates
|
|
47
|
+
*/
|
|
48
|
+
export function compileGroupedChildren(step, scope, compile) {
|
|
49
|
+
const test = compileNodeTest(step.nodeTest, "child", scope.sc);
|
|
50
|
+
const predicates = step.predicates.map((p) =>
|
|
51
|
+
compilePredicate(p, scope, compile),
|
|
52
|
+
);
|
|
53
|
+
return (input, ctx) => {
|
|
54
|
+
// Candidates in document order when there is one input node
|
|
55
|
+
const found = [];
|
|
56
|
+
for (const node of input) {
|
|
57
|
+
if (!isNode(node)) {
|
|
58
|
+
throw new XPathError(
|
|
59
|
+
"XPTY0019",
|
|
60
|
+
"The left operand of / must contain only nodes",
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
const nodes = axisNodes("descendant", node, test, Infinity, ctx.dyn);
|
|
64
|
+
for (const n of nodes) found.push(n);
|
|
65
|
+
}
|
|
66
|
+
const groups = new Map();
|
|
67
|
+
// Walks from nested input nodes overlap
|
|
68
|
+
const seen = input.length > 1 ? new Set() : null;
|
|
69
|
+
for (const node of found) {
|
|
70
|
+
if (seen) {
|
|
71
|
+
if (seen.has(node)) continue;
|
|
72
|
+
seen.add(node);
|
|
73
|
+
}
|
|
74
|
+
const parent = parentOf(node);
|
|
75
|
+
const group = groups.get(parent);
|
|
76
|
+
if (group) group.push(node);
|
|
77
|
+
else groups.set(parent, [node]);
|
|
78
|
+
}
|
|
79
|
+
const kept = new Set();
|
|
80
|
+
for (const group of groups.values()) {
|
|
81
|
+
let nodes = group;
|
|
82
|
+
for (const predicate of predicates) nodes = predicate(nodes, ctx);
|
|
83
|
+
for (const node of nodes) kept.add(node);
|
|
84
|
+
}
|
|
85
|
+
if (input.length > 1) return ctx.dyn.order.sort([...kept]);
|
|
86
|
+
return found.filter((node) => kept.has(node));
|
|
87
|
+
};
|
|
88
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compiler of inline function expressions (XPath 3.1 section 3.1.7): a
|
|
3
|
+
* closure over the variables in scope, with an absent focus in its body;
|
|
4
|
+
* arguments and result are converted to the declared types.
|
|
5
|
+
*
|
|
6
|
+
* @module @tradik/xslt3/xpath/eval/inline
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { dynamicCallContext } from "./dynamicCall.js";
|
|
10
|
+
import { XPathError } from "../../errors.js";
|
|
11
|
+
import { FunctionItem } from "../../items/function.js";
|
|
12
|
+
import { coerce } from "./coercion.js";
|
|
13
|
+
import { bindVariable } from "./scope.js";
|
|
14
|
+
import { ANY_SEQUENCE, compileSequenceType } from "./sequenceType.js";
|
|
15
|
+
import { clark, namespaceOf } from "./staticContext.js";
|
|
16
|
+
|
|
17
|
+
/** Compilers by node type. */
|
|
18
|
+
export const inlineCompilers = {
|
|
19
|
+
InlineFunctionExpr(node, scope, compile) {
|
|
20
|
+
const { sc } = scope;
|
|
21
|
+
const keys = node.params.map((param) =>
|
|
22
|
+
clark(namespaceOf(param.name, sc, ""), param.name.local),
|
|
23
|
+
);
|
|
24
|
+
if (new Set(keys).size !== keys.length) {
|
|
25
|
+
throw new XPathError(
|
|
26
|
+
"XQST0039",
|
|
27
|
+
"Two parameters of an inline function have the same name",
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
const params = node.params.map((param) =>
|
|
31
|
+
param.sequenceType
|
|
32
|
+
? compileSequenceType(param.sequenceType, sc)
|
|
33
|
+
: ANY_SEQUENCE,
|
|
34
|
+
);
|
|
35
|
+
const returns = node.returnType
|
|
36
|
+
? compileSequenceType(node.returnType, sc)
|
|
37
|
+
: ANY_SEQUENCE;
|
|
38
|
+
let bodyScope = scope;
|
|
39
|
+
for (const key of keys) bodyScope = bindVariable(bodyScope, key);
|
|
40
|
+
const body = compile(node.body, bodyScope);
|
|
41
|
+
const arity = keys.length;
|
|
42
|
+
const argOptions = keys.map((_, i) => ({
|
|
43
|
+
what: `argument ${i + 1} of an inline function`,
|
|
44
|
+
}));
|
|
45
|
+
const resultOptions = { what: "result of an inline function" };
|
|
46
|
+
const signature = { params, returns };
|
|
47
|
+
return (ctx) => [
|
|
48
|
+
new FunctionItem({
|
|
49
|
+
arity,
|
|
50
|
+
signature,
|
|
51
|
+
invoke: (args) => {
|
|
52
|
+
let env = ctx.env;
|
|
53
|
+
for (let i = 0; i < arity; i++) {
|
|
54
|
+
env = {
|
|
55
|
+
value: coerce(args[i], params[i], argOptions[i]),
|
|
56
|
+
next: env,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
const value = body({
|
|
60
|
+
item: undefined,
|
|
61
|
+
position: 0,
|
|
62
|
+
size: 0,
|
|
63
|
+
env,
|
|
64
|
+
dyn: dynamicCallContext(ctx.dyn),
|
|
65
|
+
});
|
|
66
|
+
return coerce(value, returns, resultOptions);
|
|
67
|
+
},
|
|
68
|
+
}),
|
|
69
|
+
];
|
|
70
|
+
},
|
|
71
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Namespace nodes (XDM 3.1 section 6.4), which DOMs do not have: objects
|
|
3
|
+
* with nodeType 13 made for the in-scope namespaces of an element, once
|
|
4
|
+
* per element so that they keep their identity.
|
|
5
|
+
*
|
|
6
|
+
* The in-scope namespaces come from the `xmlns` attributes of the element
|
|
7
|
+
* and its ancestors, the names of the element and its attributes (DOMs
|
|
8
|
+
* built with createElementNS may lack the declarations), and the xml
|
|
9
|
+
* prefix, which is always in scope.
|
|
10
|
+
*
|
|
11
|
+
* @module @tradik/xslt3/xpath/eval/namespaceNodes
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { isNamespaceDeclaration, NODE_TYPES, parentOf } from "./domNodes.js";
|
|
15
|
+
|
|
16
|
+
/** The namespace bound to the xml prefix. */
|
|
17
|
+
export const XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace";
|
|
18
|
+
|
|
19
|
+
/** A namespace node: prefix ("" for the default namespace) and URI. */
|
|
20
|
+
export class NamespaceNode {
|
|
21
|
+
/**
|
|
22
|
+
* @param {Element} element - Parent element
|
|
23
|
+
* @param {string} prefix
|
|
24
|
+
* @param {string} uri
|
|
25
|
+
*/
|
|
26
|
+
constructor(element, prefix, uri) {
|
|
27
|
+
this.ownerElement = element;
|
|
28
|
+
this.localName = prefix;
|
|
29
|
+
this.nodeName = prefix;
|
|
30
|
+
this.nodeValue = uri;
|
|
31
|
+
this.namespaceURI = null;
|
|
32
|
+
this.prefix = null;
|
|
33
|
+
this.childNodes = [];
|
|
34
|
+
Object.freeze(this);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** @returns {number} 13, the nodeType of namespace nodes */
|
|
38
|
+
get nodeType() {
|
|
39
|
+
return NODE_TYPES.namespace;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** @type {WeakMap<Element, NamespaceNode[]>} */
|
|
44
|
+
const cache = new WeakMap();
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* In-scope namespaces of an element as prefix → URI ("" URI: undeclared).
|
|
48
|
+
* @param {Element} element
|
|
49
|
+
* @returns {Map<string, string>}
|
|
50
|
+
*/
|
|
51
|
+
export function inScopeNamespaces(element) {
|
|
52
|
+
const chain = [];
|
|
53
|
+
for (let e = element; e && e.nodeType === 1; e = parentOf(e)) chain.push(e);
|
|
54
|
+
const bindings = new Map();
|
|
55
|
+
for (const e of chain.reverse()) {
|
|
56
|
+
for (const attribute of e.attributes) {
|
|
57
|
+
if (!isNamespaceDeclaration(attribute)) continue;
|
|
58
|
+
const name = attribute.name ?? attribute.nodeName;
|
|
59
|
+
const prefix = name === "xmlns" ? "" : name.slice(6);
|
|
60
|
+
bindings.set(prefix, attribute.value ?? attribute.nodeValue);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const declare = (node) => {
|
|
64
|
+
if (node.namespaceURI) bindings.set(node.prefix ?? "", node.namespaceURI);
|
|
65
|
+
};
|
|
66
|
+
declare(element);
|
|
67
|
+
for (const attribute of element.attributes) {
|
|
68
|
+
if (!isNamespaceDeclaration(attribute) && attribute.prefix) {
|
|
69
|
+
declare(attribute);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
bindings.set("xml", XML_NAMESPACE);
|
|
73
|
+
return bindings;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @param {Element} element
|
|
78
|
+
* @returns {NamespaceNode[]} the namespace nodes of an element
|
|
79
|
+
*/
|
|
80
|
+
export function namespaceNodesOf(element) {
|
|
81
|
+
let nodes = cache.get(element);
|
|
82
|
+
if (!nodes) {
|
|
83
|
+
nodes = [];
|
|
84
|
+
for (const [prefix, uri] of inScopeNamespaces(element)) {
|
|
85
|
+
if (uri !== "") nodes.push(new NamespaceNode(element, prefix, uri));
|
|
86
|
+
}
|
|
87
|
+
cache.set(element, nodes);
|
|
88
|
+
}
|
|
89
|
+
return nodes;
|
|
90
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node tests (XPath 3.1 section 3.3.2.2) and kind tests (section 2.5.5.3)
|
|
3
|
+
* compiled to predicates on DOM nodes.
|
|
4
|
+
*
|
|
5
|
+
* @module @tradik/xslt3/xpath/eval/nodeTests
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { XPathError } from "../../errors.js";
|
|
9
|
+
import {
|
|
10
|
+
childrenOf,
|
|
11
|
+
isXdmNode,
|
|
12
|
+
nodeLocalName,
|
|
13
|
+
nodeNamespace,
|
|
14
|
+
} from "./domNodes.js";
|
|
15
|
+
import { clark, namespaceOf } from "./staticContext.js";
|
|
16
|
+
import { untypedMatches } from "./typeNames.js";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* A compiled kind test.
|
|
20
|
+
* @typedef {object} KindTest
|
|
21
|
+
* @property {string|null} kind - XDM node kind, null for node()
|
|
22
|
+
* @property {string|null} name - Clark name required, null for any
|
|
23
|
+
* @property {(node: Node) => boolean} matches - Applies to nodes only
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/** nodeType of the principal node kind of an axis. */
|
|
27
|
+
const principal = (axis) =>
|
|
28
|
+
axis === "attribute" ? 2 : axis === "namespace" ? 13 : 1;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @param {Node} node
|
|
32
|
+
* @returns {string} Clark name of a node
|
|
33
|
+
*/
|
|
34
|
+
const nodeName = (node) => clark(nodeNamespace(node), nodeLocalName(node));
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Element or attribute test with an optional name and type.
|
|
38
|
+
* @param {object} test - ElementTest or AttributeTest
|
|
39
|
+
* @param {"element"|"attribute"} kind
|
|
40
|
+
* @param {import("./staticContext.js").StaticContext} sc
|
|
41
|
+
* @returns {KindTest}
|
|
42
|
+
*/
|
|
43
|
+
function namedKindTest(test, kind, sc) {
|
|
44
|
+
const nodeType = kind === "element" ? 1 : 2;
|
|
45
|
+
const defaultNs = kind === "element" ? sc.defaultElementNamespace : "";
|
|
46
|
+
const name = test.name
|
|
47
|
+
? clark(namespaceOf(test.name, sc, defaultNs), test.name.local)
|
|
48
|
+
: null;
|
|
49
|
+
const typed = test.typeName ? untypedMatches(test.typeName, kind, sc) : true;
|
|
50
|
+
return {
|
|
51
|
+
kind,
|
|
52
|
+
name,
|
|
53
|
+
matches: (node) =>
|
|
54
|
+
typed &&
|
|
55
|
+
node.nodeType === nodeType &&
|
|
56
|
+
(name === null || nodeName(node) === name),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Kind test compilers by node type. */
|
|
61
|
+
const kindTests = {
|
|
62
|
+
AnyKindTest: () => ({ kind: null, name: null, matches: () => true }),
|
|
63
|
+
TextTest: () => ({
|
|
64
|
+
kind: "text",
|
|
65
|
+
name: null,
|
|
66
|
+
matches: (node) => node.nodeType === 3 || node.nodeType === 4,
|
|
67
|
+
}),
|
|
68
|
+
CommentTest: () => ({
|
|
69
|
+
kind: "comment",
|
|
70
|
+
name: null,
|
|
71
|
+
matches: (node) => node.nodeType === 8,
|
|
72
|
+
}),
|
|
73
|
+
NamespaceNodeTest: () => ({
|
|
74
|
+
kind: "namespace",
|
|
75
|
+
name: null,
|
|
76
|
+
matches: (node) => node.nodeType === 13,
|
|
77
|
+
}),
|
|
78
|
+
PITest: (test) => ({
|
|
79
|
+
kind: "processing-instruction",
|
|
80
|
+
name: test.target === null ? null : clark("", test.target),
|
|
81
|
+
matches: (node) =>
|
|
82
|
+
node.nodeType === 7 &&
|
|
83
|
+
(test.target === null || nodeLocalName(node) === test.target),
|
|
84
|
+
}),
|
|
85
|
+
ElementTest: (test, sc) => namedKindTest(test, "element", sc),
|
|
86
|
+
AttributeTest: (test, sc) => namedKindTest(test, "attribute", sc),
|
|
87
|
+
SchemaElementTest: (test, sc) => {
|
|
88
|
+
namespaceOf(test.name, sc, sc.defaultElementNamespace);
|
|
89
|
+
throw new XPathError(
|
|
90
|
+
"XPST0008",
|
|
91
|
+
`No element declaration for schema-element(${test.name.local})`,
|
|
92
|
+
);
|
|
93
|
+
},
|
|
94
|
+
SchemaAttributeTest: (test, sc) => {
|
|
95
|
+
namespaceOf(test.name, sc, "");
|
|
96
|
+
throw new XPathError(
|
|
97
|
+
"XPST0008",
|
|
98
|
+
`No attribute declaration for schema-attribute(${test.name.local})`,
|
|
99
|
+
);
|
|
100
|
+
},
|
|
101
|
+
DocumentTest: (test, sc) => {
|
|
102
|
+
const element = test.elementTest && compileKindTest(test.elementTest, sc);
|
|
103
|
+
const matches = (node) => {
|
|
104
|
+
if (node.nodeType !== 9 && node.nodeType !== 11) return false;
|
|
105
|
+
if (!element) return true;
|
|
106
|
+
const children = childrenOf(node);
|
|
107
|
+
const elements = children.filter((child) => child.nodeType === 1);
|
|
108
|
+
const others = children.every(
|
|
109
|
+
(child) =>
|
|
110
|
+
child.nodeType === 1 || child.nodeType === 7 || child.nodeType === 8,
|
|
111
|
+
);
|
|
112
|
+
return elements.length === 1 && others && element.matches(elements[0]);
|
|
113
|
+
};
|
|
114
|
+
return { kind: "document", name: null, element, matches };
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @param {import("../syntax/typeAst.js").KindTest} test
|
|
120
|
+
* @param {import("./staticContext.js").StaticContext} sc
|
|
121
|
+
* @returns {KindTest}
|
|
122
|
+
* @throws {XPathError} XPST0008 for schema-element(), schema-attribute()
|
|
123
|
+
* and unknown type names, XPST0081 for undeclared prefixes
|
|
124
|
+
*/
|
|
125
|
+
export function compileKindTest(test, sc) {
|
|
126
|
+
return kindTests[test.type](test, sc);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Compiles the node test of an axis step.
|
|
131
|
+
* @param {import("../syntax/typeAst.js").NodeTest} test
|
|
132
|
+
* @param {string} axis
|
|
133
|
+
* @param {import("./staticContext.js").StaticContext} sc
|
|
134
|
+
* @returns {(node: Node) => boolean} the test, false for the nodes that
|
|
135
|
+
* are not XDM nodes
|
|
136
|
+
*/
|
|
137
|
+
export function compileNodeTest(test, axis, sc) {
|
|
138
|
+
const nodeType = principal(axis);
|
|
139
|
+
if (test.type === "NameTest") {
|
|
140
|
+
const defaultNs = nodeType === 1 ? sc.defaultElementNamespace : "";
|
|
141
|
+
const uri = namespaceOf(test.name, sc, defaultNs);
|
|
142
|
+
const local = test.name.local;
|
|
143
|
+
// nodeLocalName() of the principal node kinds, without a second read
|
|
144
|
+
// of nodeType
|
|
145
|
+
const matches = (node) =>
|
|
146
|
+
node.nodeType === nodeType &&
|
|
147
|
+
(node.localName ?? node.nodeName) === local &&
|
|
148
|
+
nodeNamespace(node) === uri;
|
|
149
|
+
// The name, for axes that can look a node up by name (attribute)
|
|
150
|
+
matches.qname = { uri, local };
|
|
151
|
+
return matches;
|
|
152
|
+
}
|
|
153
|
+
if (test.type === "Wildcard") {
|
|
154
|
+
const uri = test.prefix !== null ? namespaceOf(test, sc, "") : test.uri;
|
|
155
|
+
const { local } = test;
|
|
156
|
+
return (node) =>
|
|
157
|
+
node.nodeType === nodeType &&
|
|
158
|
+
(local === null || nodeLocalName(node) === local) &&
|
|
159
|
+
(uri === null || nodeNamespace(node) === uri);
|
|
160
|
+
}
|
|
161
|
+
// node() on an axis: any XDM node, not a document type node
|
|
162
|
+
if (test.type === "AnyKindTest") return isXdmNode;
|
|
163
|
+
return compileKindTest(test, sc).matches;
|
|
164
|
+
}
|