xslt-processor 5.0.1 → 5.0.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 +6 -0
- package/dist/LICENSE +165 -0
- package/dist/README.md +513 -0
- package/{index.d.mts → dist/index.d.mts} +18 -17
- package/{index.d.ts → dist/index.d.ts} +18 -17
- package/{index.js → dist/index.js} +28 -13
- package/dist/index.js.map +1 -0
- package/{index.mjs → dist/index.mjs} +28 -13
- package/dist/index.mjs.map +1 -0
- package/{umd → dist/umd}/xslt-processor.global.js +2 -2
- package/dist/umd/xslt-processor.global.js.map +1 -0
- package/package.json +12 -9
- package/index.js.map +0 -1
- package/index.mjs.map +0 -1
- package/umd/xslt-processor.global.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/xpath/lib/src/expressions/expression.ts","../../src/xpath/lib/src/expressions/literal-expression.ts","../../src/xpath/lib/src/constants.ts","../../src/xpath/lib/src/errors.ts","../../src/xpath/lib/src/expressions/variable-reference-expression.ts","../../src/xpath/lib/src/expressions/step-expression.ts","../../src/xpath/lib/src/expressions/location-path-expression.ts","../../src/xpath/lib/src/expressions/filter-expression.ts","../../src/xpath/lib/src/expressions/unary-expression.ts","../../src/xpath/lib/src/expressions/binary-expression.ts","../../src/xpath/lib/src/expressions/arithmetic-expression.ts","../../src/xpath/lib/src/expressions/logical-expression.ts","../../src/xpath/lib/src/expressions/conditional-expression.ts","../../src/xpath/lib/src/expressions/for-expression.ts","../../src/xpath/lib/src/expressions/quantified-expression.ts","../../src/xpath/lib/src/types/base.ts","../../src/xpath/lib/src/types/sequence-type.ts","../../src/xpath/lib/src/types/kind-tests.ts","../../src/xpath/lib/src/types/union-type.ts","../../src/xpath/lib/src/types/sequence-type-matcher.ts","../../src/xpath/lib/src/types/atomization.ts","../../src/xpath/lib/src/expressions/map-constructor-expression.ts","../../src/xpath/lib/src/expressions/array-constructor-expression.ts","../../src/xpath/lib/src/types/typed-collection-types.ts","../../src/xpath/lib/src/types/type-promotion.ts","../../src/xpath/lib/src/types/simple-types.ts","../../src/xpath/lib/src/types/numeric-types.ts","../../src/xpath/lib/src/types/datetime-types.ts","../../src/xpath/lib/src/types/gregorian-types.ts","../../src/xpath/lib/src/types/binary-types.ts","../../src/xpath/lib/src/types/uri-qname-types.ts","../../src/xpath/lib/src/types/integer-derived-types.ts","../../src/xpath/lib/src/types/function-type.ts","../../src/xpath/lib/src/schema/psvi.ts","../../src/xpath/lib/src/types/schema-aware-types.ts","../../src/xpath/lib/src/types/index.ts","../../src/xpath/lib/src/expressions/instance-of-expression.ts","../../src/xpath/lib/src/expressions/castable-expression.ts","../../src/xpath/lib/src/expressions/treat-expression.ts","../../src/xpath/lib/src/expressions/union-expression.ts","../../src/xpath/lib/src/expressions/sequence-construction.ts","../../src/xpath/lib/src/expressions/predicate-expression.ts","../../src/xpath/lib/src/expressions/value-comparison.ts","../../src/xpath/lib/src/expressions/general-comparison.ts","../../src/xpath/lib/src/expressions/node-comparison.ts","../../src/xpath/lib/src/expressions/json-to-xml-converter.ts","../../src/xpath/lib/src/functions/higher-order-functions.ts","../../src/xpath/lib/src/functions/math-functions.ts","../../src/xpath/lib/src/functions/sequence-functions.ts","../../src/xpath/lib/src/functions/sequence-functions-30.ts","../../src/xpath/lib/src/functions/environment-functions.ts","../../src/xpath/lib/src/functions/string-functions-30.ts","../../src/xpath/lib/src/functions/array-functions.ts","../../src/xpath/lib/src/functions/map-functions.ts","../../src/xpath/lib/src/functions/json-functions.ts","../../src/xpath/lib/src/functions/qname-functions.ts","../../src/xpath/lib/src/functions/uri-functions.ts","../../src/xpath/lib/src/functions/node-functions.ts","../../src/xpath/lib/src/expressions/function-call-expression.ts","../../src/xpath/lib/src/expressions/let-expression.ts","../../src/xpath/lib/src/expressions/simple-map-expression.ts","../../src/xpath/lib/src/expressions/string-concat-expression.ts","../../src/xpath/lib/src/expressions/string-template-expression.ts","../../src/xpath/lib/src/expressions/arrow-expression.ts","../../src/xpath/lib/src/expressions/named-function-ref-expression.ts","../../src/xpath/lib/src/expressions/inline-function-expression.ts","../../src/xpath/lib/src/expressions/dynamic-function-call-expression.ts","../../src/xpath/lib/src/expressions/try-expression.ts","../../src/xpath/lib/src/expressions/lookup-expression.ts","../../src/xpath/lib/src/expressions/index.ts","../../src/index.ts","../../src/xpath/lib/src/lexer/token.ts","../../src/xpath/lib/src/lexer/lexer.ts","../../src/xpath/lib/src/parser/base-parser.ts","../../src/xpath/lib/src/static-context.ts","../../src/xpath/lib/src/xslt-extensions.ts","../../src/xpath/lib/src/warnings.ts","../../src/xpath/lib/src/parser/parser-10.ts","../../src/xpath/lib/src/parser/parser-20.ts","../../src/xpath/lib/src/parser/parser-30.ts","../../src/xpath/lib/src/parser/parser-31.ts","../../src/xpath/lib/src/parser/index.ts","../../src/xpath/xpath.ts","../../src/dom/xnode.ts","../../src/dom/xdocument.ts","../../src/dom/dom-to-xdocument.ts","../../src/dom/functions.ts","../../src/dom/html-entity-decoder.ts","../../src/dom/xml-functions.ts","../../src/dom/xmltoken.ts","../../src/dom/xml-parser.ts","../../src/xpath/lib/src/context.ts","../../src/xpath/values/node-set-value.ts","../../src/xpath/values/string-value.ts","../../src/xpath/values/number-value.ts","../../src/xpath/values/boolean-value.ts","../../src/xpath/values/map-value.ts","../../src/xpath/values/array-value.ts","../../src/xpath/values/function-value.ts","../../src/xpath/expressions/node-converter.ts","../../src/xpath/expressions/expression.ts","../../src/xpath/expressions/location-expr.ts","../../src/xpath/expressions/union-expr.ts","../../src/xpath/tokens.ts","../../src/xpath/expr-context.ts","../../src/xpath/match-resolver.ts","../../src/xpath/node-tests/node-test-any.ts","../../src/xpath/node-tests/node-test-comment.ts","../../src/xpath/node-tests/node-test-element-or-attribute.ts","../../src/xpath/node-tests/node-test-name.ts","../../src/xpath/node-tests/node-test-nc.ts","../../src/xpath/node-tests/node-test-pi.ts","../../src/xpath/node-tests/node-test-text.ts","../../src/xslt/package-system/functions.ts","../../src/xslt/package-system/package-registry.ts","../../src/xslt/streaming/streamable-pattern-validator.ts","../../src/xslt/streaming/streaming-context.ts","../../src/xslt/streaming/streaming-copy-manager.ts","../../src/xslt/streaming/streaming-merge-coordinator.ts","../../src/xslt/streaming/streaming-mode-detector.ts","../../src/xslt/streaming/streaming-parser-base.ts","../../src/xslt/streaming/streaming-processor.ts","../../src/xslt/functions.ts","../../src/xslt/xslt-accumulator.ts","../../src/xslt/xslt.ts"],"sourcesContent":["import { XPathContext, XPathResult } from '../context';\r\n\r\nexport abstract class XPathExpression {\r\n abstract evaluate(context: XPathContext): XPathResult;\r\n}\r\n","import { XPathContext } from '../context';\r\nimport { XPathExpression } from './expression';\r\n\r\nexport class XPathStringLiteral extends XPathExpression {\r\n value: string;\r\n\r\n constructor(value: string) {\r\n super();\r\n this.value = value;\r\n }\r\n\r\n evaluate(_context: XPathContext): string {\r\n return this.value;\r\n }\r\n\r\n toString(): string {\r\n return `\"${this.value}\"`;\r\n }\r\n}\r\n\r\nexport class XPathNumberLiteral extends XPathExpression {\r\n value: number;\r\n\r\n constructor(value: number) {\r\n super();\r\n this.value = value;\r\n }\r\n\r\n evaluate(_context: XPathContext): number {\r\n return this.value;\r\n }\r\n\r\n toString(): string {\r\n return this.value.toString();\r\n }\r\n}\r\n","/**\r\n * Unified Constants File for XPath Implementation\r\n *\r\n * Consolidates all export const declarations from throughout the codebase\r\n * for improved maintainability and easier discovery.\r\n */\r\n\r\n// ============================================================================\r\n// DOM Node Type Constants (matching W3C DOM specification)\r\n// ============================================================================\r\n\r\nexport const NodeType = {\r\n ELEMENT_NODE: 1,\r\n ATTRIBUTE_NODE: 2,\r\n TEXT_NODE: 3,\r\n CDATA_SECTION_NODE: 4,\r\n PROCESSING_INSTRUCTION_NODE: 7,\r\n COMMENT_NODE: 8,\r\n DOCUMENT_NODE: 9,\r\n DOCUMENT_FRAGMENT_NODE: 11,\r\n NAMESPACE_NODE: 13,\r\n} as const;\r\n\r\n// ============================================================================\r\n// XML Schema & Namespace Constants\r\n// ============================================================================\r\n\r\n/** XML Schema namespace URI per W3C XML Schema specification */\r\nexport const XS_NAMESPACE = 'http://www.w3.org/2001/XMLSchema';\r\n\r\n/** XPath error namespace per W3C XPath 2.0 specification */\r\nexport const XPATH_ERROR_NAMESPACE = 'http://www.w3.org/2005/xqt-errors';\r\n\r\n/** Default function namespace for XPath/XQuery Functions and Operators library */\r\nexport const DEFAULT_FUNCTION_NAMESPACE = 'http://www.w3.org/2005/xpath-functions';\r\n\r\n/** Unicode codepoint collation URI (default per W3C specification) */\r\nexport const DEFAULT_COLLATION = 'http://www.w3.org/2005/xpath-functions/collation/codepoint';\r\n\r\n// ============================================================================\r\n// Reserved Function Names (Appendix A.3)\r\n// ============================================================================\r\n\r\n/**\r\n * Reserved function names per XPath specification.\r\n * These should not be overridden by user-defined function signatures.\r\n */\r\nexport const RESERVED_FUNCTION_NAMES: ReadonlyArray<string> = [\r\n 'last',\r\n 'position',\r\n 'count',\r\n 'id',\r\n 'local-name',\r\n 'namespace-uri',\r\n 'name',\r\n 'string',\r\n 'concat',\r\n 'starts-with',\r\n 'contains',\r\n 'substring-before',\r\n 'substring-after',\r\n 'substring',\r\n 'string-length',\r\n 'normalize-space',\r\n 'translate',\r\n 'boolean',\r\n 'not',\r\n 'true',\r\n 'false',\r\n 'lang',\r\n 'number',\r\n 'sum',\r\n 'floor',\r\n 'ceiling',\r\n 'round',\r\n];\r\n","/**\r\n * XPath 2.0 Error System (Phase 7.1)\r\n *\r\n * Implements error handling per W3C XPath 2.0 Recommendation Section 2.3:\r\n * - Static Errors (XPST*) - occur during static analysis\r\n * - Dynamic Errors (XPDY*) - occur during evaluation\r\n * - Type Errors (XPTY*) - type mismatch or type constraint violation\r\n *\r\n * Reference: https://www.w3.org/TR/xpath20/#errors\r\n */\r\n\r\nimport { XPATH_ERROR_NAMESPACE } from './constants';\r\n\r\n// Re-export constant from unified constants.ts\r\nexport { XPATH_ERROR_NAMESPACE };\r\n\r\n/**\r\n * Base error class for all XPath errors\r\n */\r\nexport class XPathError extends Error {\r\n declare code: string;\r\n declare isStatic: boolean;\r\n declare isDynamic: boolean;\r\n\r\n constructor(\r\n code: string,\r\n message: string,\r\n isStatic: boolean = false,\r\n isDynamic: boolean = false\r\n ) {\r\n super(`${code}: ${message}`);\r\n Object.setPrototypeOf(this, XPathError.prototype);\r\n this.code = code;\r\n this.isStatic = isStatic;\r\n this.isDynamic = isDynamic;\r\n this.name = 'XPathError';\r\n // Maintain proper stack trace for where our error was thrown (only available on V8)\r\n if (Error.captureStackTrace) {\r\n Error.captureStackTrace(this, this.constructor);\r\n }\r\n }\r\n\r\n /**\r\n * Get qualified error QName (e.g., \"err:XPST0001\")\r\n */\r\n getQName(): string {\r\n return `err:${this.code}`;\r\n }\r\n\r\n /**\r\n * Get error URI for namespace\r\n */\r\n getErrorURI(): string {\r\n return `${XPATH_ERROR_NAMESPACE}#${this.code}`;\r\n }\r\n}\r\n\r\n/**\r\n * Static error - detected during static analysis (parsing, early binding)\r\n * Cannot be caught by try-catch in XPath expressions\r\n */\r\nexport class XPathStaticError extends XPathError {\r\n constructor(code: string, message: string) {\r\n super(code, message, true, false);\r\n Object.setPrototypeOf(this, XPathStaticError.prototype);\r\n this.name = 'XPathStaticError';\r\n }\r\n}\r\n\r\n/**\r\n * Dynamic error - detected during expression evaluation\r\n * Can be caught by try-catch in XPath expressions\r\n */\r\nexport class XPathDynamicError extends XPathError {\r\n constructor(code: string, message: string) {\r\n super(code, message, false, true);\r\n Object.setPrototypeOf(this, XPathDynamicError.prototype);\r\n this.name = 'XPathDynamicError';\r\n }\r\n}\r\n\r\n/**\r\n * Type error - type mismatch or type constraint violation\r\n * Subclass of dynamic error per spec\r\n */\r\nexport class XPathTypeError extends XPathDynamicError {\r\n constructor(code: string, message: string) {\r\n super(code, message);\r\n Object.setPrototypeOf(this, XPathTypeError.prototype);\r\n this.name = 'XPathTypeError';\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// STATIC ERRORS (XPST*)\r\n// ============================================================================\r\n\r\n/**\r\n * XPST0001: Static context component undefined\r\n */\r\nexport function staticContextComponentUndefined(component: string): XPathStaticError {\r\n return new XPathStaticError('XPST0001', `Static context component undefined: ${component}`);\r\n}\r\n\r\n/**\r\n * XPST0003: Grammar violation (syntax error)\r\n */\r\nexport function grammarViolation(message: string): XPathStaticError {\r\n return new XPathStaticError('XPST0003', `Grammar violation: ${message}`);\r\n}\r\n\r\n/**\r\n * XPST0005: Empty sequence used in required context\r\n */\r\nexport function emptySequenceNotAllowed(context: string): XPathStaticError {\r\n return new XPathStaticError('XPST0005', `Empty sequence is not allowed in ${context}`);\r\n}\r\n\r\n/**\r\n * XPST0008: Unresolved name reference\r\n */\r\nexport function unresolvedNameReference(name: string, type: string = 'name'): XPathStaticError {\r\n return new XPathStaticError('XPST0008', `Unresolved ${type} reference: ${name}`);\r\n}\r\n\r\n/**\r\n * XPST0010: Unsupported axis\r\n */\r\nexport function unsupportedAxis(axis: string): XPathStaticError {\r\n return new XPathStaticError('XPST0010', `Unsupported axis: ${axis}`);\r\n}\r\n\r\n/**\r\n * XPST0017: Function signature mismatch\r\n */\r\nexport function functionSignatureMismatch(\r\n functionName: string,\r\n expectedArgs: string,\r\n actualArgs: number\r\n): XPathStaticError {\r\n return new XPathStaticError(\r\n 'XPST0017',\r\n `Function ${functionName} expects ${expectedArgs}, got ${actualArgs} arguments`\r\n );\r\n}\r\n\r\n/**\r\n * XPST0051: Unknown atomic type or unsupported cast target\r\n */\r\nexport function unknownAtomicType(typeName: string): XPathStaticError {\r\n return new XPathStaticError('XPST0051', `Unknown atomic type: ${typeName}`);\r\n}\r\n\r\n/**\r\n * XPST0080: NOTATION or xs:anyAtomicType used in cast\r\n */\r\nexport function notationOrAnyAtomicInCast(typeName: string): XPathStaticError {\r\n return new XPathStaticError(\r\n 'XPST0080',\r\n `NOTATION and xs:anyAtomicType cannot be used in cast: ${typeName}`\r\n );\r\n}\r\n\r\n// ============================================================================\r\n// DYNAMIC ERRORS (XPDY*)\r\n// ============================================================================\r\n\r\n/**\r\n * XPDY0002: Dynamic context component undefined\r\n */\r\nexport function dynamicContextUndefined(component: string): XPathDynamicError {\r\n return new XPathDynamicError('XPDY0002', `Dynamic context component undefined: ${component}`);\r\n}\r\n\r\n/**\r\n * XPDY0050: Context item is not a node (or document in specific contexts)\r\n */\r\nexport function contextItemNotNode(context?: string): XPathDynamicError {\r\n const msg = context ? `Context item is not a ${context}` : 'Context item is not a node';\r\n return new XPathDynamicError('XPDY0050', msg);\r\n}\r\n\r\n// ============================================================================\r\n// TYPE ERRORS (XPTY*)\r\n// ============================================================================\r\n\r\n/**\r\n * XPTY0004: Type mismatch\r\n */\r\nexport function typeMismatch(expected: string, actual: string, context?: string): XPathTypeError {\r\n const msg = context\r\n ? `Type mismatch in ${context}: expected ${expected}, got ${actual}`\r\n : `Type mismatch: expected ${expected}, got ${actual}`;\r\n return new XPathTypeError('XPTY0004', msg);\r\n}\r\n\r\n/**\r\n * XPTY0018: Mixed node-set and atomic values in path\r\n */\r\nexport function mixedPathContent(): XPathTypeError {\r\n return new XPathTypeError(\r\n 'XPTY0018',\r\n 'Cannot mix node-set and atomic values in path expression'\r\n );\r\n}\r\n\r\n/**\r\n * XPTY0019: Non-node in path step\r\n */\r\nexport function nonNodeInPath(actual: string): XPathTypeError {\r\n return new XPathTypeError('XPTY0019', `Path step requires node, got ${actual}`);\r\n}\r\n\r\n/**\r\n * XPTY0020: Context item is not a node\r\n */\r\nexport function contextItemNotNodeInPath(): XPathTypeError {\r\n return new XPathTypeError('XPTY0020', 'Context item is not a node for path evaluation');\r\n}\r\n\r\n// ============================================================================\r\n// FUNCTION EXECUTION ERRORS (FORG, FOTY, FODT, etc.)\r\n// ============================================================================\r\n\r\n/**\r\n * FORG0001: Invalid casting/conversion argument\r\n */\r\nexport function invalidCastArgument(value: unknown, targetType: string): XPathDynamicError {\r\n return new XPathDynamicError(\r\n 'FORG0001',\r\n `Cannot cast ${JSON.stringify(value)} to ${targetType}`\r\n );\r\n}\r\n\r\n/**\r\n * FOTY0012: String value of element with element-only content\r\n */\r\nexport function elementOnlyContent(): XPathDynamicError {\r\n return new XPathDynamicError(\r\n 'FOTY0012',\r\n 'Cannot extract string value from element with element-only content'\r\n );\r\n}\r\n\r\n/**\r\n * FODT0002: Invalid timezone specification\r\n */\r\nexport function invalidTimezone(timezone: string): XPathDynamicError {\r\n return new XPathDynamicError('FODT0002', `Invalid timezone specification: ${timezone}`);\r\n}\r\n\r\n/**\r\n * Division by zero error (special numeric error)\r\n */\r\nexport function divisionByZero(): XPathDynamicError {\r\n return new XPathDynamicError('FOAR0001', 'Division by zero');\r\n}\r\n\r\n// ============================================================================\r\n// VALIDATION HELPERS\r\n// ============================================================================\r\n\r\n/**\r\n * Validate that a value is not null/undefined\r\n */\r\nexport function validateNotUndefined<T>(value: T | null | undefined, context: string): T {\r\n if (value === null || value === undefined) {\r\n throw dynamicContextUndefined(context);\r\n }\r\n return value;\r\n}\r\n\r\n/**\r\n * Validate function argument count\r\n */\r\nexport function validateArgumentCount(\r\n functionName: string,\r\n actualCount: number,\r\n expectedMin: number,\r\n expectedMax: number = expectedMin\r\n): void {\r\n if (actualCount < expectedMin || actualCount > expectedMax) {\r\n const expected =\r\n expectedMin === expectedMax\r\n ? expectedMin.toString()\r\n : `${expectedMin} to ${expectedMax}`;\r\n throw functionSignatureMismatch(functionName, expected, actualCount);\r\n }\r\n}\r\n\r\n/**\r\n * Validate that operands are compatible for arithmetic\r\n */\r\nexport function validateNumericOperands(left: unknown, right: unknown): void {\r\n if (left === null || left === undefined || right === null || right === undefined) {\r\n // Empty sequence in arithmetic is valid (returns null/NaN)\r\n return;\r\n }\r\n if (typeof left !== 'number' && typeof left !== 'string' && typeof left !== 'boolean') {\r\n throw typeMismatch('numeric type', typeof left, 'arithmetic operation');\r\n }\r\n if (typeof right !== 'number' && typeof right !== 'string' && typeof right !== 'boolean') {\r\n throw typeMismatch('numeric type', typeof right, 'arithmetic operation');\r\n }\r\n}\r\n\r\n/**\r\n * Check if error is a static error\r\n */\r\nexport function isStaticError(error: unknown): error is XPathStaticError {\r\n return error instanceof XPathStaticError;\r\n}\r\n\r\n/**\r\n * Check if error is a dynamic error\r\n */\r\nexport function isDynamicError(error: unknown): error is XPathDynamicError {\r\n return error instanceof XPathDynamicError;\r\n}\r\n\r\n/**\r\n * Check if error is an XPath error\r\n */\r\nexport function isXPathError(error: unknown): error is XPathError {\r\n return error instanceof XPathError;\r\n}\r\n\r\n/**\r\n * Extract XPath error code from error\r\n */\r\nexport function getErrorCode(error: unknown): string | null {\r\n if (isXPathError(error)) {\r\n return error.code;\r\n }\r\n return null;\r\n}\r\n\r\n/**\r\n * Format error for display (includes code and message)\r\n */\r\nexport function formatError(error: unknown): string {\r\n if (isXPathError(error)) {\r\n return error.message;\r\n }\r\n if (error instanceof Error) {\r\n return error.message;\r\n }\r\n return String(error);\r\n}\r\n","import { XPathContext, XPathResult } from '../context';\r\nimport { XPathExpression } from './expression';\r\nimport { unresolvedNameReference } from '../errors';\r\n\r\nexport class XPathVariableReference extends XPathExpression {\r\n name: string;\r\n\r\n constructor(name: string) {\r\n super();\r\n this.name = name;\r\n }\r\n\r\n evaluate(context: XPathContext): XPathResult {\r\n if (!context.variables) {\r\n throw unresolvedNameReference(`$${this.name}`, 'variable');\r\n }\r\n\r\n if (!(this.name in context.variables)) {\r\n throw unresolvedNameReference(`$${this.name}`, 'variable');\r\n }\r\n\r\n return context.variables[this.name];\r\n }\r\n\r\n toString(): string {\r\n return `$${this.name}`;\r\n }\r\n}\r\n","import { XPathExpression } from './expression';\r\n\r\nexport type AxisType =\r\n | 'ancestor'\r\n | 'ancestor-or-self'\r\n | 'attribute'\r\n | 'child'\r\n | 'descendant'\r\n | 'descendant-or-self'\r\n | 'following'\r\n | 'following-sibling'\r\n | 'namespace'\r\n | 'parent'\r\n | 'preceding'\r\n | 'preceding-sibling'\r\n | 'self'\r\n | 'self-and-siblings'; // Custom axis for XSLT template matching\r\n\r\nexport interface NodeTest {\r\n type:\r\n | 'name'\r\n | 'node-type'\r\n | 'wildcard'\r\n | 'processing-instruction'\r\n | 'element'\r\n | 'attribute'\r\n | 'schema-element'\r\n | 'schema-attribute'\r\n | 'document-node';\r\n name?: string;\r\n nodeType?: 'node' | 'text' | 'comment' | 'processing-instruction';\r\n elementType?: string; // Type constraint for element/attribute tests\r\n isWildcardName?: boolean; // Indicates wildcard in element(*, type) or attribute(*, type)\r\n target?: string; // For processing-instruction(target)\r\n elementTest?: NodeTest; // For document-node(element(...))\r\n}\r\n\r\nexport class XPathStep extends XPathExpression {\r\n axis: AxisType;\r\n nodeTest: NodeTest;\r\n predicates: XPathExpression[];\r\n\r\n constructor(axis: AxisType, nodeTest: NodeTest, predicates: XPathExpression[] = []) {\r\n super();\r\n this.axis = axis;\r\n this.nodeTest = nodeTest;\r\n this.predicates = predicates;\r\n }\r\n\r\n evaluate(context: any): any[] {\r\n const node = context?.node;\r\n\r\n // XPath 3.0: When the context item is an atomic value and axis is 'self',\r\n // return the atomic value (stored in context.contextItem)\r\n if (!node && this.axis === 'self' && context?.contextItem !== undefined) {\r\n const item = context.contextItem;\r\n // Apply predicates if any\r\n if (this.predicates.length === 0) {\r\n return [item];\r\n }\r\n // For atomic items with predicates, evaluate predicates\r\n return this.applyPredicatesToAtomicItem(item, context);\r\n }\r\n\r\n if (!node) return [];\r\n\r\n // Get candidate nodes based on axis\r\n let candidates = this.getNodesByAxis(node, context);\r\n\r\n // Filter by node test (pass context for namespace resolution)\r\n candidates = candidates.filter((n) => this.matchesNodeTest(n, context));\r\n\r\n // Apply predicates\r\n candidates = this.applyPredicates(candidates, context);\r\n\r\n return candidates;\r\n }\r\n\r\n /**\r\n * Apply predicates to an atomic item context.\r\n */\r\n private applyPredicatesToAtomicItem(item: any, context: any): any[] {\r\n const itemContext = { ...context, contextItem: item, position: 1, size: 1 };\r\n for (const predicate of this.predicates) {\r\n const result = predicate.evaluate(itemContext);\r\n // Numeric predicate: position check\r\n if (typeof result === 'number') {\r\n if (result !== 1) return [];\r\n } else if (!this.toBoolean(result)) {\r\n return [];\r\n }\r\n }\r\n return [item];\r\n }\r\n\r\n private getNodesByAxis(node: any, context?: any): any[] {\r\n switch (this.axis) {\r\n case 'child':\r\n // Filter out attribute nodes (nodeType 2) from childNodes\r\n return this.getChildNodes(node);\r\n\r\n case 'parent':\r\n return node.parentNode ? [node.parentNode] : [];\r\n\r\n case 'self':\r\n return [node];\r\n\r\n case 'attribute':\r\n // Attributes can be in a separate 'attributes' property or mixed in childNodes\r\n if (node.attributes) {\r\n return Array.from(node.attributes);\r\n }\r\n // Fallback: filter childNodes for attribute nodes\r\n return Array.from(node.childNodes || []).filter((n: any) => n.nodeType === 2);\r\n\r\n case 'descendant':\r\n return this.getDescendants(node, false);\r\n\r\n case 'descendant-or-self':\r\n return this.getDescendants(node, true);\r\n\r\n case 'ancestor':\r\n return this.getAncestors(node, false);\r\n\r\n case 'ancestor-or-self':\r\n return this.getAncestors(node, true);\r\n\r\n case 'following-sibling':\r\n return this.getFollowingSiblings(node);\r\n\r\n case 'preceding-sibling':\r\n return this.getPrecedingSiblings(node);\r\n\r\n case 'following':\r\n return this.getFollowing(node);\r\n\r\n case 'preceding':\r\n return this.getPreceding(node);\r\n\r\n case 'namespace':\r\n return this.getNamespaceNodes(node);\r\n\r\n case 'self-and-siblings':\r\n // Custom axis for XSLT template matching\r\n // Returns all nodes in the context's nodeList (excluding attributes)\r\n if (context?.nodeList) {\r\n return context.nodeList.filter((n: any) => n.nodeType !== 2);\r\n }\r\n // Fallback: just return self\r\n return [node];\r\n\r\n default:\r\n return [];\r\n }\r\n }\r\n\r\n /**\r\n * Get child nodes excluding attribute nodes.\r\n * XNode stores attributes in childNodes, but XPath child axis doesn't include them.\r\n */\r\n private getChildNodes(node: any): any[] {\r\n const children = Array.from(node.childNodes || []);\r\n // Filter out attribute nodes (nodeType 2)\r\n return children.filter((n: any) => n.nodeType !== 2);\r\n }\r\n\r\n private getDescendants(node: any, includeSelf: boolean): any[] {\r\n const result: any[] = [];\r\n if (includeSelf) result.push(node);\r\n\r\n const walk = (n: any) => {\r\n // Use getChildNodes to exclude attribute nodes\r\n for (const child of this.getChildNodes(n)) {\r\n result.push(child);\r\n walk(child);\r\n }\r\n };\r\n walk(node);\r\n return result;\r\n }\r\n\r\n private getAncestors(node: any, includeSelf: boolean): any[] {\r\n const result: any[] = [];\r\n if (includeSelf) result.push(node);\r\n\r\n let current = node.parentNode;\r\n while (current) {\r\n result.push(current);\r\n current = current.parentNode;\r\n }\r\n return result;\r\n }\r\n\r\n private getFollowingSiblings(node: any): any[] {\r\n const result: any[] = [];\r\n let sibling = node.nextSibling;\r\n while (sibling) {\r\n result.push(sibling);\r\n sibling = sibling.nextSibling;\r\n }\r\n return result;\r\n }\r\n\r\n private getPrecedingSiblings(node: any): any[] {\r\n const result: any[] = [];\r\n let sibling = node.previousSibling;\r\n while (sibling) {\r\n result.unshift(sibling);\r\n sibling = sibling.previousSibling;\r\n }\r\n return result;\r\n }\r\n\r\n private getFollowing(node: any): any[] {\r\n const result: any[] = [];\r\n\r\n // First, following siblings and their descendants\r\n let sibling = node.nextSibling;\r\n while (sibling) {\r\n result.push(sibling);\r\n result.push(...this.getDescendants(sibling, false));\r\n sibling = sibling.nextSibling;\r\n }\r\n\r\n // Then ancestors' following siblings\r\n let ancestor = node.parentNode;\r\n while (ancestor) {\r\n sibling = ancestor.nextSibling;\r\n while (sibling) {\r\n result.push(sibling);\r\n result.push(...this.getDescendants(sibling, false));\r\n sibling = sibling.nextSibling;\r\n }\r\n ancestor = ancestor.parentNode;\r\n }\r\n\r\n return result;\r\n }\r\n\r\n private getPreceding(node: any): any[] {\r\n const result: any[] = [];\r\n\r\n // Preceding siblings and their descendants (in reverse document order)\r\n let sibling = node.previousSibling;\r\n while (sibling) {\r\n result.unshift(sibling);\r\n const descendants = this.getDescendants(sibling, false);\r\n result.unshift(...descendants);\r\n sibling = sibling.previousSibling;\r\n }\r\n\r\n // Ancestors' preceding siblings\r\n let ancestor = node.parentNode;\r\n while (ancestor) {\r\n sibling = ancestor.previousSibling;\r\n while (sibling) {\r\n result.unshift(sibling);\r\n const descendants = this.getDescendants(sibling, false);\r\n result.unshift(...descendants);\r\n sibling = sibling.previousSibling;\r\n }\r\n ancestor = ancestor.parentNode;\r\n }\r\n\r\n return result;\r\n }\r\n\r\n private getNamespaceNodes(node: any): any[] {\r\n if (!node || node.nodeType !== 1) return [];\r\n\r\n const namespaces: Record<string, string> = {};\r\n\r\n let current: any = node;\r\n while (current) {\r\n type AttrLike = {\r\n nodeName?: string;\r\n localName?: string;\r\n nodeValue?: string | null;\r\n textContent?: string | null;\r\n };\r\n\r\n const attrs = Array.from(current.attributes || []) as AttrLike[];\r\n for (const attr of attrs) {\r\n const name = attr.nodeName || attr.localName || '';\r\n const value = attr.nodeValue ?? attr.textContent ?? '';\r\n\r\n if (name === 'xmlns') {\r\n if (!('' in namespaces)) {\r\n namespaces[''] = value;\r\n }\r\n } else if (name.startsWith('xmlns:')) {\r\n const prefix = name.substring('xmlns:'.length);\r\n if (!(prefix in namespaces)) {\r\n namespaces[prefix] = value;\r\n }\r\n }\r\n }\r\n\r\n current = current.parentNode;\r\n }\r\n\r\n if (!('xml' in namespaces)) {\r\n namespaces['xml'] = 'http://www.w3.org/XML/1998/namespace';\r\n }\r\n\r\n return Object.entries(namespaces).map(([prefix, uri]) => ({\r\n nodeType: 13,\r\n nodeName: prefix,\r\n localName: prefix,\r\n prefix,\r\n namespaceURI: uri,\r\n namespaceUri: uri,\r\n nodeValue: uri,\r\n textContent: uri,\r\n parentNode: node,\r\n ownerDocument: node.ownerDocument,\r\n }));\r\n }\r\n\r\n private matchesNodeTest(node: any, context?: any, test: NodeTest = this.nodeTest): boolean {\r\n const nodeType = node.nodeType;\r\n\r\n const matchesQName = (testName: string, allowedNodeTypes: number[]): boolean => {\r\n if (!allowedNodeTypes.includes(nodeType)) return false;\r\n\r\n // Namespace wildcard (prefix:*)\r\n if (testName.endsWith(':*')) {\r\n const prefix = testName.slice(0, -2);\r\n const nsUri = context?.namespaces?.[prefix];\r\n if (!nsUri) return false;\r\n const nodeNsUri = node.namespaceURI || node.namespaceUri || '';\r\n return nodeNsUri === nsUri;\r\n }\r\n\r\n const colonIndex = testName.indexOf(':');\r\n if (colonIndex > 0) {\r\n const prefix = testName.substring(0, colonIndex);\r\n const localName = testName.substring(colonIndex + 1);\r\n const nsUri = context?.namespaces?.[prefix];\r\n if (!nsUri) return false;\r\n\r\n const nodeLocalName =\r\n node.localName || (node.nodeName && this.extractLocalName(node.nodeName));\r\n const nodeNsUri = node.namespaceURI || node.namespaceUri || '';\r\n return nodeLocalName === localName && nodeNsUri === nsUri;\r\n }\r\n\r\n const nodeLocalName = node.localName || this.extractLocalName(node.nodeName);\r\n return nodeLocalName === testName;\r\n };\r\n\r\n switch (test.type) {\r\n case 'wildcard':\r\n // Check if it's a namespaced wildcard like \"ns:*\"\r\n if (test.name && test.name.endsWith(':*')) {\r\n const prefix = test.name.slice(0, -2);\r\n const nsUri = context?.namespaces?.[prefix];\r\n if (!nsUri) return false; // Unknown prefix - no match\r\n\r\n const nodeNsUri = node.namespaceURI || node.namespaceUri || '';\r\n return (\r\n (nodeType === 1 || nodeType === 2 || nodeType === 13) && nodeNsUri === nsUri\r\n );\r\n }\r\n // Regular wildcard - matches any element (nodeType 1), attribute (nodeType 2), or namespace node (nodeType 13)\r\n return nodeType === 1 || nodeType === 2 || nodeType === 13;\r\n\r\n case 'name':\r\n return matchesQName(test.name!, [1, 2, 13]);\r\n\r\n case 'element':\r\n if (nodeType !== 1) return false;\r\n if (!test.name || test.isWildcardName) return true; // type constraints ignored at runtime\r\n return matchesQName(test.name, [1]);\r\n\r\n case 'attribute':\r\n if (nodeType !== 2) return false;\r\n if (!test.name || test.isWildcardName) return true; // type constraints ignored at runtime\r\n return matchesQName(test.name, [2]);\r\n\r\n case 'schema-element':\r\n return matchesQName(test.name!, [1]);\r\n\r\n case 'schema-attribute':\r\n return matchesQName(test.name!, [2]);\r\n\r\n case 'document-node':\r\n if (nodeType !== 9) return false;\r\n if (!test.elementTest) return true;\r\n\r\n const root =\r\n node.documentElement ||\r\n Array.from(node.childNodes || []).find((n: any) => n.nodeType === 1);\r\n if (!root) return false;\r\n\r\n return this.matchesNodeTest(root, context, test.elementTest);\r\n\r\n case 'node-type':\r\n switch (test.nodeType) {\r\n case 'node':\r\n return true; // matches any node\r\n case 'text':\r\n return nodeType === 3; // text node\r\n case 'comment':\r\n return nodeType === 8; // comment node\r\n case 'processing-instruction':\r\n return nodeType === 7; // processing instruction\r\n default:\r\n return false;\r\n }\r\n\r\n case 'processing-instruction':\r\n if (nodeType !== 7) return false;\r\n if (test.target) {\r\n return (node.target ?? node.nodeName) === test.target;\r\n }\r\n return true;\r\n\r\n default:\r\n return false;\r\n }\r\n }\r\n\r\n private applyPredicates(nodes: any[], context: any): any[] {\r\n let result = nodes;\r\n\r\n for (const predicate of this.predicates) {\r\n const filtered: any[] = [];\r\n const size = result.length;\r\n\r\n for (let i = 0; i < result.length; i++) {\r\n const predicateContext = {\r\n ...context,\r\n node: result[i],\r\n position: i + 1,\r\n size: size,\r\n };\r\n\r\n const predicateResult = predicate.evaluate(predicateContext);\r\n\r\n // If predicate result is a number, it's a position test\r\n if (typeof predicateResult === 'number') {\r\n if (predicateResult === i + 1) {\r\n filtered.push(result[i]);\r\n }\r\n } else if (this.toBoolean(predicateResult)) {\r\n filtered.push(result[i]);\r\n }\r\n }\r\n\r\n result = filtered;\r\n }\r\n\r\n return result;\r\n }\r\n\r\n private toBoolean(value: any): boolean {\r\n if (typeof value === 'boolean') return value;\r\n if (typeof value === 'number') return value !== 0 && !isNaN(value);\r\n if (typeof value === 'string') return value.length > 0;\r\n if (Array.isArray(value)) return value.length > 0;\r\n return !!value;\r\n }\r\n\r\n /**\r\n * Extract the local name from a qualified name (e.g., \"ns:name\" -> \"name\", \"name\" -> \"name\")\r\n */\r\n private extractLocalName(qname: string): string {\r\n if (!qname) return '';\r\n const colonIndex = qname.indexOf(':');\r\n if (colonIndex > 0) {\r\n return qname.substring(colonIndex + 1);\r\n }\r\n return qname;\r\n }\r\n}\r\n","import { XPathExpression } from './expression';\r\nimport { XPathStep } from './step-expression';\r\n\r\nexport class XPathLocationPath extends XPathExpression {\r\n steps: XPathStep[];\r\n absolute: boolean;\r\n\r\n constructor(steps: XPathStep[], absolute: boolean = false) {\r\n super();\r\n this.steps = steps;\r\n this.absolute = absolute;\r\n }\r\n\r\n evaluate(context: any): any[] {\r\n let nodes: any[];\r\n\r\n if (this.absolute) {\r\n // Start from document root\r\n const root = this.getDocumentRoot(context?.node);\r\n nodes = root ? [root] : [];\r\n } else {\r\n // Start from context node or context item (XPath 3.0)\r\n if (context?.node) {\r\n nodes = [context.node];\r\n } else if (context?.contextItem !== undefined) {\r\n // XPath 3.0: atomic context item - only valid for self axis (.)\r\n // For location paths starting with '.', the first step will handle atomic items\r\n // We use a special marker to indicate we're starting with an atomic context\r\n nodes = [{ __atomicContextItem: context.contextItem }];\r\n } else {\r\n nodes = [];\r\n }\r\n }\r\n\r\n // Apply each step\r\n for (const step of this.steps) {\r\n const nextNodes: any[] = [];\r\n\r\n for (const node of nodes) {\r\n // Handle atomic context item marker\r\n if (node && node.__atomicContextItem !== undefined) {\r\n // Pass the atomic item through the step context\r\n const stepContext = { ...context, contextItem: node.__atomicContextItem };\r\n const result = step.evaluate(stepContext);\r\n nextNodes.push(...result);\r\n } else {\r\n const stepContext = { ...context, node };\r\n const result = step.evaluate(stepContext);\r\n nextNodes.push(...result);\r\n }\r\n }\r\n\r\n // Remove duplicates while preserving document order\r\n nodes = this.uniqueNodes(nextNodes);\r\n }\r\n\r\n return nodes;\r\n }\r\n\r\n private getDocumentRoot(node: any): any {\r\n if (!node) return null;\r\n\r\n let root = node;\r\n while (root.parentNode) {\r\n root = root.parentNode;\r\n }\r\n\r\n // Return the document node itself (not the document element)\r\n // In XPath, \"/\" represents the document node, and \"/test\" selects\r\n // children of the document node named \"test\"\r\n return root;\r\n }\r\n\r\n private uniqueNodes(nodes: any[]): any[] {\r\n const seen = new Set();\r\n const result: any[] = [];\r\n\r\n for (const node of nodes) {\r\n if (!seen.has(node)) {\r\n seen.add(node);\r\n result.push(node);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n}\r\n","import { XPathExpression } from './expression';\r\nimport { XPathContext } from '../context';\r\nimport { XPathPredicate } from './predicate-expression';\r\n\r\n/**\r\n * Represents a filter expression in XPath 2.0.\r\n *\r\n * A filter expression is a primary expression followed by one or more predicates.\r\n * The predicates are evaluated against each item in the result of the primary expression.\r\n *\r\n * Syntax: PrimaryExpr Predicate*\r\n * Examples:\r\n * - (1 to 10)[. > 5] Filter with boolean predicate\r\n * - (1, 2, 3)[2] Filter with numeric predicate (position)\r\n * - (1 to 10)[position() mod 2 = 0] Filter with position-based predicate\r\n */\r\nexport class XPathFilterExpression extends XPathExpression {\r\n /**\r\n * The primary expression to be filtered.\r\n */\r\n expression: XPathExpression;\r\n\r\n /**\r\n * The list of predicates to apply to the expression result.\r\n */\r\n predicates: XPathExpression[];\r\n\r\n constructor(expression: XPathExpression, predicates: XPathExpression[]) {\r\n super();\r\n this.expression = expression;\r\n this.predicates = predicates || [];\r\n }\r\n\r\n /**\r\n * Evaluate the filter expression.\r\n *\r\n * Steps:\r\n * 1. Evaluate the primary expression to get a sequence\r\n * 2. For each predicate:\r\n * a. Set position/size in context\r\n * b. Evaluate predicate for each item\r\n * c. Keep items where predicate test succeeds\r\n * 3. Return the filtered result\r\n *\r\n * @param context The evaluation context\r\n * @returns The filtered sequence\r\n */\r\n evaluate(context: XPathContext): any[] {\r\n // Step 1: Evaluate the primary expression\r\n let result = this.expression.evaluate(context);\r\n\r\n // Ensure result is an array\r\n if (!Array.isArray(result)) {\r\n result = result === undefined || result === null ? [] : [result];\r\n }\r\n\r\n // Step 2: Apply each predicate to filter the result\r\n for (const predicateExpr of this.predicates) {\r\n result = this.applyPredicate(result, predicateExpr, context);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Apply a single predicate to filter the result sequence.\r\n *\r\n * For each item in the sequence:\r\n * - Set position and size in context\r\n * - Evaluate the predicate\r\n * - Test if the predicate matches\r\n * - Keep the item if it matches\r\n *\r\n * @param items The sequence to filter\r\n * @param predicateExpr The predicate expression\r\n * @param context The evaluation context\r\n * @returns The filtered sequence\r\n */\r\n private applyPredicate(\r\n items: any[],\r\n predicateExpr: XPathExpression,\r\n context: XPathContext\r\n ): any[] {\r\n const result: any[] = [];\r\n\r\n // Iterate through each item with position and size\r\n for (let i = 0; i < items.length; i++) {\r\n const item = items[i];\r\n const itemContext: XPathContext = {\r\n ...context,\r\n node: item?.nodeType !== undefined ? item : context.node,\r\n position: i + 1, // XPath uses 1-based indexing\r\n size: items.length,\r\n };\r\n\r\n // Evaluate the predicate for this item\r\n if (this.testPredicate(predicateExpr, itemContext)) {\r\n result.push(item);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Test if a predicate expression matches in the given context.\r\n *\r\n * A predicate matches if:\r\n * - It evaluates to a number equal to the context position (numeric predicate)\r\n * - It evaluates to true (boolean predicate)\r\n *\r\n * @param predicateExpr The predicate expression\r\n * @param context The evaluation context with position/size\r\n * @returns True if the predicate matches\r\n */\r\n private testPredicate(predicateExpr: XPathExpression, context: XPathContext): boolean {\r\n const result = predicateExpr.evaluate(context);\r\n\r\n // Numeric predicate: test if number equals context position\r\n if (typeof result === 'number') {\r\n return result === context.position;\r\n }\r\n\r\n // Boolean predicate: convert to boolean using XPath rules\r\n return this.toBoolean(result);\r\n }\r\n\r\n /**\r\n * Convert a value to boolean using XPath rules.\r\n *\r\n * XPath boolean conversion rules:\r\n * - boolean: use as-is\r\n * - number: 0 or NaN is false, otherwise true\r\n * - string: empty string is false, non-empty is true\r\n * - array/sequence: non-empty is true, empty is false\r\n * - object/node: true\r\n * - null/undefined: false\r\n *\r\n * @param value The value to convert\r\n * @returns The boolean result\r\n */\r\n private toBoolean(value: any): boolean {\r\n if (typeof value === 'boolean') {\r\n return value;\r\n }\r\n if (typeof value === 'number') {\r\n return value !== 0 && !isNaN(value);\r\n }\r\n if (typeof value === 'string') {\r\n return value.length > 0;\r\n }\r\n if (Array.isArray(value)) {\r\n return value.length > 0;\r\n }\r\n if (value === null || value === undefined) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n}\r\n\r\n/**\r\n * Helper class for combining a filter expression with a subsequent location path.\r\n *\r\n * This represents expressions like: (primary-expr)[predicates]/steps\r\n * The filter expression is evaluated first, then the location path is applied to each result.\r\n *\r\n * @internal\r\n */\r\nexport class FilteredPathExpression extends XPathExpression {\r\n /**\r\n * The filter expression to evaluate first.\r\n */\r\n filterExpr: XPathExpression;\r\n\r\n /**\r\n * The location path to apply to the filter results.\r\n */\r\n pathExpr: XPathExpression;\r\n\r\n constructor(filterExpr: XPathExpression, pathExpr: XPathExpression) {\r\n super();\r\n this.filterExpr = filterExpr;\r\n this.pathExpr = pathExpr;\r\n }\r\n\r\n /**\r\n * Evaluate by first evaluating the filter expression,\r\n * then applying the path expression to each result.\r\n *\r\n * @param context The evaluation context\r\n * @returns The combined result\r\n */\r\n evaluate(context: XPathContext): any[] {\r\n // Step 1: Evaluate the filter expression to get initial items\r\n const items = this.filterExpr.evaluate(context);\r\n\r\n if (!Array.isArray(items)) {\r\n return [];\r\n }\r\n\r\n // Step 2: Apply the path expression to each item\r\n const result: any[] = [];\r\n\r\n for (const item of items) {\r\n const itemContext: XPathContext = {\r\n ...context,\r\n node: item?.nodeType !== undefined ? item : context.node,\r\n };\r\n\r\n const pathResult = this.pathExpr.evaluate(itemContext);\r\n if (Array.isArray(pathResult)) {\r\n result.push(...pathResult);\r\n } else if (pathResult !== undefined && pathResult !== null) {\r\n result.push(pathResult);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n}\r\n","/**\r\n * XPath 2.0 Unary Expressions (Section 3.4)\r\n * https://www.w3.org/TR/xpath20/#id-arithmetic\r\n *\r\n * Unary arithmetic operators:\r\n * - `+expr` - converts operand to number (identity)\r\n * - `-expr` - numeric negation\r\n *\r\n * Type promotion rules:\r\n * - Operand is atomized\r\n * - Atomic value is promoted to numeric type\r\n * - Empty sequence returns empty sequence\r\n */\r\n\r\nimport { XPathContext } from '../context';\r\nimport { XPathExpression } from './expression';\r\n\r\n/**\r\n * UnaryExpression - Unary plus and minus operations\r\n *\r\n * Syntax:\r\n * +expr // unary plus (converts to number)\r\n * -expr // unary negation\r\n *\r\n * Examples:\r\n * +5 → 5\r\n * +\"5\" → 5\r\n * -10 → -10\r\n * -\"5\" → -5\r\n * +() → () (empty sequence)\r\n */\r\nexport class XPathUnaryExpression extends XPathExpression {\r\n operator: '+' | '-';\r\n operand: XPathExpression;\r\n\r\n constructor(operator: '+' | '-', operand: XPathExpression) {\r\n super();\r\n this.operator = operator;\r\n this.operand = operand;\r\n }\r\n\r\n evaluate(context: XPathContext): number | null {\r\n const value = this.operand.evaluate(context);\r\n\r\n // Atomize operand\r\n const atomic = this.atomize(value);\r\n\r\n // Empty sequence returns empty sequence\r\n if (atomic === null) {\r\n return null;\r\n }\r\n\r\n // Convert to number\r\n const num = this.toNumber(atomic);\r\n\r\n // Apply operator\r\n if (this.operator === '+') {\r\n return num;\r\n } else {\r\n return -num;\r\n }\r\n }\r\n\r\n /**\r\n * Atomize value - extract atomic values from sequences\r\n */\r\n private atomize(value: any): any {\r\n if (value === null || value === undefined) {\r\n return null;\r\n }\r\n\r\n // Single atomic value\r\n if (!Array.isArray(value)) {\r\n return value;\r\n }\r\n\r\n // Array (sequence)\r\n if (value.length === 0) {\r\n return null; // Empty sequence\r\n }\r\n\r\n // Multiple items - use first\r\n return value[0];\r\n }\r\n\r\n /**\r\n * Convert atomic value to number following XPath 2.0 rules\r\n */\r\n private toNumber(value: any): number {\r\n if (typeof value === 'number') return value;\r\n if (typeof value === 'boolean') return value ? 1 : 0;\r\n if (typeof value === 'string') {\r\n const trimmed = value.trim();\r\n if (trimmed === '') return NaN;\r\n const num = Number(trimmed);\r\n return num;\r\n }\r\n // For other types, try generic conversion\r\n return Number(value);\r\n }\r\n\r\n toString(): string {\r\n return `${this.operator}${this.operand.toString()}`;\r\n }\r\n}\r\n","import { XPathContext } from '../context';\r\nimport { XPathExpression } from './expression';\r\n\r\nexport class XPathBinaryExpression extends XPathExpression {\r\n left: XPathExpression;\r\n right: XPathExpression;\r\n operator: string;\r\n\r\n constructor(left: XPathExpression, right: XPathExpression, operator: string) {\r\n super();\r\n this.left = left;\r\n this.right = right;\r\n this.operator = operator;\r\n }\r\n\r\n evaluate(context: XPathContext): boolean {\r\n const leftValue = this.left.evaluate(context);\r\n const rightValue = this.right.evaluate(context);\r\n\r\n return this.compare(leftValue, rightValue, this.operator);\r\n }\r\n\r\n /**\r\n * XPath comparison rules:\r\n * - If both are node-sets: compare each node in left with each node in right\r\n * - If one is node-set and other is string: convert node-set to strings and compare\r\n * - If one is node-set and other is number: convert node-set to numbers and compare\r\n * - If one is node-set and other is boolean: convert node-set to boolean and compare\r\n * - Otherwise, convert both to numbers for numeric comparison, or strings for equality\r\n */\r\n private compare(left: any, right: any, operator: string): boolean {\r\n const leftIsNodeSet = Array.isArray(left);\r\n const rightIsNodeSet = Array.isArray(right);\r\n\r\n // Both are node-sets\r\n if (leftIsNodeSet && rightIsNodeSet) {\r\n return this.compareNodeSets(left, right, operator);\r\n }\r\n\r\n // Left is node-set\r\n if (leftIsNodeSet) {\r\n return this.compareNodeSetToValue(left, right, operator);\r\n }\r\n\r\n // Right is node-set\r\n if (rightIsNodeSet) {\r\n return this.compareValueToNodeSet(left, right, operator);\r\n }\r\n\r\n // Neither is a node-set\r\n return this.comparePrimitives(left, right, operator);\r\n }\r\n\r\n private compareNodeSets(left: any[], right: any[], operator: string): boolean {\r\n // For each node in left, compare with each node in right\r\n for (const leftNode of left) {\r\n const leftStr = this.getStringValue(leftNode);\r\n for (const rightNode of right) {\r\n const rightStr = this.getStringValue(rightNode);\r\n if (this.comparePrimitives(leftStr, rightStr, operator)) {\r\n return true;\r\n }\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n private compareNodeSetToValue(nodeSet: any[], value: any, operator: string): boolean {\r\n // Compare each node in the set to the value\r\n for (const node of nodeSet) {\r\n const nodeValue =\r\n typeof value === 'number'\r\n ? Number(this.getStringValue(node))\r\n : this.getStringValue(node);\r\n if (this.comparePrimitives(nodeValue, value, operator)) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n private compareValueToNodeSet(value: any, nodeSet: any[], operator: string): boolean {\r\n // Compare value to each node in the set\r\n for (const node of nodeSet) {\r\n const nodeValue =\r\n typeof value === 'number'\r\n ? Number(this.getStringValue(node))\r\n : this.getStringValue(node);\r\n if (this.comparePrimitives(value, nodeValue, operator)) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n private comparePrimitives(left: any, right: any, operator: string): boolean {\r\n // For equality operators, compare as-is (after node-set conversion)\r\n // For relational operators, convert to numbers\r\n switch (operator) {\r\n case '=':\r\n return left == right; // Use loose equality for type coercion\r\n case '!=':\r\n return left != right;\r\n case '<':\r\n return Number(left) < Number(right);\r\n case '>':\r\n return Number(left) > Number(right);\r\n case '<=':\r\n return Number(left) <= Number(right);\r\n case '>=':\r\n return Number(left) >= Number(right);\r\n default:\r\n throw new Error(`Unknown operator: ${operator}`);\r\n }\r\n }\r\n\r\n private getStringValue(node: any): string {\r\n if (!node) return '';\r\n\r\n // Text node or attribute\r\n if (node.nodeType === 3 || node.nodeType === 2) {\r\n return node.nodeValue || node.textContent || '';\r\n }\r\n\r\n // Element node - get text content\r\n if (node.textContent !== undefined) {\r\n return node.textContent;\r\n }\r\n\r\n // Fallback: recursively get text content\r\n if (node.childNodes) {\r\n let text = '';\r\n for (const child of Array.from(node.childNodes as ArrayLike<any>)) {\r\n if (child.nodeType === 3) {\r\n text += child.nodeValue || '';\r\n } else if (child.nodeType === 1) {\r\n text += this.getStringValue(child);\r\n }\r\n }\r\n return text;\r\n }\r\n\r\n return String(node);\r\n }\r\n}\r\n","/**\r\n * XPath 2.0 Arithmetic Expressions (Section 3.4)\r\n * https://www.w3.org/TR/xpath20/#id-arithmetic\r\n *\r\n * Arithmetic operators work on numeric values:\r\n * 1. Binary operators: `+`, `-`, `*`, `div`, `idiv`, `mod`\r\n * 2. Unary operators: `+expr`, `-expr`\r\n *\r\n * Type promotion rules:\r\n * - Operands are atomized\r\n * - Atomic values are promoted to numeric types\r\n * - If operand is empty sequence, result is empty sequence (in 2.0 mode)\r\n * - In XPath 1.0 mode, empty sequence converts to NaN, then double\r\n *\r\n * Division by zero:\r\n * - `div` returns INF or -INF\r\n * - `idiv` raises XPDY0002 error\r\n * - `mod` by 0 raises XPDY0002 error\r\n */\r\n\r\nimport { XPathContext } from '../context';\r\nimport { XPathExpression } from './expression';\r\n\r\nexport type ArithmeticOperator = '+' | '-' | '*' | 'div' | 'idiv' | 'mod';\r\n\r\n/**\r\n * ArithmeticExpression - Binary arithmetic operations\r\n *\r\n * Syntax:\r\n * expr1 + expr2 // addition\r\n * expr1 - expr2 // subtraction\r\n * expr1 * expr2 // multiplication\r\n * expr1 div expr2 // division\r\n * expr1 idiv expr2 // integer division\r\n * expr1 mod expr2 // modulo\r\n *\r\n * Examples:\r\n * 5 + 3 → 8\r\n * 10 div 3 → 3.3333...\r\n * 10 idiv 3 → 3\r\n * 10 mod 3 → 1\r\n * \"5\" + 3 → 8 (string promoted to number)\r\n * () + 5 → () (empty sequence in XPath 2.0)\r\n */\r\nexport class XPathArithmeticExpression extends XPathExpression {\r\n left: XPathExpression;\r\n right: XPathExpression;\r\n operator: ArithmeticOperator;\r\n\r\n constructor(left: XPathExpression, right: XPathExpression, operator: ArithmeticOperator) {\r\n super();\r\n this.left = left;\r\n this.right = right;\r\n this.operator = operator;\r\n }\r\n\r\n evaluate(context: XPathContext): number | null {\r\n // Evaluate both operands\r\n const leftValue = this.left.evaluate(context);\r\n const rightValue = this.right.evaluate(context);\r\n\r\n // Atomize operands (extract atomic values from sequences)\r\n const leftAtomic = this.atomize(leftValue);\r\n const rightAtomic = this.atomize(rightValue);\r\n\r\n // In XPath 2.0, empty sequence returns empty sequence (null)\r\n if (leftAtomic === null || rightAtomic === null) {\r\n return null;\r\n }\r\n\r\n // Convert to numbers\r\n const leftNum = this.toNumber(leftAtomic);\r\n const rightNum = this.toNumber(rightAtomic);\r\n\r\n // Perform operation\r\n switch (this.operator) {\r\n case '+':\r\n return leftNum + rightNum;\r\n case '-':\r\n return leftNum - rightNum;\r\n case '*':\r\n return leftNum * rightNum;\r\n case 'div':\r\n return leftNum / rightNum; // Allows Infinity\r\n case 'idiv':\r\n if (rightNum === 0) {\r\n throw new Error('XPDY0002: Integer division by zero');\r\n }\r\n return Math.trunc(leftNum / rightNum);\r\n case 'mod':\r\n if (rightNum === 0) {\r\n throw new Error('XPDY0002: Modulo by zero');\r\n }\r\n // XPath mod: a mod b = a - (a idiv b) * b\r\n return leftNum - Math.trunc(leftNum / rightNum) * rightNum;\r\n default:\r\n throw new Error(`Unknown arithmetic operator: ${this.operator}`);\r\n }\r\n }\r\n\r\n /**\r\n * Atomize value - extract atomic values from sequences\r\n * Returns first atomic value or null for empty sequence\r\n */\r\n private atomize(value: any): any {\r\n if (value === null || value === undefined) {\r\n return null;\r\n }\r\n\r\n // Handle NodeValue objects from XSLT context (StringValue, NumberValue, etc.)\r\n if (typeof value === 'object' && 'numberValue' in value && typeof value.numberValue === 'function') {\r\n return value.numberValue();\r\n }\r\n\r\n // Single atomic value\r\n if (!Array.isArray(value)) {\r\n return value;\r\n }\r\n\r\n // Array (sequence)\r\n if (value.length === 0) {\r\n return null; // Empty sequence\r\n }\r\n\r\n // Multiple items - use first (recursive to handle nested NodeValue)\r\n return this.atomize(value[0]);\r\n }\r\n\r\n /**\r\n * Convert atomic value to number following XPath 2.0 rules\r\n */\r\n private toNumber(value: any): number {\r\n if (typeof value === 'number') return value;\r\n if (typeof value === 'boolean') return value ? 1 : 0;\r\n if (typeof value === 'string') {\r\n const trimmed = value.trim();\r\n if (trimmed === '') return NaN;\r\n const num = Number(trimmed);\r\n return num;\r\n }\r\n // For other types, try generic conversion\r\n return Number(value);\r\n }\r\n\r\n toString(): string {\r\n return `${this.left.toString()} ${this.operator} ${this.right.toString()}`;\r\n }\r\n}\r\n","import { XPathContext, XPathResult } from '../context';\r\nimport { XPathExpression } from './expression';\r\n\r\nexport class XPathLogicalExpression extends XPathExpression {\r\n left: XPathExpression;\r\n right: XPathExpression;\r\n operator: 'and' | 'or';\r\n\r\n constructor(left: XPathExpression, right: XPathExpression, operator: 'and' | 'or') {\r\n super();\r\n this.left = left;\r\n this.right = right;\r\n this.operator = operator;\r\n }\r\n\r\n // Effective Boolean Value (EBV) per XPath 2.0 rules (simplified)\r\n private toBoolean(value: XPathResult): boolean {\r\n // Empty sequence -> false\r\n if (value === null || value === undefined) {\r\n return false;\r\n }\r\n\r\n // Boolean stays as is\r\n if (typeof value === 'boolean') {\r\n return value;\r\n }\r\n\r\n // Sequence handling\r\n if (Array.isArray(value)) {\r\n if (value.length === 0) return false;\r\n if (value.length === 1) return this.toBoolean(value[0] as XPathResult);\r\n // Multiple items: treat non-empty sequence as true (node-sequence case)\r\n return true;\r\n }\r\n\r\n // Number: false if 0 or NaN\r\n if (typeof value === 'number') {\r\n return value !== 0 && !isNaN(value);\r\n }\r\n\r\n // String: true if non-empty\r\n if (typeof value === 'string') {\r\n return value.length > 0;\r\n }\r\n\r\n // Fallback for maps/functions/other values\r\n return !!value;\r\n }\r\n\r\n evaluate(context: XPathContext): boolean {\r\n const leftValue = this.toBoolean(this.left.evaluate(context));\r\n\r\n // Short-circuit evaluation\r\n if (this.operator === 'and') {\r\n if (!leftValue) return false;\r\n return this.toBoolean(this.right.evaluate(context));\r\n }\r\n\r\n if (this.operator === 'or') {\r\n if (leftValue) return true;\r\n return this.toBoolean(this.right.evaluate(context));\r\n }\r\n\r\n throw new Error(`Unknown logical operator: ${this.operator}`);\r\n }\r\n}\r\n","import { XPathContext, XPathResult } from '../context';\r\nimport { XPathExpression } from './expression';\r\n\r\nexport class XPathConditionalExpression extends XPathExpression {\r\n test: XPathExpression;\r\n thenExpr: XPathExpression;\r\n elseExpr: XPathExpression;\r\n\r\n constructor(test: XPathExpression, thenExpr: XPathExpression, elseExpr: XPathExpression) {\r\n super();\r\n this.test = test;\r\n this.thenExpr = thenExpr;\r\n this.elseExpr = elseExpr;\r\n }\r\n\r\n // Effective Boolean Value (EBV) per XPath 2.0 rules (simplified)\r\n private toBoolean(value: XPathResult): boolean {\r\n if (value === null || value === undefined) return false;\r\n\r\n if (typeof value === 'boolean') return value;\r\n\r\n if (Array.isArray(value)) {\r\n if (value.length === 0) return false;\r\n if (value.length === 1) return this.toBoolean(value[0] as XPathResult);\r\n return true;\r\n }\r\n\r\n if (typeof value === 'number') return value !== 0 && !isNaN(value);\r\n if (typeof value === 'string') return value.length > 0;\r\n\r\n return !!value;\r\n }\r\n\r\n evaluate(context: XPathContext): XPathResult {\r\n const testValue = this.toBoolean(this.test.evaluate(context));\r\n if (testValue) {\r\n return this.thenExpr.evaluate(context);\r\n }\r\n return this.elseExpr.evaluate(context);\r\n }\r\n}\r\n","/**\r\n * XPath 2.0 For Expression (Section 3.7)\r\n * Supports one or more variable bindings with sequential expansion.\r\n */\r\nimport { XPathContext, XPathResult } from '../context';\r\nimport { XPathExpression } from './expression';\r\n\r\nexport interface XPathForBinding {\r\n variable: string;\r\n expression: XPathExpression;\r\n}\r\n\r\nexport class XPathForExpression extends XPathExpression {\r\n bindings: XPathForBinding[];\r\n returnExpr: XPathExpression;\r\n\r\n constructor(bindings: XPathForBinding[], returnExpr: XPathExpression) {\r\n super();\r\n this.bindings = bindings;\r\n this.returnExpr = returnExpr;\r\n }\r\n\r\n evaluate(context: XPathContext): XPathResult {\r\n const initialVariables = context.variables ? { ...context.variables } : {};\r\n const initialContext: XPathContext = { ...context, variables: initialVariables };\r\n const results: any[] = [];\r\n\r\n this.evaluateBinding(0, initialContext, results);\r\n return results;\r\n }\r\n\r\n private evaluateBinding(index: number, currentContext: XPathContext, results: any[]): void {\r\n // Base case: evaluate the return expression with accumulated bindings\r\n if (index >= this.bindings.length) {\r\n const value = this.returnExpr.evaluate(currentContext);\r\n this.appendResult(results, value);\r\n return;\r\n }\r\n\r\n const binding = this.bindings[index];\r\n const sequence = this.normalizeSequence(binding.expression.evaluate(currentContext));\r\n const size = sequence.length;\r\n\r\n for (let i = 0; i < size; i++) {\r\n const item = sequence[i];\r\n const variables = { ...(currentContext.variables ?? {}), [binding.variable]: item };\r\n const iterationContext: XPathContext = {\r\n ...currentContext,\r\n variables,\r\n node: this.resolveNode(item, currentContext),\r\n position: i + 1,\r\n size,\r\n };\r\n\r\n this.evaluateBinding(index + 1, iterationContext, results);\r\n }\r\n }\r\n\r\n private normalizeSequence(value: XPathResult): any[] {\r\n if (value === null || value === undefined) {\r\n return [];\r\n }\r\n if (Array.isArray(value)) {\r\n return value;\r\n }\r\n return [value];\r\n }\r\n\r\n private appendResult(results: any[], value: XPathResult): void {\r\n if (value === null || value === undefined) {\r\n return;\r\n }\r\n if (Array.isArray(value)) {\r\n results.push(...value);\r\n return;\r\n }\r\n results.push(value);\r\n }\r\n\r\n private resolveNode(item: any, context: XPathContext) {\r\n if (item && typeof item === 'object' && 'nodeType' in item) {\r\n return item;\r\n }\r\n return context.node;\r\n }\r\n}\r\n","/**\r\n * XPath 2.0 Quantified Expressions (Section 3.9)\r\n * Implements `some` (existential) and `every` (universal) quantifiers with one or more bindings.\r\n */\r\nimport { XPathContext, XPathResult } from '../context';\r\nimport { XPathExpression } from './expression';\r\n\r\nexport interface XPathQuantifiedBinding {\r\n variable: string;\r\n expression: XPathExpression;\r\n}\r\n\r\nexport type Quantifier = 'some' | 'every';\r\n\r\nexport class XPathQuantifiedExpression extends XPathExpression {\r\n quantifier: Quantifier;\r\n bindings: XPathQuantifiedBinding[];\r\n satisfiesExpr: XPathExpression;\r\n\r\n constructor(\r\n quantifier: Quantifier,\r\n bindings: XPathQuantifiedBinding[],\r\n satisfiesExpr: XPathExpression\r\n ) {\r\n super();\r\n this.quantifier = quantifier;\r\n this.bindings = bindings;\r\n this.satisfiesExpr = satisfiesExpr;\r\n }\r\n\r\n evaluate(context: XPathContext): XPathResult {\r\n const initialVariables = context.variables ? { ...context.variables } : {};\r\n const initialContext: XPathContext = { ...context, variables: initialVariables };\r\n\r\n if (this.quantifier === 'some') {\r\n return this.evaluateSome(0, initialContext);\r\n }\r\n return this.evaluateEvery(0, initialContext);\r\n }\r\n\r\n private evaluateSome(index: number, currentContext: XPathContext): boolean {\r\n if (index >= this.bindings.length) {\r\n return this.toBoolean(this.satisfiesExpr.evaluate(currentContext));\r\n }\r\n\r\n const binding = this.bindings[index];\r\n const sequence = this.normalizeSequence(binding.expression.evaluate(currentContext));\r\n\r\n for (let i = 0; i < sequence.length; i++) {\r\n const item = sequence[i];\r\n const variables = { ...(currentContext.variables ?? {}), [binding.variable]: item };\r\n const iterationContext: XPathContext = {\r\n ...currentContext,\r\n variables,\r\n node: this.resolveNode(item, currentContext),\r\n position: i + 1,\r\n size: sequence.length,\r\n };\r\n\r\n if (this.evaluateSome(index + 1, iterationContext)) {\r\n return true; // short-circuit on first match\r\n }\r\n }\r\n\r\n return false; // no binding satisfied predicate\r\n }\r\n\r\n private evaluateEvery(index: number, currentContext: XPathContext): boolean {\r\n if (index >= this.bindings.length) {\r\n return this.toBoolean(this.satisfiesExpr.evaluate(currentContext));\r\n }\r\n\r\n const binding = this.bindings[index];\r\n const sequence = this.normalizeSequence(binding.expression.evaluate(currentContext));\r\n\r\n // Vacuous truth: empty sequence means this binding imposes no constraint\r\n if (sequence.length === 0) {\r\n return true;\r\n }\r\n\r\n for (let i = 0; i < sequence.length; i++) {\r\n const item = sequence[i];\r\n const variables = { ...(currentContext.variables ?? {}), [binding.variable]: item };\r\n const iterationContext: XPathContext = {\r\n ...currentContext,\r\n variables,\r\n node: this.resolveNode(item, currentContext),\r\n position: i + 1,\r\n size: sequence.length,\r\n };\r\n\r\n if (!this.evaluateEvery(index + 1, iterationContext)) {\r\n return false; // short-circuit on first failure\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private normalizeSequence(value: XPathResult): any[] {\r\n if (value === null || value === undefined) {\r\n return [];\r\n }\r\n if (Array.isArray(value)) {\r\n return value;\r\n }\r\n return [value];\r\n }\r\n\r\n private resolveNode(item: any, context: XPathContext) {\r\n if (item && typeof item === 'object' && 'nodeType' in item) {\r\n return item;\r\n }\r\n return context.node;\r\n }\r\n\r\n // Boolean conversion aligning with XPath EBV rules (simplified for current types)\r\n private toBoolean(value: XPathResult): boolean {\r\n if (value === null || value === undefined) return false;\r\n if (typeof value === 'boolean') return value;\r\n if (typeof value === 'number') return value !== 0 && !isNaN(value);\r\n if (typeof value === 'string') return value.length > 0;\r\n if (Array.isArray(value)) return value.length > 0;\r\n return !!value;\r\n }\r\n}\r\n","/**\r\n * Base types and interfaces for XPath 2.0 Atomic Types\r\n * Based on XML Schema Part 2: Datatypes and XPath 2.0 Section 2.5.1\r\n */\r\n\r\nimport { XS_NAMESPACE } from '../constants';\r\n\r\n/**\r\n * Base interface for all atomic types\r\n */\r\nexport interface AtomicType {\r\n readonly name: string;\r\n readonly namespace: string;\r\n readonly baseType?: AtomicType;\r\n readonly primitive?: AtomicType;\r\n validate(value: any): boolean;\r\n cast(value: any): any;\r\n}\r\n\r\n// Re-export constant from unified constants.ts\r\nexport { XS_NAMESPACE };\r\n\r\n/**\r\n * Creates a qualified type name for an XS type\r\n */\r\nexport function xsType(localName: string): string {\r\n return `{${XS_NAMESPACE}}${localName}`;\r\n}\r\n\r\n/**\r\n * Abstract base implementation for atomic types\r\n */\r\nexport abstract class AtomicTypeImpl implements AtomicType {\r\n constructor(\r\n public readonly name: string,\r\n public readonly namespace: string = XS_NAMESPACE,\r\n public readonly baseType?: AtomicType,\r\n public readonly primitive?: AtomicType\r\n ) {}\r\n\r\n abstract validate(value: any): boolean;\r\n abstract cast(value: any): any;\r\n\r\n get qualifiedName(): string {\r\n return `{${this.namespace}}${this.name}`;\r\n }\r\n}\r\n","/**\r\n * XPath 2.0 SequenceType System (Section 2.5.3)\r\n *\r\n * A SequenceType specifies:\r\n * 1. ItemType - what kinds of items are allowed\r\n * 2. OccurrenceIndicator - how many items are expected\r\n *\r\n * Syntax: ItemType OccurrenceIndicator?\r\n * Examples:\r\n * - item() ? - zero or one item\r\n * - xs:integer * - zero or more integers\r\n * - element(name) + - one or more elements with local name \"name\"\r\n * - attribute(*, xs:ID) - attribute with any name and xs:ID type\r\n * - empty-sequence() - no items (special case)\r\n */\r\n\r\nimport { AtomicType } from './base';\r\n\r\n/**\r\n * OccurrenceIndicator specifies cardinality of items in a sequence\r\n */\r\nexport enum OccurrenceIndicator {\r\n /**\r\n * Exactly one item (no indicator)\r\n * Cardinality: exactly 1\r\n */\r\n EXACTLY_ONE = 'ONE',\r\n\r\n /**\r\n * Zero or one item (?)\r\n * Cardinality: 0 or 1\r\n */\r\n ZERO_OR_ONE = '?',\r\n\r\n /**\r\n * Zero or more items (*)\r\n * Cardinality: 0 or more\r\n */\r\n ZERO_OR_MORE = '*',\r\n\r\n /**\r\n * One or more items (+)\r\n * Cardinality: 1 or more\r\n */\r\n ONE_OR_MORE = '+',\r\n}\r\n\r\n/**\r\n * ItemType represents the type of individual items in a sequence\r\n * Can be: atomic types, node types, or item()\r\n */\r\nexport interface ItemType {\r\n /**\r\n * Human-readable name of the item type\r\n */\r\n readonly name: string;\r\n\r\n /**\r\n * Check if a value matches this ItemType\r\n */\r\n matches(value: any): boolean;\r\n\r\n /**\r\n * Get the type's namespace URI (if applicable)\r\n */\r\n readonly namespace?: string;\r\n\r\n /**\r\n * Indicates if this is a wildcard match (matches any item)\r\n */\r\n readonly isWildcard?: boolean;\r\n\r\n /**\r\n * For atomic types, reference to the AtomicType\r\n */\r\n readonly atomicType?: AtomicType;\r\n}\r\n\r\n/**\r\n * KindTest represents tests for specific node kinds\r\n * Used in path expressions and sequence types\r\n */\r\nexport interface KindTest extends ItemType {\r\n /**\r\n * The node kind being tested\r\n * Possible values: 'element', 'attribute', 'text', 'comment', 'processing-instruction', 'document-node'\r\n */\r\n readonly nodeKind: string;\r\n\r\n /**\r\n * Optional name constraint for the node\r\n */\r\n readonly nodeName?: string;\r\n\r\n /**\r\n * Optional type constraint for the node\r\n */\r\n readonly nodeType?: string;\r\n\r\n /**\r\n * Indicates if name is a wildcard (*)\r\n */\r\n readonly isWildcardName?: boolean;\r\n}\r\n\r\n/**\r\n * SequenceType specifies the expected type and cardinality of a sequence\r\n *\r\n * Special cases:\r\n * - empty-sequence() : represents a sequence with no items\r\n * - item() : matches any single item\r\n * - xs:integer+ : one or more integers\r\n */\r\nexport class SequenceType {\r\n private readonly itemType: ItemType | 'empty';\r\n private readonly occurrence: OccurrenceIndicator;\r\n\r\n /**\r\n * Create a SequenceType\r\n *\r\n * @param itemType - The ItemType (or 'empty' for empty-sequence())\r\n * @param occurrence - The occurrence indicator (default: EXACTLY_ONE)\r\n */\r\n constructor(\r\n itemType: ItemType | 'empty',\r\n occurrence: OccurrenceIndicator = OccurrenceIndicator.EXACTLY_ONE\r\n ) {\r\n if (itemType === 'empty' && occurrence !== OccurrenceIndicator.EXACTLY_ONE) {\r\n throw new Error('empty-sequence() must have exactly one occurrence');\r\n }\r\n this.itemType = itemType;\r\n this.occurrence = occurrence;\r\n }\r\n\r\n /**\r\n * Get the ItemType\r\n */\r\n getItemType(): ItemType | 'empty' {\r\n return this.itemType;\r\n }\r\n\r\n /**\r\n * Get the OccurrenceIndicator\r\n */\r\n getOccurrence(): OccurrenceIndicator {\r\n return this.occurrence;\r\n }\r\n\r\n /**\r\n * Check if this is empty-sequence()\r\n */\r\n isEmptySequence(): boolean {\r\n return this.itemType === 'empty';\r\n }\r\n\r\n /**\r\n * Check if this type allows zero items\r\n */\r\n allowsZeroItems(): boolean {\r\n return (\r\n this.isEmptySequence() ||\r\n this.occurrence === OccurrenceIndicator.ZERO_OR_ONE ||\r\n this.occurrence === OccurrenceIndicator.ZERO_OR_MORE\r\n );\r\n }\r\n\r\n /**\r\n * Check if this type allows multiple items\r\n */\r\n allowsMultipleItems(): boolean {\r\n return (\r\n this.occurrence === OccurrenceIndicator.ZERO_OR_MORE ||\r\n this.occurrence === OccurrenceIndicator.ONE_OR_MORE\r\n );\r\n }\r\n\r\n /**\r\n * Check if this type requires at least one item\r\n */\r\n requiresItems(): boolean {\r\n return !this.allowsZeroItems();\r\n }\r\n\r\n /**\r\n * Get a string representation of this SequenceType\r\n * Examples: \"empty-sequence()\", \"xs:integer\", \"xs:integer?\", \"element(*)\"\r\n */\r\n toString(): string {\r\n if (this.isEmptySequence()) {\r\n return 'empty-sequence()';\r\n }\r\n\r\n const typeName = (this.itemType as ItemType).name;\r\n const indicator =\r\n this.occurrence === OccurrenceIndicator.EXACTLY_ONE ? '' : this.occurrence;\r\n\r\n return typeName + indicator;\r\n }\r\n\r\n /**\r\n * Get the minimum cardinality allowed by this type\r\n * 0 = allows empty, 1 = requires at least one item\r\n */\r\n getMinCardinality(): number {\r\n if (this.isEmptySequence() || this.allowsZeroItems()) {\r\n return 0;\r\n }\r\n return 1;\r\n }\r\n\r\n /**\r\n * Get the maximum cardinality allowed by this type\r\n * 1 = exactly one item, Infinity = unbounded\r\n */\r\n getMaxCardinality(): number {\r\n if (this.allowsMultipleItems()) {\r\n return Infinity;\r\n }\r\n return 1;\r\n }\r\n\r\n /**\r\n * Check if another SequenceType is compatible with this one\r\n * (i.e., can values of that type be assigned to this type)\r\n *\r\n * This is a simple compatibility check. Full implementation would require\r\n * schema information and type hierarchy checking.\r\n */\r\n isCompatibleWith(other: SequenceType): boolean {\r\n // Empty sequence is compatible with any type\r\n if (other.isEmptySequence()) {\r\n return this.allowsZeroItems();\r\n }\r\n\r\n // Check cardinality compatibility\r\n const otherMin = other.getMinCardinality();\r\n const otherMax = other.getMaxCardinality();\r\n const thisMin = this.getMinCardinality();\r\n const thisMax = this.getMaxCardinality();\r\n\r\n // Other's cardinality must fit within this type's cardinality\r\n if (otherMin < thisMin || (otherMax > thisMax && thisMax !== Infinity)) {\r\n return false;\r\n }\r\n\r\n // For item types, check if other's item type matches\r\n if (this.itemType !== 'empty' && other.itemType !== 'empty') {\r\n const thisItemType = this.itemType as ItemType;\r\n const otherItemType = other.itemType as ItemType;\r\n\r\n // If this is a wildcard item type, accept any item type\r\n if (thisItemType.isWildcard) {\r\n return true;\r\n }\r\n\r\n // Otherwise, names must match (simplified check)\r\n return thisItemType.name === otherItemType.name;\r\n }\r\n\r\n return this.itemType === 'empty' ? other.isEmptySequence() : true;\r\n }\r\n}\r\n\r\n/**\r\n * Built-in ItemType for \"item()\" - matches any single item\r\n */\r\nexport const ITEM_TYPE: ItemType = {\r\n name: 'item()',\r\n isWildcard: true,\r\n matches: () => true,\r\n};\r\n\r\n/**\r\n * Create a SequenceType for empty-sequence()\r\n */\r\nexport function createEmptySequenceType(): SequenceType {\r\n return new SequenceType('empty', OccurrenceIndicator.EXACTLY_ONE);\r\n}\r\n\r\n/**\r\n * Create a SequenceType for a single item type with specified occurrence\r\n */\r\nexport function createItemSequenceType(\r\n itemType: ItemType,\r\n occurrence: OccurrenceIndicator = OccurrenceIndicator.EXACTLY_ONE\r\n): SequenceType {\r\n return new SequenceType(itemType, occurrence);\r\n}\r\n\r\n/**\r\n * Create a SequenceType from an AtomicType with specified occurrence\r\n */\r\nexport function createAtomicSequenceType(\r\n atomicType: AtomicType,\r\n occurrence: OccurrenceIndicator = OccurrenceIndicator.EXACTLY_ONE\r\n): SequenceType {\r\n const itemType: ItemType = {\r\n name: atomicType.name,\r\n namespace: atomicType.namespace,\r\n atomicType: atomicType,\r\n matches: (value: any) => {\r\n if (value === null || value === undefined) return false;\r\n try {\r\n return atomicType.validate(value);\r\n } catch {\r\n return false;\r\n }\r\n },\r\n };\r\n\r\n return new SequenceType(itemType, occurrence);\r\n}\r\n","/**\r\n * KindTest implementations for XPath 2.0 node tests\r\n * (Section 2.5.3, Section 5.2)\r\n *\r\n * KindTests are used in path expressions to filter nodes by their kind:\r\n * - element() - any element\r\n * - element(QName) - element with specific name\r\n * - element(QName, type) - element with specific name and type\r\n * - attribute() - any attribute\r\n * - document-node() - document node (root)\r\n * - text() - text node\r\n * - comment() - comment node\r\n * - processing-instruction() - processing instruction\r\n * - node() - any node\r\n */\r\n\r\nimport { KindTest, ItemType } from './sequence-type';\r\n\r\n/**\r\n * Base implementation of KindTest\r\n */\r\nabstract class KindTestImpl implements KindTest {\r\n readonly name: string;\r\n readonly nodeKind: string;\r\n readonly nodeName?: string;\r\n readonly nodeType?: string;\r\n readonly isWildcardName?: boolean;\r\n\r\n constructor(\r\n name: string,\r\n nodeKind: string,\r\n nodeName?: string,\r\n nodeType?: string,\r\n isWildcardName?: boolean\r\n ) {\r\n this.name = name;\r\n this.nodeKind = nodeKind;\r\n this.nodeName = nodeName;\r\n this.nodeType = nodeType;\r\n this.isWildcardName = isWildcardName;\r\n }\r\n\r\n matches(value: any): boolean {\r\n // Check if value is a node-like object\r\n if (!value || typeof value !== 'object') {\r\n return false;\r\n }\r\n\r\n // Check node kind\r\n if (value.nodeType !== this.nodeKind) {\r\n return false;\r\n }\r\n\r\n // Check node name if specified\r\n if (this.nodeName && !this.isWildcardName) {\r\n if (value.localName !== this.nodeName && value.nodeName !== this.nodeName) {\r\n return false;\r\n }\r\n }\r\n\r\n // Check node type if specified\r\n if (this.nodeType && value.type !== this.nodeType) {\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n}\r\n\r\n/**\r\n * NodeKindTest: node() - matches any node\r\n */\r\nexport class NodeKindTest extends KindTestImpl {\r\n constructor() {\r\n super('node()', 'node');\r\n }\r\n\r\n matches(): boolean {\r\n return true; // Matches any node\r\n }\r\n}\r\n\r\n/**\r\n * ElementTest: element() or element(name) or element(name, type)\r\n *\r\n * Examples:\r\n * - element() - any element\r\n * - element(book) - element with local name \"book\"\r\n * - element(*, xs:integer) - any element with xs:integer type\r\n * - element(book, xs:date) - element \"book\" with xs:date type\r\n */\r\nexport class ElementTest extends KindTestImpl {\r\n constructor(elementName?: string, elementType?: string) {\r\n const name = elementName\r\n ? elementType\r\n ? `element(${elementName}, ${elementType})`\r\n : `element(${elementName})`\r\n : 'element()';\r\n\r\n super(name, 'element', elementName, elementType, !elementName);\r\n }\r\n}\r\n\r\n/**\r\n * AttributeTest: attribute() or attribute(name) or attribute(name, type)\r\n *\r\n * Examples:\r\n * - attribute() - any attribute\r\n * - attribute(id) - attribute with local name \"id\"\r\n * - attribute(*, xs:IDREF) - any attribute with xs:IDREF type\r\n * - attribute(lang, xs:language) - attribute \"lang\" with xs:language type\r\n */\r\nexport class AttributeTest extends KindTestImpl {\r\n constructor(attributeName?: string, attributeType?: string) {\r\n const name = attributeName\r\n ? attributeType\r\n ? `attribute(${attributeName}, ${attributeType})`\r\n : `attribute(${attributeName})`\r\n : 'attribute()';\r\n\r\n super(name, 'attribute', attributeName, attributeType, !attributeName);\r\n }\r\n}\r\n\r\n/**\r\n * DocumentNodeTest: document-node() or document-node(element(...))\r\n *\r\n * Matches the document node (root). Can optionally specify a required element test.\r\n *\r\n * Examples:\r\n * - document-node() - any document node\r\n * - document-node(element(book)) - document containing a \"book\" element\r\n * - document-node(element()) - document containing any root element\r\n */\r\nexport class DocumentNodeTest extends KindTestImpl {\r\n private readonly elementTest?: ElementTest;\r\n\r\n constructor(elementTest?: ElementTest) {\r\n const name = elementTest ? `document-node(${elementTest.name})` : 'document-node()';\r\n super(name, 'document', undefined, undefined, true);\r\n this.elementTest = elementTest;\r\n }\r\n\r\n matches(value: any): boolean {\r\n if (!super.matches(value)) {\r\n return false;\r\n }\r\n\r\n // If element test specified, check the document element\r\n if (this.elementTest && value.documentElement) {\r\n return this.elementTest.matches(value.documentElement);\r\n }\r\n\r\n return true;\r\n }\r\n}\r\n\r\n/**\r\n * TextTest: text() - matches text nodes\r\n */\r\nexport class TextTest extends KindTestImpl {\r\n constructor() {\r\n super('text()', 'text');\r\n }\r\n}\r\n\r\n/**\r\n * CommentTest: comment() - matches comment nodes\r\n */\r\nexport class CommentTest extends KindTestImpl {\r\n constructor() {\r\n super('comment()', 'comment');\r\n }\r\n}\r\n\r\n/**\r\n * ProcessingInstructionTest: processing-instruction() or processing-instruction(target)\r\n *\r\n * Examples:\r\n * - processing-instruction() - any processing instruction\r\n * - processing-instruction(php) - processing instruction with target \"php\"\r\n */\r\nexport class ProcessingInstructionTest extends KindTestImpl {\r\n constructor(target?: string) {\r\n const name = target ? `processing-instruction(${target})` : 'processing-instruction()';\r\n super(name, 'processing-instruction', target, undefined, !target);\r\n }\r\n}\r\n\r\n/**\r\n * SchemaElementTest: schema-element(name)\r\n *\r\n * Matches elements declared in the schema with the given name.\r\n * Requires schema information to be available.\r\n *\r\n * Example:\r\n * - schema-element(book) - element declared as <xs:element name=\"book\"> in schema\r\n */\r\nexport class SchemaElementTest extends KindTestImpl {\r\n constructor(elementName: string) {\r\n super(`schema-element(${elementName})`, 'element', elementName, undefined, false);\r\n }\r\n\r\n matches(value: any): boolean {\r\n if (!super.matches(value)) {\r\n return false;\r\n }\r\n\r\n // Schema matching would require schema information\r\n // For now, just check the name\r\n return true;\r\n }\r\n}\r\n\r\n/**\r\n * SchemaAttributeTest: schema-attribute(name)\r\n *\r\n * Matches attributes declared in the schema with the given name.\r\n * Requires schema information to be available.\r\n *\r\n * Example:\r\n * - schema-attribute(lang) - attribute declared as <xs:attribute name=\"lang\"> in schema\r\n */\r\nexport class SchemaAttributeTest extends KindTestImpl {\r\n constructor(attributeName: string) {\r\n super(`schema-attribute(${attributeName})`, 'attribute', attributeName, undefined, false);\r\n }\r\n\r\n matches(value: any): boolean {\r\n if (!super.matches(value)) {\r\n return false;\r\n }\r\n\r\n // Schema matching would require schema information\r\n // For now, just check the name\r\n return true;\r\n }\r\n}\r\n\r\n/**\r\n * Pre-defined KindTest instances for common cases\r\n */\r\nexport const KIND_TESTS = {\r\n node: new NodeKindTest(),\r\n element: new ElementTest(),\r\n attribute: new AttributeTest(),\r\n documentNode: new DocumentNodeTest(),\r\n text: new TextTest(),\r\n comment: new CommentTest(),\r\n processingInstruction: new ProcessingInstructionTest(),\r\n};\r\n\r\n/**\r\n * Create an ElementTest with the given name and optional type\r\n */\r\nexport function createElement(name?: string, type?: string): ElementTest {\r\n return new ElementTest(name, type);\r\n}\r\n\r\n/**\r\n * Create an AttributeTest with the given name and optional type\r\n */\r\nexport function createAttribute(name?: string, type?: string): AttributeTest {\r\n return new AttributeTest(name, type);\r\n}\r\n\r\n/**\r\n * Create a DocumentNodeTest with optional element test\r\n */\r\nexport function createDocumentNode(elementTest?: ElementTest): DocumentNodeTest {\r\n return new DocumentNodeTest(elementTest);\r\n}\r\n\r\n/**\r\n * Create a ProcessingInstructionTest with optional target\r\n */\r\nexport function createProcessingInstruction(target?: string): ProcessingInstructionTest {\r\n return new ProcessingInstructionTest(target);\r\n}\r\n\r\n/**\r\n * Create a SchemaElementTest with the given name\r\n */\r\nexport function createSchemaElement(name: string): SchemaElementTest {\r\n return new SchemaElementTest(name);\r\n}\r\n\r\n/**\r\n * Create a SchemaAttributeTest with the given name\r\n */\r\nexport function createSchemaAttribute(name: string): SchemaAttributeTest {\r\n return new SchemaAttributeTest(name);\r\n}\r\n","/**\r\n * Union Types (XPath 3.1 Extension)\r\n *\r\n * Implements union type declarations for more expressive type constraints.\r\n * A union type matches a value if it matches ANY of the member types.\r\n *\r\n * Syntax: type1 | type2 | ... | typeN\r\n * Examples:\r\n * - xs:string | xs:integer - matches strings or integers\r\n * - (xs:integer | xs:decimal) | xs:double - nested unions\r\n * - element() | attribute() - matches elements or attributes\r\n *\r\n * Reference: XPath 3.1 Type System Extensions\r\n */\r\n\r\nimport { ItemType } from './sequence-type';\r\nimport { AtomicType } from './base';\r\n\r\n/**\r\n * UnionItemType represents a union of multiple ItemTypes\r\n * A value matches if it matches ANY of the member types\r\n */\r\nexport class UnionItemType implements ItemType {\r\n readonly name: string;\r\n readonly memberTypes: ItemType[];\r\n readonly isWildcard: boolean = false;\r\n\r\n /**\r\n * Create a UnionItemType\r\n *\r\n * @param memberTypes - Array of ItemTypes that form the union\r\n * @throws Error if memberTypes is empty or contains only one type\r\n */\r\n constructor(memberTypes: ItemType[]) {\r\n if (memberTypes.length === 0) {\r\n throw new Error('Union type must have at least one member type');\r\n }\r\n\r\n if (memberTypes.length === 1) {\r\n throw new Error(\r\n 'Union type must have at least two member types (use the single type directly)'\r\n );\r\n }\r\n\r\n // Check for empty-sequence type (represented as 'empty' string)\r\n if (memberTypes.some((t: any) => t === 'empty')) {\r\n throw new Error('empty-sequence() cannot be used in union types');\r\n }\r\n\r\n this.memberTypes = memberTypes;\r\n this.name = memberTypes.map((t) => t.name).join(' | ');\r\n }\r\n\r\n /**\r\n * Check if a value matches this union type\r\n * Returns true if the value matches ANY of the member types\r\n *\r\n * @param value - The value to check\r\n * @returns true if value matches any member type\r\n */\r\n matches(value: any): boolean {\r\n // A value matches a union type if it matches at least one member type\r\n return this.memberTypes.some((memberType) => memberType.matches(value));\r\n }\r\n\r\n /**\r\n * Get all member types in this union\r\n */\r\n getMemberTypes(): ItemType[] {\r\n return [...this.memberTypes];\r\n }\r\n\r\n /**\r\n * Check if this union contains a specific type\r\n *\r\n * @param typeName - The name of the type to check for\r\n * @returns true if any member type has this name\r\n */\r\n containsType(typeName: string): boolean {\r\n return this.memberTypes.some((memberType) => memberType.name === typeName);\r\n }\r\n\r\n /**\r\n * Flatten nested unions into a single-level union\r\n * If any member is itself a union, extract its members\r\n *\r\n * @returns A new UnionItemType with all unions flattened\r\n */\r\n flatten(): UnionItemType {\r\n const flattenedTypes: ItemType[] = [];\r\n\r\n for (const memberType of this.memberTypes) {\r\n if (memberType instanceof UnionItemType) {\r\n // Recursively flatten nested unions\r\n const nested = memberType.flatten();\r\n flattenedTypes.push(...nested.memberTypes);\r\n } else {\r\n flattenedTypes.push(memberType);\r\n }\r\n }\r\n\r\n // Remove duplicates based on type name\r\n const uniqueTypes = flattenedTypes.filter(\r\n (type, index, self) => self.findIndex((t) => t.name === type.name) === index\r\n );\r\n\r\n return new UnionItemType(uniqueTypes);\r\n }\r\n\r\n /**\r\n * Get the most general atomic type in the union\r\n * Used for type promotion in expressions\r\n *\r\n * @returns The most general atomic type, or undefined if no atomic types\r\n */\r\n getMostGeneralAtomicType(): AtomicType | undefined {\r\n const atomicTypes = this.memberTypes\r\n .filter((t) => t.atomicType !== undefined)\r\n .map((t) => t.atomicType!);\r\n\r\n if (atomicTypes.length === 0) {\r\n return undefined;\r\n }\r\n\r\n // Determine the most general type\r\n // Priority order: xs:string > xs:double > xs:decimal > xs:integer\r\n const hasString = atomicTypes.some((t) => t.name === 'string');\r\n if (hasString) {\r\n return atomicTypes.find((t) => t.name === 'string');\r\n }\r\n\r\n const hasDouble = atomicTypes.some((t) => t.name === 'double');\r\n if (hasDouble) {\r\n return atomicTypes.find((t) => t.name === 'double');\r\n }\r\n\r\n const hasDecimal = atomicTypes.some((t) => t.name === 'decimal');\r\n if (hasDecimal) {\r\n return atomicTypes.find((t) => t.name === 'decimal');\r\n }\r\n\r\n // Return the first atomic type found\r\n return atomicTypes[0];\r\n }\r\n\r\n /**\r\n * String representation of this union type\r\n */\r\n toString(): string {\r\n return this.name;\r\n }\r\n}\r\n\r\n/**\r\n * Create a union type from multiple ItemTypes\r\n *\r\n * @param memberTypes - The types to combine into a union\r\n * @returns A UnionItemType\r\n * @throws Error if memberTypes is empty or contains only one type\r\n */\r\nexport function createUnionType(...memberTypes: ItemType[]): UnionItemType {\r\n return new UnionItemType(memberTypes);\r\n}\r\n\r\n/**\r\n * Check if an ItemType is a union type\r\n *\r\n * @param itemType - The ItemType to check\r\n * @returns true if itemType is a UnionItemType\r\n */\r\nexport function isUnionType(itemType: ItemType): itemType is UnionItemType {\r\n return itemType instanceof UnionItemType;\r\n}\r\n","/**\r\n * SequenceType Matching Algorithm (Section 2.5.4)\r\n *\r\n * Implements the algorithm for checking if a value/sequence matches a given SequenceType.\r\n *\r\n * The matching process:\r\n * 1. If the SequenceType is empty-sequence(), the sequence must be empty\r\n * 2. Otherwise, each item in the sequence must match the ItemType\r\n * 3. The total number of items must satisfy the occurrence indicator\r\n */\r\n\r\nimport { SequenceType, OccurrenceIndicator, ItemType, ITEM_TYPE } from './sequence-type';\r\nimport { AtomicType } from './base';\r\n\r\n/**\r\n * Result of a sequence type match operation\r\n */\r\nexport interface MatchResult {\r\n /**\r\n * Whether the value matches the SequenceType\r\n */\r\n matches: boolean;\r\n\r\n /**\r\n * If doesn't match, reason why\r\n */\r\n reason?: string;\r\n\r\n /**\r\n * Number of items that matched (useful for debugging)\r\n */\r\n itemCount?: number;\r\n}\r\n\r\n/**\r\n * Check if a single value matches an ItemType\r\n *\r\n * @param value - The value to check\r\n * @param itemType - The ItemType to match against\r\n * @returns true if the value matches the ItemType\r\n */\r\nexport function matchesItemType(value: any, itemType: ItemType): boolean {\r\n // Check for union types (XPath 3.1 Extension)\r\n const { isUnionType } = require('./union-type');\r\n if (isUnionType(itemType)) {\r\n return itemType.matches(value);\r\n }\r\n\r\n // Check for typed collection types (map/array) which have their own wildcard semantics\r\n // These should use their matches() method directly, not the isWildcard shortcut\r\n const hasMapTest = (itemType as any).isMapTest;\r\n const hasArrayTest = (itemType as any).isArrayTest;\r\n const hasFunctionTest = (itemType as any).isFunctionTest;\r\n\r\n if (hasMapTest || hasArrayTest || hasFunctionTest) {\r\n return itemType.matches(value);\r\n }\r\n\r\n if (itemType.isWildcard) {\r\n // item() matches any single value\r\n return value !== null && value !== undefined;\r\n }\r\n\r\n return itemType.matches(value);\r\n}\r\n\r\n/**\r\n * Check if an array/sequence of values matches a SequenceType\r\n *\r\n * @param values - A single value or array of values to check\r\n * @param sequenceType - The SequenceType to match against\r\n * @returns MatchResult with details of the match\r\n */\r\nexport function matchesSequenceType(values: any, sequenceType: SequenceType): MatchResult {\r\n // Normalize input to array\r\n const sequence = Array.isArray(values) ? values : [values].filter((v) => v !== undefined);\r\n\r\n // Handle empty sequence\r\n if (sequence.length === 0) {\r\n if (sequenceType.isEmptySequence()) {\r\n return { matches: true, itemCount: 0 };\r\n }\r\n\r\n if (sequenceType.allowsZeroItems()) {\r\n return { matches: true, itemCount: 0 };\r\n }\r\n\r\n return {\r\n matches: false,\r\n itemCount: 0,\r\n reason: `Empty sequence not allowed by ${sequenceType.toString()}`,\r\n };\r\n }\r\n\r\n // Handle empty-sequence() type\r\n if (sequenceType.isEmptySequence()) {\r\n return {\r\n matches: false,\r\n itemCount: sequence.length,\r\n reason: `Expected empty sequence but got ${sequence.length} item(s)`,\r\n };\r\n }\r\n\r\n // Get the ItemType to match against\r\n const itemType = sequenceType.getItemType();\r\n if (itemType === 'empty') {\r\n return {\r\n matches: false,\r\n itemCount: sequence.length,\r\n reason: 'Expected empty sequence',\r\n };\r\n }\r\n\r\n // Check each item in the sequence\r\n const typedItemType = itemType as ItemType;\r\n const unmatched = sequence.findIndex((item) => !matchesItemType(item, typedItemType));\r\n\r\n if (unmatched !== -1) {\r\n const unmatchedItem = sequence[unmatched];\r\n // Handle object/array conversion safely for error messages\r\n let itemDesc: string;\r\n try {\r\n if (typeof unmatchedItem === 'object' && unmatchedItem !== null) {\r\n itemDesc = JSON.stringify(unmatchedItem);\r\n } else {\r\n itemDesc = String(unmatchedItem);\r\n }\r\n } catch {\r\n itemDesc = '[complex value]';\r\n }\r\n\r\n return {\r\n matches: false,\r\n itemCount: sequence.length,\r\n reason: `Item ${unmatched} (${itemDesc}) does not match ${typedItemType.name}`,\r\n };\r\n }\r\n\r\n // Check cardinality\r\n const occurrence = sequenceType.getOccurrence();\r\n const itemCount = sequence.length;\r\n\r\n switch (occurrence) {\r\n case OccurrenceIndicator.EXACTLY_ONE:\r\n if (itemCount === 1) {\r\n return { matches: true, itemCount };\r\n }\r\n return {\r\n matches: false,\r\n itemCount,\r\n reason: `Expected exactly one item but got ${itemCount}`,\r\n };\r\n\r\n case OccurrenceIndicator.ZERO_OR_ONE:\r\n if (itemCount <= 1) {\r\n return { matches: true, itemCount };\r\n }\r\n return {\r\n matches: false,\r\n itemCount,\r\n reason: `Expected zero or one item but got ${itemCount}`,\r\n };\r\n\r\n case OccurrenceIndicator.ZERO_OR_MORE:\r\n return { matches: true, itemCount };\r\n\r\n case OccurrenceIndicator.ONE_OR_MORE:\r\n if (itemCount >= 1) {\r\n return { matches: true, itemCount };\r\n }\r\n return {\r\n matches: false,\r\n itemCount: 0,\r\n reason: `Expected one or more items but got none`,\r\n };\r\n\r\n default:\r\n return {\r\n matches: false,\r\n itemCount,\r\n reason: `Unknown occurrence indicator: ${occurrence}`,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Check if a value matches an ItemType (shorthand)\r\n */\r\nexport function matchesItem(value: any, itemType: ItemType): boolean {\r\n return matchesItemType(value, itemType);\r\n}\r\n\r\n/**\r\n * Check if a sequence matches a SequenceType (shorthand - returns boolean)\r\n */\r\nexport function matches(values: any, sequenceType: SequenceType): boolean {\r\n return matchesSequenceType(values, sequenceType).matches;\r\n}\r\n\r\n/**\r\n * Find the first item in a sequence that doesn't match an ItemType\r\n *\r\n * @param sequence - Array of values\r\n * @param itemType - The ItemType to match against\r\n * @returns Index of non-matching item, or -1 if all match\r\n */\r\nexport function findMismatch(sequence: any[], itemType: ItemType): number {\r\n return sequence.findIndex((item) => !matchesItemType(item, itemType));\r\n}\r\n\r\n/**\r\n * Count how many items in a sequence match an ItemType\r\n */\r\nexport function countMatches(sequence: any[], itemType: ItemType): number {\r\n return sequence.filter((item) => matchesItemType(item, itemType)).length;\r\n}\r\n\r\n/**\r\n * Check if an AtomicType satisfies a SequenceType's ItemType\r\n * (useful for static type checking)\r\n *\r\n * @param atomicType - The atomic type to check\r\n * @param sequenceType - The sequence type to match against\r\n * @returns true if the atomic type satisfies the sequence type's item type\r\n */\r\nexport function atomicTypeSatisfies(atomicType: AtomicType, sequenceType: SequenceType): boolean {\r\n const itemType = sequenceType.getItemType();\r\n\r\n if (itemType === 'empty') {\r\n return false; // Atomic type cannot be empty\r\n }\r\n\r\n const typedItemType = itemType as ItemType;\r\n\r\n // Check if the ItemType's atomic type matches\r\n if (typedItemType.atomicType) {\r\n return typedItemType.atomicType.name === atomicType.name;\r\n }\r\n\r\n // Check if it's the wildcard item() type\r\n if (typedItemType.isWildcard) {\r\n return true;\r\n }\r\n\r\n // Check by name\r\n return typedItemType.name === atomicType.name;\r\n}\r\n\r\n/**\r\n * Get a human-readable description of what a SequenceType accepts\r\n */\r\nexport function describeSequenceType(sequenceType: SequenceType): string {\r\n if (sequenceType.isEmptySequence()) {\r\n return 'an empty sequence';\r\n }\r\n\r\n const itemType = sequenceType.getItemType() as ItemType;\r\n const typeName = itemType.name;\r\n\r\n const occurrence = sequenceType.getOccurrence();\r\n const descriptions: { [key: string]: string } = {\r\n [OccurrenceIndicator.EXACTLY_ONE]: `exactly one ${typeName}`,\r\n [OccurrenceIndicator.ZERO_OR_ONE]: `zero or one ${typeName}`,\r\n [OccurrenceIndicator.ZERO_OR_MORE]: `zero or more ${typeName}s`,\r\n [OccurrenceIndicator.ONE_OR_MORE]: `one or more ${typeName}s`,\r\n };\r\n\r\n return descriptions[occurrence] || typeName;\r\n}\r\n\r\n/**\r\n * Check if a value is a valid single item (not a sequence)\r\n */\r\nexport function isSingleItem(value: any): boolean {\r\n return value !== null && value !== undefined && !Array.isArray(value);\r\n}\r\n\r\n/**\r\n * Check if a value is a valid sequence (array or single item)\r\n */\r\nexport function isValidSequence(value: any): boolean {\r\n return Array.isArray(value) || isSingleItem(value);\r\n}\r\n\r\n/**\r\n * Convert a value to a sequence (array)\r\n *\r\n * @param value - Single item or array\r\n * @returns Array representation of the sequence\r\n */\r\nexport function toSequence(value: any): any[] {\r\n if (Array.isArray(value)) {\r\n return value;\r\n }\r\n if (value === undefined || value === null) {\r\n return [];\r\n }\r\n return [value];\r\n}\r\n\r\n/**\r\n * Check if two ItemTypes are equivalent\r\n */\r\nexport function itemTypesEquivalent(itemType1: ItemType, itemType2: ItemType): boolean {\r\n if (itemType1.isWildcard && itemType2.isWildcard) {\r\n return true;\r\n }\r\n\r\n if (itemType1.isWildcard || itemType2.isWildcard) {\r\n return false;\r\n }\r\n\r\n // Compare by name and namespace\r\n if (itemType1.name !== itemType2.name) {\r\n return false;\r\n }\r\n\r\n if (itemType1.namespace !== itemType2.namespace) {\r\n return false;\r\n }\r\n\r\n return true;\r\n}\r\n\r\n/**\r\n * Check if two SequenceTypes are equivalent\r\n */\r\nexport function sequenceTypesEquivalent(seq1: SequenceType, seq2: SequenceType): boolean {\r\n // Both empty\r\n if (seq1.isEmptySequence() && seq2.isEmptySequence()) {\r\n return true;\r\n }\r\n\r\n // One empty, other not\r\n if (seq1.isEmptySequence() || seq2.isEmptySequence()) {\r\n return false;\r\n }\r\n\r\n // Compare occurrence indicators\r\n if (seq1.getOccurrence() !== seq2.getOccurrence()) {\r\n return false;\r\n }\r\n\r\n // Compare item types\r\n const itemType1 = seq1.getItemType() as ItemType;\r\n const itemType2 = seq2.getItemType() as ItemType;\r\n\r\n return itemTypesEquivalent(itemType1, itemType2);\r\n}\r\n","/**\r\n * XPath 2.0 Atomization (Section 2.4.2)\r\n * https://www.w3.org/TR/xpath20/#atomization\r\n *\r\n * Atomization is the process of extracting typed atomic values from nodes.\r\n *\r\n * Rules:\r\n * 1. If the input is already an atomic value, return it unchanged\r\n * 2. If the input is a node:\r\n * a. If it has a typed value, return that value (or values)\r\n * b. If it's untyped, return the string value\r\n * 3. For nodes with complex content, extract the text nodes and concatenate\r\n * 4. Special error FOTY0012 for nodes with element-only content (no text)\r\n */\r\n\r\nimport { AtomicType } from './base';\r\nimport { getAtomicType } from './index';\r\n\r\n/**\r\n * Result of atomization\r\n */\r\nexport interface AtomizationResult {\r\n /**\r\n * The atomized value(s) - always an array\r\n */\r\n values: any[];\r\n\r\n /**\r\n * The type of the atomized value(s)\r\n */\r\n type: AtomicType | undefined;\r\n\r\n /**\r\n * Whether this is an empty sequence\r\n */\r\n isEmpty: boolean;\r\n\r\n /**\r\n * Error code if atomization failed (e.g., 'FOTY0012')\r\n */\r\n error?: string;\r\n}\r\n\r\n/**\r\n * Node-like object interface\r\n */\r\nexport interface XPathNode {\r\n nodeType: string;\r\n nodeName?: string;\r\n localName?: string;\r\n value?: any;\r\n textContent?: string;\r\n childNodes?: XPathNode[];\r\n attributes?: { [key: string]: any };\r\n /**\r\n * Optional: typed value (if node has schema type info)\r\n */\r\n typedValue?: any;\r\n /**\r\n * Optional: type annotation\r\n */\r\n type?: string;\r\n}\r\n\r\n/**\r\n * Check if a value is a node-like object\r\n */\r\nexport function isNode(value: any): value is XPathNode {\r\n if (!value || typeof value !== 'object') {\r\n return false;\r\n }\r\n\r\n // Check for node-like properties\r\n return (\r\n typeof value.nodeType === 'string' ||\r\n typeof value.nodeName === 'string' ||\r\n typeof value.textContent === 'string'\r\n );\r\n}\r\n\r\n/**\r\n * Check if a node contains only element content (no text nodes)\r\n * This would trigger error FOTY0012 in certain contexts\r\n */\r\nexport function hasElementOnlyContent(node: XPathNode): boolean {\r\n if (!node.childNodes || node.childNodes.length === 0) {\r\n return false; // Empty is not \"element-only\"\r\n }\r\n\r\n // Check if all children are elements (nodeType === 'element')\r\n return node.childNodes.every((child) => child.nodeType === 'element');\r\n}\r\n\r\n/**\r\n * Get the typed value of a node\r\n * This extracts the schema-validated value from a node\r\n */\r\nexport function getNodeTypedValue(node: XPathNode): { value: any; type: AtomicType | undefined } {\r\n // If node has explicit typed value, use it\r\n if (node.typedValue !== undefined) {\r\n if (node.type) {\r\n const atomicType = getAtomicType(node.type);\r\n return { value: node.typedValue, type: atomicType };\r\n }\r\n return { value: node.typedValue, type: undefined };\r\n }\r\n\r\n // If node has type annotation, use it with string content\r\n if (node.type) {\r\n const atomicType = getAtomicType(node.type);\r\n const textContent = getNodeStringValue(node);\r\n if (atomicType) {\r\n try {\r\n const castValue = atomicType.cast(textContent);\r\n return { value: castValue, type: atomicType };\r\n } catch {\r\n // If casting fails, return as untyped\r\n return { value: textContent, type: undefined };\r\n }\r\n }\r\n }\r\n\r\n // Default: use string value\r\n return { value: getNodeStringValue(node), type: undefined };\r\n}\r\n\r\n/**\r\n * Get the string value of a node\r\n * For element/document nodes: concatenates all text nodes\r\n * For text/attribute/comment nodes: the text content\r\n * For processing instructions: the data part\r\n */\r\nexport function getNodeStringValue(node: XPathNode): string {\r\n if (node.nodeType === 'text' || node.nodeType === 'attribute' || node.nodeType === 'comment') {\r\n return node.value || node.textContent || '';\r\n }\r\n\r\n if (node.nodeType === 'processing-instruction') {\r\n // PI: target followed by space and data\r\n return node.value || '';\r\n }\r\n\r\n if (node.nodeType === 'element' || node.nodeType === 'document') {\r\n // Concatenate all text node descendants\r\n if (node.textContent) {\r\n return node.textContent;\r\n }\r\n\r\n if (!node.childNodes) {\r\n return '';\r\n }\r\n\r\n let result = '';\r\n for (const child of node.childNodes) {\r\n if (child.nodeType === 'text') {\r\n result += child.value || child.textContent || '';\r\n } else if (child.nodeType === 'element') {\r\n result += getNodeStringValue(child);\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n return '';\r\n}\r\n\r\n/**\r\n * Atomize a value\r\n * Extracts atomic values from nodes or returns atomic values unchanged\r\n *\r\n * @param value - Single value or array of values\r\n * @param strict - If true, raise error FOTY0012 for element-only content\r\n * @returns AtomizationResult\r\n */\r\nexport function atomize(value: any, strict: boolean = false): AtomizationResult {\r\n // Handle undefined/null\r\n if (value === undefined || value === null) {\r\n return {\r\n values: [],\r\n type: undefined,\r\n isEmpty: true,\r\n };\r\n }\r\n\r\n // Handle arrays\r\n if (Array.isArray(value)) {\r\n const results: any[] = [];\r\n let resultType: AtomicType | undefined = undefined;\r\n let hasError = false;\r\n let errorCode = '';\r\n\r\n for (const item of value) {\r\n const result = atomize(item, strict);\r\n\r\n if (result.error) {\r\n hasError = true;\r\n errorCode = result.error;\r\n break;\r\n }\r\n\r\n results.push(...result.values);\r\n\r\n // Track type (should be consistent)\r\n if (result.type && !resultType) {\r\n resultType = result.type;\r\n }\r\n }\r\n\r\n return {\r\n values: results,\r\n type: resultType,\r\n isEmpty: results.length === 0,\r\n error: hasError ? errorCode : undefined,\r\n };\r\n }\r\n\r\n // Handle nodes\r\n if (isNode(value)) {\r\n // Check for element-only content error\r\n if (strict && hasElementOnlyContent(value)) {\r\n return {\r\n values: [],\r\n type: undefined,\r\n isEmpty: false,\r\n error: 'FOTY0012', // Cannot atomize node with element-only content\r\n };\r\n }\r\n\r\n const { value: atomizedValue, type } = getNodeTypedValue(value);\r\n\r\n return {\r\n values: atomizedValue !== undefined ? [atomizedValue] : [],\r\n type,\r\n isEmpty: atomizedValue === undefined,\r\n };\r\n }\r\n\r\n // Atomic values are returned unchanged\r\n return {\r\n values: [value],\r\n type: undefined,\r\n isEmpty: false,\r\n };\r\n}\r\n\r\n/**\r\n * Atomize and return single value\r\n * Throws error if sequence contains multiple values\r\n */\r\nexport function atomizeToSingleValue(value: any): any {\r\n const result = atomize(value);\r\n\r\n if (result.error) {\r\n throw new Error(`Atomization error: ${result.error}`);\r\n }\r\n\r\n if (result.values.length === 0) {\r\n return undefined;\r\n }\r\n\r\n if (result.values.length > 1) {\r\n throw new Error(\r\n `Cannot atomize to single value: expected 1 item, got ${result.values.length}`\r\n );\r\n }\r\n\r\n return result.values[0];\r\n}\r\n\r\n/**\r\n * Extract all string values from nodes by concatenating text content\r\n * Used for string operations on mixed content\r\n */\r\nexport function extractStringValues(value: any): string[] {\r\n if (value === undefined || value === null) {\r\n return [];\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n return value.flatMap(extractStringValues);\r\n }\r\n\r\n if (isNode(value)) {\r\n return [getNodeStringValue(value)];\r\n }\r\n\r\n if (typeof value === 'string') {\r\n return [value];\r\n }\r\n\r\n return [String(value)];\r\n}\r\n\r\n/**\r\n * Convert atomization result to a sequence of values\r\n */\r\nexport function atomizationToSequence(result: AtomizationResult): any[] {\r\n if (result.error) {\r\n throw new Error(`Atomization failed: ${result.error}`);\r\n }\r\n return result.values;\r\n}\r\n\r\n/**\r\n * Check if atomization succeeded\r\n */\r\nexport function isAtomizationSuccess(result: AtomizationResult): boolean {\r\n return !result.error;\r\n}\r\n\r\n/**\r\n * Get error description from atomization result\r\n */\r\nexport function getAtomizationErrorDescription(error: string): string {\r\n const descriptions: { [key: string]: string } = {\r\n FOTY0012: 'Cannot atomize node with element-only content (no text nodes)',\r\n XPTY0004: 'Type error in atomization',\r\n };\r\n\r\n return descriptions[error] || `Atomization error: ${error}`;\r\n}\r\n\r\n/**\r\n * Create a mock node for testing\r\n */\r\nexport function createTestNode(\r\n nodeType: string,\r\n content?: string,\r\n type?: string,\r\n children?: XPathNode[]\r\n): XPathNode {\r\n return {\r\n nodeType,\r\n nodeName: nodeType === 'element' ? 'test' : undefined,\r\n localName: nodeType === 'element' ? 'test' : undefined,\r\n value: content,\r\n textContent: content,\r\n type,\r\n childNodes: children,\r\n };\r\n}\r\n\r\n/**\r\n * Create a test element node with child text nodes\r\n */\r\nexport function createElementWithText(\r\n elementName: string,\r\n textContent: string,\r\n type?: string\r\n): XPathNode {\r\n const textNode = createTestNode('text', textContent);\r\n\r\n return {\r\n nodeType: 'element',\r\n nodeName: elementName,\r\n localName: elementName,\r\n textContent,\r\n type,\r\n childNodes: [textNode],\r\n };\r\n}\r\n\r\n/**\r\n * Create a test element node with only element children (element-only content)\r\n */\r\nexport function createElementWithChildren(\r\n elementName: string,\r\n children: XPathNode[],\r\n type?: string\r\n): XPathNode {\r\n return {\r\n nodeType: 'element',\r\n nodeName: elementName,\r\n localName: elementName,\r\n type,\r\n childNodes: children,\r\n };\r\n}\r\n","/**\r\n * Map Constructor Expression (XPath 3.1)\r\n *\r\n * Represents a map constructor expression: map { key: value, key: value, ... }\r\n *\r\n * Syntax: map { ExprSingle : ExprSingle (, ExprSingle : ExprSingle)* }\r\n *\r\n * Key features:\r\n * - Keys are atomized (converted to atomic values)\r\n * - Duplicate keys: last value wins\r\n * - Empty map: map { }\r\n * - Nested maps allowed: map { \"outer\": map { \"inner\": 42 } }\r\n *\r\n * Reference: https://www.w3.org/TR/xpath-31/#id-map-constructors\r\n */\r\n\r\nimport { XPathExpression } from './expression';\r\nimport { XPathContext } from '../context';\r\nimport { atomize } from '../types/atomization';\r\nimport { typeMismatch } from '../errors';\r\n\r\n/**\r\n * Represents a single key-value pair entry in a map constructor.\r\n */\r\nexport interface MapConstructorEntry {\r\n key: XPathExpression;\r\n value: XPathExpression;\r\n}\r\n\r\n/**\r\n * Check if a value is an XPath map.\r\n */\r\nexport function isXPathMap(value: any): value is XPathMap {\r\n return value && typeof value === 'object' && value.__isMap === true;\r\n}\r\n\r\n/**\r\n * Represents an XPath map with string keys and arbitrary values.\r\n */\r\nexport interface XPathMap {\r\n __isMap: true;\r\n [key: string]: any;\r\n}\r\n\r\n/**\r\n * Map Constructor Expression: map { key: value, ... }\r\n *\r\n * Creates a map data structure from key-value pairs.\r\n * Keys must be atomic values, values can be any sequence.\r\n */\r\nexport class XPathMapConstructorExpression implements XPathExpression {\r\n constructor(private entries: MapConstructorEntry[]) {}\r\n\r\n evaluate(context: XPathContext): any {\r\n const result: Record<string, any> = {};\r\n\r\n for (const entry of this.entries) {\r\n // Evaluate and atomize the key\r\n const keyResult = entry.key.evaluate(context);\r\n const atomicKeys = atomize(keyResult);\r\n\r\n // Keys must be atomic values (single atomic value per entry)\r\n if (atomicKeys.error) {\r\n throw typeMismatch('atomic value', 'value with error', 'map key');\r\n }\r\n\r\n if (atomicKeys.isEmpty || atomicKeys.values.length === 0) {\r\n throw typeMismatch('atomic value', 'empty sequence', 'map key');\r\n }\r\n\r\n if (atomicKeys.values.length > 1) {\r\n throw typeMismatch('single atomic value', 'sequence', 'map key');\r\n }\r\n\r\n const key = atomicKeys.values[0];\r\n\r\n // Convert key to string for JavaScript object property\r\n const keyString = String(key);\r\n\r\n // Evaluate the value (can be any sequence)\r\n const value = entry.value.evaluate(context);\r\n\r\n // Store in map (last value wins for duplicate keys)\r\n result[keyString] = value;\r\n }\r\n\r\n // Mark the result as a map for type checking\r\n return this.createMap(result);\r\n }\r\n\r\n /**\r\n * Create a map object with type marker.\r\n * Maps are distinguishable from plain objects and arrays.\r\n */\r\n private createMap(entries: Record<string, any>): any {\r\n // Create a map with a type marker\r\n // This allows us to distinguish maps from plain objects\r\n const map = Object.create(null);\r\n map.__isMap = true;\r\n Object.assign(map, entries);\r\n return map;\r\n }\r\n}\r\n","/**\r\n * Array Constructor Expression (XPath 3.1)\r\n *\r\n * Represents array constructor expressions:\r\n * - Square bracket syntax: [item1, item2, ...]\r\n * - Curly syntax: array { expr }\r\n *\r\n * Key features:\r\n * - Each item in square bracket syntax becomes a separate array member\r\n * - In curly syntax, the expression result is atomized/flattened into members\r\n * - Empty array: [] or array { }\r\n * - Arrays are 1-indexed (not 0-indexed)\r\n * - Nested arrays allowed: [[1, 2], [3, 4]]\r\n *\r\n * Reference: https://www.w3.org/TR/xpath-31/#id-array-constructors\r\n */\r\n\r\nimport { XPathExpression } from './expression';\r\nimport { XPathContext } from '../context';\r\n\r\n/**\r\n * Marker interface for XPath 3.1 arrays.\r\n * Arrays are distinguishable from plain JavaScript arrays.\r\n */\r\nexport interface XPathArray {\r\n __isArray: true;\r\n members: any[];\r\n}\r\n\r\n/**\r\n * Check if a value is an XPath array.\r\n */\r\nexport function isXPathArray(value: any): value is XPathArray {\r\n return value && typeof value === 'object' && value.__isArray === true;\r\n}\r\n\r\n/**\r\n * Create an XPath array from members.\r\n */\r\nexport function createXPathArray(members: any[]): XPathArray {\r\n return {\r\n __isArray: true,\r\n members: members,\r\n };\r\n}\r\n\r\n/**\r\n * Get the size of an XPath array.\r\n */\r\nexport function getArraySize(arr: XPathArray): number {\r\n return arr.members.length;\r\n}\r\n\r\n/**\r\n * Get a member from an XPath array (1-based indexing).\r\n * @param arr The array\r\n * @param position 1-based position\r\n * @returns The member at that position, or throws error if out of bounds\r\n */\r\nexport function getArrayMember(arr: XPathArray, position: number): any {\r\n if (position < 1 || position > arr.members.length) {\r\n throw new Error(\r\n `FOAY0001: Array index ${position} out of bounds (array size: ${arr.members.length})`\r\n );\r\n }\r\n return arr.members[position - 1];\r\n}\r\n\r\n/**\r\n * Square Bracket Array Constructor: [item1, item2, ...]\r\n *\r\n * Creates an array where each expression becomes a separate member.\r\n * Each member can be any sequence.\r\n */\r\nexport class XPathSquareBracketArrayConstructor implements XPathExpression {\r\n constructor(private items: XPathExpression[]) {}\r\n\r\n evaluate(context: XPathContext): any {\r\n const members: any[] = [];\r\n\r\n for (const item of this.items) {\r\n // Each expression evaluates to one array member\r\n // The member can be any sequence (including empty sequence)\r\n const value = item.evaluate(context);\r\n members.push(value);\r\n }\r\n\r\n return createXPathArray(members);\r\n }\r\n\r\n toString(): string {\r\n const itemStrs = this.items.map((i) => i.toString()).join(', ');\r\n return `[${itemStrs}]`;\r\n }\r\n}\r\n\r\n/**\r\n * Curly Brace Array Constructor: array { expr }\r\n *\r\n * Creates an array where the expression result is flattened into members.\r\n * Each item in the sequence becomes a separate array member.\r\n */\r\nexport class XPathCurlyBraceArrayConstructor implements XPathExpression {\r\n constructor(private expr: XPathExpression) {}\r\n\r\n evaluate(context: XPathContext): any {\r\n const result = this.expr.evaluate(context);\r\n\r\n // Convert the result to an array of members\r\n // Each item in the sequence becomes a member\r\n const members = this.toSequence(result);\r\n\r\n return createXPathArray(members);\r\n }\r\n\r\n /**\r\n * Convert any value to a sequence (array) of items.\r\n */\r\n private toSequence(value: any): any[] {\r\n if (value === null || value === undefined) {\r\n return [];\r\n }\r\n\r\n // If it's already a plain JavaScript array, use it as is\r\n // (each element becomes a member)\r\n if (Array.isArray(value)) {\r\n return value;\r\n }\r\n\r\n // If it's an XPath array, don't flatten - treat it as single item\r\n if (isXPathArray(value)) {\r\n return [value];\r\n }\r\n\r\n // Single value becomes single-member array\r\n return [value];\r\n }\r\n\r\n toString(): string {\r\n return `array { ${this.expr.toString()} }`;\r\n }\r\n}\r\n","/**\r\n * Typed Collection Types for XPath 3.1\r\n *\r\n * Implements TypedMapTest and TypedArrayTest for runtime type checking\r\n * of maps and arrays with constrained key/value and member types.\r\n *\r\n * Syntax:\r\n * - map(key-type, value-type) - Map with specific key and value types\r\n * - map(*) - Any map with any key/value types\r\n * - array(member-type) - Array with specific member type\r\n * - array(*) - Any array with any member type\r\n */\r\n\r\nimport { ItemType, SequenceType } from './sequence-type';\r\nimport { isXPathMap } from '../expressions/map-constructor-expression';\r\nimport { isXPathArray } from '../expressions/array-constructor-expression';\r\nimport { matchesSequenceType } from './sequence-type-matcher';\r\n\r\n/**\r\n * TypedMapItemType represents map(key-type, value-type) type test\r\n * Used for static and dynamic type checking of maps\r\n */\r\nexport interface TypedMapItemType extends ItemType {\r\n /**\r\n * Indicates this is a map type test\r\n */\r\n readonly isMapTest: true;\r\n\r\n /**\r\n * The SequenceType that keys must match\r\n * If null, allows any key (map(*))\r\n */\r\n readonly keyType: SequenceType | null;\r\n\r\n /**\r\n * The SequenceType that values must match\r\n * If null, allows any value (map(*))\r\n */\r\n readonly valueType: SequenceType | null;\r\n\r\n /**\r\n * Whether this is the wildcard map(*) test\r\n */\r\n readonly isWildcard: boolean;\r\n}\r\n\r\n/**\r\n * TypedArrayItemType represents array(member-type) type test\r\n * Used for static and dynamic type checking of arrays\r\n */\r\nexport interface TypedArrayItemType extends ItemType {\r\n /**\r\n * Indicates this is an array type test\r\n */\r\n readonly isArrayTest: true;\r\n\r\n /**\r\n * The SequenceType that members must match\r\n * If null, allows any member (array(*))\r\n */\r\n readonly memberType: SequenceType | null;\r\n\r\n /**\r\n * Whether this is the wildcard array(*) test\r\n */\r\n readonly isWildcard: boolean;\r\n}\r\n\r\n/**\r\n * Create a TypedMapItemType for map(key-type, value-type)\r\n *\r\n * @param keyType - The SequenceType for keys (null for wildcard)\r\n * @param valueType - The SequenceType for values (null for wildcard)\r\n * @returns TypedMapItemType that can be used in instance-of or treat-as expressions\r\n */\r\nexport function createTypedMapTest(\r\n keyType: SequenceType | null,\r\n valueType: SequenceType | null\r\n): TypedMapItemType {\r\n const isWildcardMapTest = keyType === null && valueType === null;\r\n\r\n const itemType: TypedMapItemType = {\r\n name: formatMapTypeName(keyType, valueType),\r\n isMapTest: true,\r\n keyType,\r\n valueType,\r\n isWildcard: isWildcardMapTest, // TypedMapItemType.isWildcard field\r\n namespace: undefined,\r\n\r\n matches(value: any): boolean {\r\n // Must be a map\r\n if (!isXPathMap(value)) {\r\n return false;\r\n }\r\n\r\n // Wildcard map matches any map\r\n if (isWildcardMapTest) {\r\n return true;\r\n }\r\n\r\n // Check each entry if specific types are required\r\n const entries = Object.entries(value).filter(\r\n ([key]) => !key.startsWith('_') && !key.startsWith('__')\r\n );\r\n\r\n for (const [key, val] of entries) {\r\n // Check key type\r\n if (keyType !== null) {\r\n const matchResult = matchesSequenceType(key, keyType);\r\n if (!matchResult.matches) {\r\n return false;\r\n }\r\n }\r\n\r\n // Check value type\r\n if (valueType !== null) {\r\n const matchResult = matchesSequenceType(val, valueType);\r\n if (!matchResult.matches) {\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n return true;\r\n },\r\n };\r\n\r\n return itemType;\r\n}\r\n\r\n/**\r\n * Create a TypedArrayItemType for array(member-type)\r\n *\r\n * @param memberType - The SequenceType for members (null for wildcard)\r\n * @returns TypedArrayItemType that can be used in instance-of or treat-as expressions\r\n */\r\nexport function createTypedArrayTest(memberType: SequenceType | null): TypedArrayItemType {\r\n const isWildcardArrayTest = memberType === null;\r\n\r\n const itemType: TypedArrayItemType = {\r\n name: formatArrayTypeName(memberType),\r\n isArrayTest: true,\r\n memberType,\r\n isWildcard: isWildcardArrayTest, // TypedArrayItemType.isWildcard field\r\n namespace: undefined,\r\n\r\n matches(value: any): boolean {\r\n // Must be an array\r\n if (!isXPathArray(value)) {\r\n return false;\r\n }\r\n\r\n // Wildcard array matches any array\r\n if (isWildcardArrayTest) {\r\n return true;\r\n }\r\n\r\n // Check each member if specific type is required\r\n const members = value.members || [];\r\n for (const member of members) {\r\n const matchResult = matchesSequenceType(member, memberType as SequenceType);\r\n if (!matchResult.matches) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n },\r\n };\r\n\r\n return itemType;\r\n}\r\n\r\n/**\r\n * Format a map type name for display\r\n *\r\n * @param keyType - Key SequenceType or null\r\n * @param valueType - Value SequenceType or null\r\n * @returns Formatted type name like \"map(*)\" or \"map(xs:string, xs:integer)\"\r\n */\r\nfunction formatMapTypeName(keyType: SequenceType | null, valueType: SequenceType | null): string {\r\n if (keyType === null && valueType === null) {\r\n return 'map(*)';\r\n }\r\n\r\n const keyStr = keyType ? keyType.toString() : '*';\r\n const valueStr = valueType ? valueType.toString() : '*';\r\n\r\n return `map(${keyStr}, ${valueStr})`;\r\n}\r\n\r\n/**\r\n * Format an array type name for display\r\n *\r\n * @param memberType - Member SequenceType or null\r\n * @returns Formatted type name like \"array(*)\" or \"array(xs:string)\"\r\n */\r\nfunction formatArrayTypeName(memberType: SequenceType | null): string {\r\n if (memberType === null) {\r\n return 'array(*)';\r\n }\r\n\r\n return `array(${memberType.toString()})`;\r\n}\r\n\r\n/**\r\n * Check if an ItemType is a TypedMapTest\r\n */\r\nexport function isTypedMapTest(itemType: ItemType): itemType is TypedMapItemType {\r\n return (itemType as TypedMapItemType).isMapTest === true;\r\n}\r\n\r\n/**\r\n * Check if an ItemType is a TypedArrayTest\r\n */\r\nexport function isTypedArrayTest(itemType: ItemType): itemType is TypedArrayItemType {\r\n return (itemType as TypedArrayItemType).isArrayTest === true;\r\n}\r\n","/**\r\n * XPath 2.0 Type Promotion (Appendix B.1)\r\n * https://www.w3.org/TR/xpath20/#promotion\r\n *\r\n * Type promotion rules:\r\n * 1. Numeric type promotion: integer → decimal → float → double\r\n * 2. URI to string promotion: anyURI → string\r\n * 3. Untyped atomic to string: untypedAtomic → string\r\n * 4. Untyped atomic to numeric: untypedAtomic → double (in numeric contexts)\r\n *\r\n * These rules allow implicit type conversions in certain contexts.\r\n */\r\n\r\nimport { AtomicType, XS_NAMESPACE } from './base';\r\nimport { getAtomicType } from './index';\r\n\r\n/**\r\n * XPath 2.0 Type Promotion Hierarchy\r\n * Lower types promote to higher types in numeric operations\r\n */\r\nexport enum NumericTypeHierarchy {\r\n INTEGER = 0,\r\n DECIMAL = 1,\r\n FLOAT = 2,\r\n DOUBLE = 3,\r\n}\r\n\r\n/**\r\n * Get the numeric type hierarchy level for a type\r\n * Returns -1 if the type is not in the numeric hierarchy\r\n */\r\nexport function getNumericHierarchyLevel(type: AtomicType): NumericTypeHierarchy | -1 {\r\n const name = type.name;\r\n\r\n // All integer-derived types are at INTEGER level\r\n if (\r\n name === 'integer' ||\r\n name === 'long' ||\r\n name === 'int' ||\r\n name === 'short' ||\r\n name === 'byte' ||\r\n name === 'nonPositiveInteger' ||\r\n name === 'negativeInteger' ||\r\n name === 'nonNegativeInteger' ||\r\n name === 'positiveInteger' ||\r\n name === 'unsignedLong' ||\r\n name === 'unsignedInt' ||\r\n name === 'unsignedShort' ||\r\n name === 'unsignedByte'\r\n ) {\r\n return NumericTypeHierarchy.INTEGER;\r\n }\r\n\r\n if (name === 'decimal') {\r\n return NumericTypeHierarchy.DECIMAL;\r\n }\r\n\r\n if (name === 'float') {\r\n return NumericTypeHierarchy.FLOAT;\r\n }\r\n\r\n if (name === 'double') {\r\n return NumericTypeHierarchy.DOUBLE;\r\n }\r\n\r\n return -1;\r\n}\r\n\r\n/**\r\n * Check if one numeric type can be promoted to another\r\n * Promotion only goes upward: integer → decimal → float → double\r\n *\r\n * @param fromType - The source type\r\n * @param toType - The target type\r\n * @returns true if fromType can be promoted to toType\r\n */\r\nexport function canPromoteNumeric(fromType: AtomicType, toType: AtomicType): boolean {\r\n const fromLevel = getNumericHierarchyLevel(fromType);\r\n const toLevel = getNumericHierarchyLevel(toType);\r\n\r\n if (fromLevel === -1 || toLevel === -1) {\r\n return false;\r\n }\r\n\r\n // Can always promote to the same level or higher\r\n return fromLevel <= toLevel;\r\n}\r\n\r\n/**\r\n * Promote a numeric value from one type to another\r\n * Follows XPath 2.0 type promotion rules\r\n *\r\n * @param value - The value to promote (should already be validated as fromType)\r\n * @param fromType - The source type name\r\n * @param toType - The target type name\r\n * @returns The promoted value (or the original value if types match)\r\n * @throws Error if promotion is not allowed\r\n */\r\nexport function promoteNumericValue(value: any, fromType: string, toType: string): any {\r\n // If same type, no promotion needed\r\n if (fromType === toType) {\r\n return value;\r\n }\r\n\r\n // Get the actual type objects\r\n const sourceType = getAtomicType(fromType);\r\n const targetType = getAtomicType(toType);\r\n\r\n if (!sourceType || !targetType) {\r\n throw new Error(`Cannot promote unknown types: ${fromType} to ${toType}`);\r\n }\r\n\r\n // Check if promotion is allowed\r\n if (!canPromoteNumeric(sourceType, targetType)) {\r\n throw new Error(`Cannot promote numeric type ${fromType} to ${toType}`);\r\n }\r\n\r\n // Numeric values are already in JavaScript number format\r\n // The value itself doesn't change, just the semantic type interpretation\r\n return value;\r\n}\r\n\r\n/**\r\n * Get the common type for two numeric types\r\n * Returns the higher type in the hierarchy\r\n *\r\n * @param type1 - First type\r\n * @param type2 - Second type\r\n * @returns The common type, or undefined if not both numeric\r\n */\r\nexport function getCommonNumericType(type1: AtomicType, type2: AtomicType): AtomicType | undefined {\r\n const level1 = getNumericHierarchyLevel(type1);\r\n const level2 = getNumericHierarchyLevel(type2);\r\n\r\n if (level1 === -1 || level2 === -1) {\r\n return undefined;\r\n }\r\n\r\n if (level1 > level2) {\r\n return type1;\r\n } else if (level2 > level1) {\r\n return type2;\r\n } else {\r\n // Same level\r\n return type1;\r\n }\r\n}\r\n\r\n/**\r\n * Check if a type can be promoted to string\r\n * According to XPath 2.0, anyURI can be promoted to string\r\n */\r\nexport function canPromoteToString(type: AtomicType): boolean {\r\n return type.name === 'anyURI' || type.name === 'untypedAtomic';\r\n}\r\n\r\n/**\r\n * Promote a value to string\r\n * Used for anyURI → string and untypedAtomic → string promotions\r\n *\r\n * @param value - The value to promote\r\n * @param fromType - The source type name\r\n * @returns The string value\r\n * @throws Error if promotion is not allowed\r\n */\r\nexport function promoteToString(value: any, fromType: string): string {\r\n if (!['anyURI', 'untypedAtomic', 'string'].includes(fromType)) {\r\n throw new Error(`Cannot promote type ${fromType} to string`);\r\n }\r\n\r\n if (typeof value === 'string') {\r\n return value;\r\n }\r\n\r\n return String(value);\r\n}\r\n\r\n/**\r\n * Promote untypedAtomic to a numeric type\r\n * In numeric contexts, untypedAtomic is promoted to double\r\n *\r\n * @param value - The untyped value (as string)\r\n * @param targetType - The target numeric type ('decimal', 'float', 'double', or 'integer')\r\n * @returns The promoted numeric value\r\n * @throws Error if the value cannot be converted to the target type\r\n */\r\nexport function promoteUntypedToNumeric(value: string, targetType: string): number {\r\n if (!['integer', 'decimal', 'float', 'double'].includes(targetType)) {\r\n throw new Error(`Cannot promote untypedAtomic to non-numeric type ${targetType}`);\r\n }\r\n\r\n const num = parseFloat(value);\r\n\r\n if (isNaN(num)) {\r\n throw new Error(`Cannot convert \"${value}\" to numeric type ${targetType}`);\r\n }\r\n\r\n return num;\r\n}\r\n\r\n/**\r\n * Promotion context enum\r\n * Different contexts apply different promotion rules\r\n */\r\nexport enum PromotionContext {\r\n /**\r\n * Arithmetic context: untypedAtomic → double, numeric types promoted\r\n */\r\n ARITHMETIC = 'arithmetic',\r\n\r\n /**\r\n * Comparison context: untypedAtomic → string or double depending on comparison\r\n */\r\n COMPARISON = 'comparison',\r\n\r\n /**\r\n * String context: everything converts to string\r\n */\r\n STRING = 'string',\r\n\r\n /**\r\n * Boolean context: Effective Boolean Value\r\n */\r\n BOOLEAN = 'boolean',\r\n}\r\n\r\n/**\r\n * Apply type promotion in a specific context\r\n * Used by operators to normalize operand types\r\n *\r\n * @param value - The value to promote\r\n * @param fromType - Current type name\r\n * @param context - The promotion context\r\n * @param targetType - Optional explicit target type\r\n * @returns { value, type } - The promoted value and resulting type\r\n */\r\nexport function promoteInContext(\r\n value: any,\r\n fromType: string,\r\n context: PromotionContext,\r\n targetType?: string\r\n): { value: any; type: string } {\r\n if (fromType === 'untypedAtomic') {\r\n switch (context) {\r\n case PromotionContext.ARITHMETIC:\r\n // Promote to double\r\n return {\r\n value: promoteUntypedToNumeric(value, 'double'),\r\n type: 'double',\r\n };\r\n\r\n case PromotionContext.STRING:\r\n return {\r\n value: promoteToString(value, fromType),\r\n type: 'string',\r\n };\r\n\r\n case PromotionContext.COMPARISON:\r\n if (targetType) {\r\n const targetAtomicType = getAtomicType(targetType);\r\n if (targetAtomicType && getNumericHierarchyLevel(targetAtomicType) !== -1) {\r\n return {\r\n value: promoteUntypedToNumeric(value, targetType),\r\n type: targetType,\r\n };\r\n }\r\n }\r\n return {\r\n value: promoteToString(value, fromType),\r\n type: 'string',\r\n };\r\n\r\n case PromotionContext.BOOLEAN:\r\n // In boolean context, untyped atomic is treated as string\r\n return {\r\n value: promoteToString(value, fromType),\r\n type: 'string',\r\n };\r\n\r\n default:\r\n return { value, type: fromType };\r\n }\r\n }\r\n\r\n if (fromType === 'anyURI' && context === PromotionContext.STRING) {\r\n return {\r\n value: promoteToString(value, fromType),\r\n type: 'string',\r\n };\r\n }\r\n\r\n return { value, type: fromType };\r\n}\r\n\r\n/**\r\n * Get a human-readable description of type promotion rules\r\n */\r\nexport function describePromotion(fromType: string, toType: string): string {\r\n if (fromType === toType) {\r\n return `No promotion needed (same type)`;\r\n }\r\n\r\n if (fromType === 'untypedAtomic') {\r\n if (toType === 'double') {\r\n return 'Promote untypedAtomic to double (numeric context)';\r\n }\r\n if (toType === 'string') {\r\n return 'Promote untypedAtomic to string (string context)';\r\n }\r\n }\r\n\r\n if (fromType === 'anyURI' && toType === 'string') {\r\n return 'Promote anyURI to string';\r\n }\r\n\r\n const fromAtomicType = getAtomicType(fromType);\r\n const toAtomicType = getAtomicType(toType);\r\n\r\n if (fromAtomicType && toAtomicType && canPromoteNumeric(fromAtomicType, toAtomicType)) {\r\n return `Promote numeric type ${fromType} to ${toType}`;\r\n }\r\n\r\n return `Cannot promote ${fromType} to ${toType}`;\r\n}\r\n","/**\r\n * Simple atomic types: anyAtomicType, untypedAtomic, string, boolean\r\n */\r\n\r\nimport { AtomicType, AtomicTypeImpl, XS_NAMESPACE } from './base';\r\n\r\n/**\r\n * xs:anyAtomicType - base type for all atomic types\r\n */\r\nexport class AnyAtomicTypeImpl extends AtomicTypeImpl {\r\n constructor() {\r\n super('anyAtomicType', XS_NAMESPACE);\r\n }\r\n\r\n validate(value: any): boolean {\r\n // anyAtomicType accepts any atomic value\r\n return value !== null && value !== undefined && typeof value !== 'object';\r\n }\r\n\r\n cast(value: any): any {\r\n return value;\r\n }\r\n}\r\n\r\n/**\r\n * xs:untypedAtomic - for untyped atomic data\r\n */\r\nexport class UntypedAtomicImpl extends AtomicTypeImpl {\r\n constructor(baseType: AtomicType) {\r\n super('untypedAtomic', XS_NAMESPACE, baseType, baseType);\r\n }\r\n\r\n validate(value: any): boolean {\r\n return typeof value === 'string';\r\n }\r\n\r\n cast(value: any): string {\r\n return String(value);\r\n }\r\n}\r\n\r\n/**\r\n * xs:string - character strings\r\n */\r\nexport class StringTypeImpl extends AtomicTypeImpl {\r\n constructor(baseType: AtomicType) {\r\n super('string', XS_NAMESPACE, baseType, undefined);\r\n }\r\n\r\n validate(value: any): boolean {\r\n return typeof value === 'string';\r\n }\r\n\r\n cast(value: any): string {\r\n if (value === null || value === undefined) {\r\n throw new Error('Cannot cast null or undefined to xs:string');\r\n }\r\n return String(value);\r\n }\r\n}\r\n\r\n/**\r\n * xs:boolean - true/false values\r\n */\r\nexport class BooleanTypeImpl extends AtomicTypeImpl {\r\n constructor(baseType: AtomicType) {\r\n super('boolean', XS_NAMESPACE, baseType, undefined);\r\n }\r\n\r\n validate(value: any): boolean {\r\n return typeof value === 'boolean';\r\n }\r\n\r\n cast(value: any): boolean {\r\n if (typeof value === 'boolean') return value;\r\n if (typeof value === 'string') {\r\n const trimmed = value.trim().toLowerCase();\r\n if (trimmed === 'true' || trimmed === '1') return true;\r\n if (trimmed === 'false' || trimmed === '0') return false;\r\n throw new Error(`Cannot cast \"${value}\" to xs:boolean`);\r\n }\r\n if (typeof value === 'number') {\r\n if (value === 0) return false;\r\n if (value === 1) return true;\r\n throw new Error(`Cannot cast ${value} to xs:boolean`);\r\n }\r\n throw new Error(`Cannot cast ${typeof value} to xs:boolean`);\r\n }\r\n}\r\n","/**\r\n * Numeric types: decimal, float, double, integer\r\n */\r\n\r\nimport { AtomicType, AtomicTypeImpl, XS_NAMESPACE } from './base';\r\n\r\n/**\r\n * xs:decimal - arbitrary precision decimal numbers\r\n */\r\nexport class DecimalTypeImpl extends AtomicTypeImpl {\r\n constructor(baseType: AtomicType) {\r\n super('decimal', XS_NAMESPACE, baseType, undefined);\r\n }\r\n\r\n validate(value: any): boolean {\r\n if (typeof value === 'number') {\r\n return isFinite(value);\r\n }\r\n return false;\r\n }\r\n\r\n cast(value: any): number {\r\n if (typeof value === 'number' && isFinite(value)) return value;\r\n if (typeof value === 'string') {\r\n const num = parseFloat(value);\r\n if (!isFinite(num)) throw new Error(`Cannot cast \"${value}\" to xs:decimal`);\r\n return num;\r\n }\r\n if (typeof value === 'boolean') return value ? 1 : 0;\r\n throw new Error(`Cannot cast ${typeof value} to xs:decimal`);\r\n }\r\n}\r\n\r\n/**\r\n * xs:float - 32-bit floating point (IEEE 754)\r\n */\r\nexport class FloatTypeImpl extends AtomicTypeImpl {\r\n constructor(baseType: AtomicType) {\r\n super('float', XS_NAMESPACE, baseType, undefined);\r\n }\r\n\r\n validate(value: any): boolean {\r\n return typeof value === 'number';\r\n }\r\n\r\n cast(value: any): number {\r\n if (typeof value === 'number') return value;\r\n if (typeof value === 'string') {\r\n if (value === 'INF') return Infinity;\r\n if (value === '-INF') return -Infinity;\r\n if (value === 'NaN') return NaN;\r\n const num = parseFloat(value);\r\n if (isNaN(num)) throw new Error(`Cannot cast \"${value}\" to xs:float`);\r\n return num;\r\n }\r\n if (typeof value === 'boolean') return value ? 1 : 0;\r\n throw new Error(`Cannot cast ${typeof value} to xs:float`);\r\n }\r\n}\r\n\r\n/**\r\n * xs:double - 64-bit floating point (IEEE 754)\r\n */\r\nexport class DoubleTypeImpl extends AtomicTypeImpl {\r\n constructor(baseType: AtomicType) {\r\n super('double', XS_NAMESPACE, baseType, undefined);\r\n }\r\n\r\n validate(value: any): boolean {\r\n return typeof value === 'number';\r\n }\r\n\r\n cast(value: any): number {\r\n if (typeof value === 'number') return value;\r\n if (typeof value === 'string') {\r\n if (value === 'INF') return Infinity;\r\n if (value === '-INF') return -Infinity;\r\n if (value === 'NaN') return NaN;\r\n const num = parseFloat(value);\r\n if (isNaN(num)) throw new Error(`Cannot cast \"${value}\" to xs:double`);\r\n return num;\r\n }\r\n if (typeof value === 'boolean') return value ? 1 : 0;\r\n throw new Error(`Cannot cast ${typeof value} to xs:double`);\r\n }\r\n}\r\n\r\n/**\r\n * xs:integer - whole numbers (unbounded)\r\n */\r\nexport class IntegerTypeImpl extends AtomicTypeImpl {\r\n constructor(baseType: AtomicType, primitive: AtomicType) {\r\n super('integer', XS_NAMESPACE, baseType, primitive);\r\n }\r\n\r\n validate(value: any): boolean {\r\n return typeof value === 'number' && Number.isInteger(value) && isFinite(value);\r\n }\r\n\r\n cast(value: any): number {\r\n const num = this.baseType!.cast(value);\r\n const intVal = Math.trunc(num);\r\n if (!isFinite(intVal)) throw new Error(`Cannot cast ${value} to xs:integer`);\r\n return intVal;\r\n }\r\n}\r\n","/**\r\n * Date and time types: duration, dateTime, date, time\r\n */\r\n\r\nimport { AtomicType, AtomicTypeImpl, XS_NAMESPACE } from './base';\r\n\r\n/**\r\n * Parse ISO 8601 duration format\r\n * Format: [-]P[nY][nM][nD][T[nH][nM][nS]]\r\n */\r\nexport function parseDuration(value: string): {\r\n negative: boolean;\r\n years: number;\r\n months: number;\r\n days: number;\r\n hours: number;\r\n minutes: number;\r\n seconds: number;\r\n} {\r\n const match = value.match(\r\n /^(-)?P(?:(\\d+)Y)?(?:(\\d+)M)?(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+(?:\\.\\d+)?)S)?)?$/\r\n );\r\n\r\n if (!match) {\r\n throw new Error(`Invalid duration format: \"${value}\"`);\r\n }\r\n\r\n // Check that at least one component is present\r\n const hasComponents = match.slice(2).some((component) => component !== undefined);\r\n if (!hasComponents) {\r\n throw new Error(`Invalid duration format: \"${value}\"`);\r\n }\r\n\r\n const isNegative = !!match[1];\r\n const sign = isNegative ? -1 : 1;\r\n\r\n return {\r\n negative: isNegative,\r\n years: sign * (parseInt(match[2]) || 0),\r\n months: sign * (parseInt(match[3]) || 0),\r\n days: sign * (parseInt(match[4]) || 0),\r\n hours: sign * (parseInt(match[5]) || 0),\r\n minutes: sign * (parseInt(match[6]) || 0),\r\n seconds: sign * (parseFloat(match[7]) || 0),\r\n };\r\n}\r\n\r\n/**\r\n * Parse ISO 8601 time format\r\n * Format: HH:MM:SS[.SSS][Z|±HH:MM]\r\n */\r\nexport function parseTime(value: string): {\r\n hours: number;\r\n minutes: number;\r\n seconds: number;\r\n timezone?: { sign: string; hours: number; minutes: number };\r\n} {\r\n const match = value.match(/^(\\d{2}):(\\d{2}):(\\d{2}(?:\\.\\d+)?)(?:Z|([+-])(\\d{2}):(\\d{2}))?$/);\r\n\r\n if (!match) {\r\n throw new Error(`Invalid time format: \"${value}\"`);\r\n }\r\n\r\n const hours = parseInt(match[1], 10);\r\n const minutes = parseInt(match[2], 10);\r\n const seconds = parseFloat(match[3]);\r\n\r\n // Validate ranges\r\n if (hours < 0 || hours > 23) {\r\n throw new Error(`Invalid hours value: ${hours}`);\r\n }\r\n if (minutes < 0 || minutes > 59) {\r\n throw new Error(`Invalid minutes value: ${minutes}`);\r\n }\r\n if (seconds < 0 || seconds >= 60) {\r\n throw new Error(`Invalid seconds value: ${seconds}`);\r\n }\r\n\r\n let timezone: { sign: string; hours: number; minutes: number } | undefined;\r\n if (match[4]) {\r\n timezone = {\r\n sign: match[4],\r\n hours: parseInt(match[5], 10),\r\n minutes: parseInt(match[6], 10),\r\n };\r\n }\r\n\r\n return { hours, minutes, seconds, timezone };\r\n}\r\n\r\n/**\r\n * xs:duration - duration values\r\n */\r\nexport class DurationTypeImpl extends AtomicTypeImpl {\r\n constructor(baseType: AtomicType) {\r\n super('duration', XS_NAMESPACE, baseType, undefined);\r\n }\r\n\r\n validate(value: any): boolean {\r\n if (typeof value === 'object' && value !== null && 'years' in value) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n cast(value: any): any {\r\n if (this.validate(value)) return value;\r\n if (typeof value === 'string') {\r\n return parseDuration(value);\r\n }\r\n throw new Error(`Cannot cast ${typeof value} to xs:duration`);\r\n }\r\n}\r\n\r\n/**\r\n * xs:dateTime - date and time combined\r\n */\r\nexport class DateTimeTypeImpl extends AtomicTypeImpl {\r\n constructor(baseType: AtomicType) {\r\n super('dateTime', XS_NAMESPACE, baseType, undefined);\r\n }\r\n\r\n validate(value: any): boolean {\r\n return value instanceof Date;\r\n }\r\n\r\n cast(value: any): Date {\r\n if (value instanceof Date) return value;\r\n if (typeof value === 'string') {\r\n const date = new Date(value);\r\n if (isNaN(date.getTime())) {\r\n throw new Error(`Invalid dateTime value: \"${value}\"`);\r\n }\r\n return date;\r\n }\r\n throw new Error(`Cannot cast ${typeof value} to xs:dateTime`);\r\n }\r\n}\r\n\r\n/**\r\n * xs:date - date values (year-month-day)\r\n */\r\nexport class DateTypeImpl extends AtomicTypeImpl {\r\n constructor(baseType: AtomicType, primitive: AtomicType) {\r\n super('date', XS_NAMESPACE, baseType, primitive);\r\n }\r\n\r\n validate(value: any): boolean {\r\n return value instanceof Date;\r\n }\r\n\r\n cast(value: any): Date {\r\n const dateTime = this.baseType!.cast(value);\r\n const date = new Date(dateTime);\r\n date.setHours(0, 0, 0, 0);\r\n return date;\r\n }\r\n}\r\n\r\n/**\r\n * xs:time - time values (hours-minutes-seconds)\r\n */\r\nexport class TimeTypeImpl extends AtomicTypeImpl {\r\n constructor(baseType: AtomicType, primitive: AtomicType) {\r\n super('time', XS_NAMESPACE, baseType, primitive);\r\n }\r\n\r\n validate(value: any): boolean {\r\n if (typeof value === 'object' && value !== null && 'hours' in value) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n cast(value: any): any {\r\n if (this.validate(value)) return value;\r\n if (typeof value === 'string') {\r\n return parseTime(value);\r\n }\r\n throw new Error(`Cannot cast ${typeof value} to xs:time`);\r\n }\r\n}\r\n","/**\r\n * Gregorian date types: gYearMonth, gYear, gMonthDay, gDay, gMonth\r\n */\r\n\r\nimport { AtomicType, AtomicTypeImpl, XS_NAMESPACE } from './base';\r\n\r\n/**\r\n * xs:gYearMonth - gregorian year and month\r\n */\r\nexport class GYearMonthTypeImpl extends AtomicTypeImpl {\r\n constructor(baseType: AtomicType) {\r\n super('gYearMonth', XS_NAMESPACE, baseType, undefined);\r\n }\r\n\r\n validate(value: any): boolean {\r\n return typeof value === 'object' && value !== null && 'year' in value && 'month' in value;\r\n }\r\n\r\n cast(value: any): any {\r\n if (this.validate(value)) return value;\r\n if (typeof value === 'string') {\r\n // Format: YYYY-MM\r\n const match = value.match(/^(-?\\d{4})-(\\d{2})$/);\r\n if (!match) {\r\n throw new Error(`Invalid gYearMonth format: \"${value}\"`);\r\n }\r\n const year = parseInt(match[1], 10);\r\n const month = parseInt(match[2], 10);\r\n if (month < 1 || month > 12) {\r\n throw new Error(`Invalid month value: ${month}`);\r\n }\r\n return { year, month };\r\n }\r\n throw new Error(`Cannot cast ${typeof value} to xs:gYearMonth`);\r\n }\r\n}\r\n\r\n/**\r\n * xs:gYear - gregorian year\r\n */\r\nexport class GYearTypeImpl extends AtomicTypeImpl {\r\n constructor(baseType: AtomicType) {\r\n super('gYear', XS_NAMESPACE, baseType, undefined);\r\n }\r\n\r\n validate(value: any): boolean {\r\n return typeof value === 'object' && value !== null && 'year' in value;\r\n }\r\n\r\n cast(value: any): any {\r\n if (this.validate(value)) return value;\r\n if (typeof value === 'string') {\r\n // Format: YYYY\r\n const match = value.match(/^(-?\\d{4})$/);\r\n if (!match) {\r\n throw new Error(`Invalid gYear format: \"${value}\"`);\r\n }\r\n return { year: parseInt(match[1], 10) };\r\n }\r\n throw new Error(`Cannot cast ${typeof value} to xs:gYear`);\r\n }\r\n}\r\n\r\n/**\r\n * xs:gMonthDay - gregorian month and day\r\n */\r\nexport class GMonthDayTypeImpl extends AtomicTypeImpl {\r\n constructor(baseType: AtomicType) {\r\n super('gMonthDay', XS_NAMESPACE, baseType, undefined);\r\n }\r\n\r\n validate(value: any): boolean {\r\n return typeof value === 'object' && value !== null && 'month' in value && 'day' in value;\r\n }\r\n\r\n cast(value: any): any {\r\n if (this.validate(value)) return value;\r\n if (typeof value === 'string') {\r\n // Format: --MM-DD\r\n const match = value.match(/^--(\\d{2})-(\\d{2})$/);\r\n if (!match) {\r\n throw new Error(`Invalid gMonthDay format: \"${value}\"`);\r\n }\r\n const month = parseInt(match[1], 10);\r\n const day = parseInt(match[2], 10);\r\n if (month < 1 || month > 12) {\r\n throw new Error(`Invalid month value: ${month}`);\r\n }\r\n if (day < 1 || day > 31) {\r\n throw new Error(`Invalid day value: ${day}`);\r\n }\r\n return { month, day };\r\n }\r\n throw new Error(`Cannot cast ${typeof value} to xs:gMonthDay`);\r\n }\r\n}\r\n\r\n/**\r\n * xs:gDay - gregorian day\r\n */\r\nexport class GDayTypeImpl extends AtomicTypeImpl {\r\n constructor(baseType: AtomicType) {\r\n super('gDay', XS_NAMESPACE, baseType, undefined);\r\n }\r\n\r\n validate(value: any): boolean {\r\n return typeof value === 'object' && value !== null && 'day' in value;\r\n }\r\n\r\n cast(value: any): any {\r\n if (this.validate(value)) return value;\r\n if (typeof value === 'string') {\r\n // Format: ---DD\r\n const match = value.match(/^---(\\d{2})$/);\r\n if (!match) {\r\n throw new Error(`Invalid gDay format: \"${value}\"`);\r\n }\r\n const day = parseInt(match[1], 10);\r\n if (day < 1 || day > 31) {\r\n throw new Error(`Invalid day value: ${day}`);\r\n }\r\n return { day };\r\n }\r\n throw new Error(`Cannot cast ${typeof value} to xs:gDay`);\r\n }\r\n}\r\n\r\n/**\r\n * xs:gMonth - gregorian month\r\n */\r\nexport class GMonthTypeImpl extends AtomicTypeImpl {\r\n constructor(baseType: AtomicType) {\r\n super('gMonth', XS_NAMESPACE, baseType, undefined);\r\n }\r\n\r\n validate(value: any): boolean {\r\n return typeof value === 'object' && value !== null && 'month' in value;\r\n }\r\n\r\n cast(value: any): any {\r\n if (this.validate(value)) return value;\r\n if (typeof value === 'string') {\r\n // Format: --MM\r\n const match = value.match(/^--(\\d{2})$/);\r\n if (!match) {\r\n throw new Error(`Invalid gMonth format: \"${value}\"`);\r\n }\r\n const month = parseInt(match[1], 10);\r\n if (month < 1 || month > 12) {\r\n throw new Error(`Invalid month value: ${month}`);\r\n }\r\n return { month };\r\n }\r\n throw new Error(`Cannot cast ${typeof value} to xs:gMonth`);\r\n }\r\n}\r\n","/**\r\n * Binary types: hexBinary, base64Binary\r\n */\r\n\r\nimport { AtomicType, AtomicTypeImpl, XS_NAMESPACE } from './base';\r\n\r\n/**\r\n * xs:hexBinary - hex-encoded binary data\r\n */\r\nexport class HexBinaryTypeImpl extends AtomicTypeImpl {\r\n constructor(baseType: AtomicType) {\r\n super('hexBinary', XS_NAMESPACE, baseType, undefined);\r\n }\r\n\r\n validate(value: any): boolean {\r\n if (typeof value === 'string') {\r\n return /^[0-9A-Fa-f]*$/.test(value) && value.length % 2 === 0;\r\n }\r\n return value instanceof Uint8Array;\r\n }\r\n\r\n cast(value: any): string {\r\n if (typeof value === 'string') {\r\n if (!this.validate(value)) {\r\n throw new Error(`Invalid hexBinary format: \"${value}\"`);\r\n }\r\n return value.toUpperCase();\r\n }\r\n if (value instanceof Uint8Array) {\r\n return Array.from(value)\r\n .map((b) => b.toString(16).padStart(2, '0'))\r\n .join('')\r\n .toUpperCase();\r\n }\r\n throw new Error(`Cannot cast ${typeof value} to xs:hexBinary`);\r\n }\r\n}\r\n\r\n/**\r\n * xs:base64Binary - base64-encoded binary data\r\n */\r\nexport class Base64BinaryTypeImpl extends AtomicTypeImpl {\r\n constructor(baseType: AtomicType) {\r\n super('base64Binary', XS_NAMESPACE, baseType, undefined);\r\n }\r\n\r\n validate(value: any): boolean {\r\n if (typeof value === 'string') {\r\n return /^[A-Za-z0-9+/]*={0,2}$/.test(value) && value.length % 4 === 0;\r\n }\r\n return value instanceof Uint8Array;\r\n }\r\n\r\n cast(value: any): string {\r\n if (typeof value === 'string') {\r\n if (!this.validate(value)) {\r\n throw new Error(`Invalid base64Binary format: \"${value}\"`);\r\n }\r\n return value;\r\n }\r\n if (value instanceof Uint8Array) {\r\n // Simple base64 encoding\r\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\r\n let result = '';\r\n let i = 0;\r\n const len = value.length;\r\n\r\n while (i < len) {\r\n const a = value[i++];\r\n const hasB = i < len;\r\n const b = hasB ? value[i++] : 0;\r\n const hasC = i < len;\r\n const c = hasC ? value[i++] : 0;\r\n\r\n const bitmap = (a << 16) | (b << 8) | c;\r\n\r\n result += chars[(bitmap >> 18) & 0x3f];\r\n result += chars[(bitmap >> 12) & 0x3f];\r\n result += hasB ? chars[(bitmap >> 6) & 0x3f] : '=';\r\n result += hasC ? chars[bitmap & 0x3f] : '=';\r\n }\r\n\r\n return result;\r\n }\r\n throw new Error(`Cannot cast ${typeof value} to xs:base64Binary`);\r\n }\r\n}\r\n\r\n/**\r\n * Utility functions for binary data encoding/decoding\r\n */\r\n\r\n/**\r\n * Decode hex string to Uint8Array\r\n */\r\nexport function hexToBytes(hex: string): Uint8Array {\r\n if (hex.length % 2 !== 0) {\r\n throw new Error('Hex string must have even length');\r\n }\r\n\r\n const bytes = new Uint8Array(hex.length / 2);\r\n for (let i = 0; i < hex.length; i += 2) {\r\n bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);\r\n }\r\n return bytes;\r\n}\r\n\r\n/**\r\n * Encode Uint8Array to hex string\r\n */\r\nexport function bytesToHex(bytes: Uint8Array): string {\r\n return Array.from(bytes)\r\n .map((b) => b.toString(16).padStart(2, '0'))\r\n .join('')\r\n .toUpperCase();\r\n}\r\n\r\n/**\r\n * Decode base64 string to Uint8Array\r\n */\r\nexport function base64ToBytes(base64: string): Uint8Array {\r\n // Remove whitespace\r\n base64 = base64.replace(/\\s/g, '');\r\n\r\n // Validate\r\n if (!/^[A-Za-z0-9+/]*={0,2}$/.test(base64) || base64.length % 4 !== 0) {\r\n throw new Error('Invalid base64 string');\r\n }\r\n\r\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\r\n const lookup: { [key: string]: number } = {};\r\n for (let i = 0; i < chars.length; i++) {\r\n lookup[chars[i]] = i;\r\n }\r\n\r\n const len = base64.length;\r\n const padding = base64.endsWith('==') ? 2 : base64.endsWith('=') ? 1 : 0;\r\n const byteCount = (len / 4) * 3 - padding;\r\n const bytes = new Uint8Array(byteCount);\r\n\r\n let byteIndex = 0;\r\n for (let i = 0; i < len; i += 4) {\r\n const encoded1 = lookup[base64[i]];\r\n const encoded2 = lookup[base64[i + 1]];\r\n const encoded3 = base64[i + 2] === '=' ? 0 : lookup[base64[i + 2]];\r\n const encoded4 = base64[i + 3] === '=' ? 0 : lookup[base64[i + 3]];\r\n\r\n bytes[byteIndex++] = (encoded1 << 2) | (encoded2 >> 4);\r\n if (base64[i + 2] !== '=') {\r\n bytes[byteIndex++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);\r\n }\r\n if (base64[i + 3] !== '=') {\r\n bytes[byteIndex++] = ((encoded3 & 3) << 6) | encoded4;\r\n }\r\n }\r\n\r\n return bytes;\r\n}\r\n\r\n/**\r\n * Encode Uint8Array to base64 string\r\n */\r\nexport function bytesToBase64(bytes: Uint8Array): string {\r\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\r\n let result = '';\r\n let i = 0;\r\n const len = bytes.length;\r\n\r\n while (i < len) {\r\n const a = bytes[i++];\r\n const hasB = i < len;\r\n const b = hasB ? bytes[i++] : 0;\r\n const hasC = i < len;\r\n const c = hasC ? bytes[i++] : 0;\r\n\r\n const bitmap = (a << 16) | (b << 8) | c;\r\n\r\n result += chars[(bitmap >> 18) & 0x3f];\r\n result += chars[(bitmap >> 12) & 0x3f];\r\n result += hasB ? chars[(bitmap >> 6) & 0x3f] : '=';\r\n result += hasC ? chars[bitmap & 0x3f] : '=';\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Convert string to Uint8Array using UTF-8 encoding\r\n */\r\nexport function stringToBytes(str: string): Uint8Array {\r\n const encoder = new TextEncoder();\r\n return encoder.encode(str);\r\n}\r\n\r\n/**\r\n * Convert Uint8Array to string using UTF-8 decoding\r\n */\r\nexport function bytesToString(bytes: Uint8Array): string {\r\n const decoder = new TextDecoder();\r\n return decoder.decode(bytes);\r\n}\r\n","/**\r\n * URI and QName types: anyURI, QName\r\n */\r\n\r\nimport { AtomicType, AtomicTypeImpl, XS_NAMESPACE } from './base';\r\n\r\n/**\r\n * xs:anyURI - Uniform Resource Identifier\r\n */\r\nexport class AnyURITypeImpl extends AtomicTypeImpl {\r\n constructor(baseType: AtomicType) {\r\n super('anyURI', XS_NAMESPACE, baseType, undefined);\r\n }\r\n\r\n validate(value: any): boolean {\r\n return typeof value === 'string';\r\n }\r\n\r\n cast(value: any): string {\r\n if (typeof value === 'string') return value;\r\n throw new Error(`Cannot cast ${typeof value} to xs:anyURI`);\r\n }\r\n}\r\n\r\n/**\r\n * xs:QName - qualified name\r\n */\r\nexport class QNameTypeImpl extends AtomicTypeImpl {\r\n constructor(baseType: AtomicType) {\r\n super('QName', XS_NAMESPACE, baseType, undefined);\r\n }\r\n\r\n validate(value: any): boolean {\r\n return (\r\n typeof value === 'object' &&\r\n value !== null &&\r\n 'localName' in value &&\r\n 'namespaceURI' in value\r\n );\r\n }\r\n\r\n cast(value: any): any {\r\n if (this.validate(value)) return value;\r\n if (typeof value === 'string') {\r\n // Simple parsing: prefix:localName\r\n const parts = value.split(':');\r\n if (parts.length === 1) {\r\n return { localName: parts[0], namespaceURI: '', prefix: undefined };\r\n }\r\n if (parts.length === 2) {\r\n return { localName: parts[1], namespaceURI: '', prefix: parts[0] };\r\n }\r\n }\r\n throw new Error(`Cannot cast ${typeof value} to xs:QName`);\r\n }\r\n}\r\n","/**\r\n * Integer-derived types: long, int, short, byte, unsigned*, nonPositiveInteger, etc.\r\n */\r\n\r\nimport { AtomicType, AtomicTypeImpl, XS_NAMESPACE } from './base';\r\n\r\n/**\r\n * Integer-derived type with range validation\r\n */\r\nexport class IntegerDerivedTypeImpl extends AtomicTypeImpl {\r\n constructor(\r\n name: string,\r\n baseType: AtomicType,\r\n primitive: AtomicType,\r\n private min?: number,\r\n private max?: number\r\n ) {\r\n super(name, XS_NAMESPACE, baseType, primitive);\r\n }\r\n\r\n validate(value: any): boolean {\r\n if (\r\n typeof value !== 'number' ||\r\n !Number.isInteger(value) ||\r\n !isFinite(value) ||\r\n !Number.isSafeInteger(value)\r\n ) {\r\n return false;\r\n }\r\n if (this.min !== undefined && value < this.min) return false;\r\n if (this.max !== undefined && value > this.max) return false;\r\n return true;\r\n }\r\n\r\n cast(value: any): number {\r\n const num = this.baseType!.cast(value);\r\n if (!Number.isSafeInteger(num)) {\r\n throw new Error(`Value ${num} is not a safe integer for ${this.name}`);\r\n }\r\n if (this.min !== undefined && num < this.min) {\r\n throw new Error(`Value ${num} is below minimum ${this.min} for ${this.name}`);\r\n }\r\n if (this.max !== undefined && num > this.max) {\r\n throw new Error(`Value ${num} is above maximum ${this.max} for ${this.name}`);\r\n }\r\n return num;\r\n }\r\n}\r\n","/**\r\n * XPath 3.0 Function Type System\r\n *\r\n * In XPath 3.0, functions are first-class values that can be:\r\n * - Passed as arguments to other functions\r\n * - Returned from functions\r\n * - Stored in variables\r\n * - Created as anonymous inline functions\r\n *\r\n * Reference: https://www.w3.org/TR/xpath-30/#id-function-item-types\r\n */\r\n\r\nimport { ItemType, SequenceType } from './sequence-type';\r\n\r\n/**\r\n * Represents the type signature of a function.\r\n */\r\nexport interface FunctionType {\r\n kind: 'function';\r\n /** Types of the function parameters */\r\n parameterTypes: SequenceType[];\r\n /** Return type of the function */\r\n returnType: SequenceType;\r\n /** Number of parameters (arity) */\r\n arity: number;\r\n}\r\n\r\n/**\r\n * Represents a function item - a first-class function value in XPath 3.0.\r\n *\r\n * Function items can be:\r\n * - Named functions obtained via function references (fn:upper-case#1)\r\n * - Anonymous inline functions (function($x) { $x + 1 })\r\n * - Partially applied functions\r\n *\r\n * This interface extends XPathFunctionItem from context.ts to ensure\r\n * FunctionItem values are valid XPathResult values.\r\n */\r\nexport interface FunctionItem {\r\n /** Marker to identify this as a function item */\r\n __isFunctionItem: true;\r\n /** The type signature of the function */\r\n type?: FunctionType;\r\n /** The actual implementation */\r\n implementation: (...args: any[]) => any;\r\n /** Function name (undefined for anonymous functions) */\r\n name?: string;\r\n /** Namespace URI for named functions */\r\n namespace?: string;\r\n /** Number of parameters */\r\n arity: number;\r\n /** Captured closure context for inline functions */\r\n closureContext?: Record<string, any>;\r\n}\r\n\r\n/**\r\n * Function test item type (e.g., function(*)) for sequence type matching.\r\n */\r\nexport interface FunctionTestItemType extends ItemType {\r\n /** Marker to identify this as a function() test */\r\n readonly isFunctionTest: true;\r\n /** Parameter type constraints (undefined/null means wildcard) */\r\n readonly parameterTypes?: SequenceType[] | null;\r\n /** Return type constraint (undefined/null means wildcard) */\r\n readonly returnType?: SequenceType | null;\r\n /** Whether this is the wildcard function(*) test */\r\n readonly isWildcard: boolean;\r\n}\r\n\r\n/**\r\n * Create a function item from an implementation.\r\n */\r\nexport function createFunctionItem(\r\n implementation: (...args: any[]) => any,\r\n arity: number,\r\n name?: string,\r\n namespace?: string,\r\n type?: FunctionType\r\n): FunctionItem {\r\n return {\r\n __isFunctionItem: true,\r\n implementation,\r\n arity,\r\n name,\r\n namespace,\r\n type,\r\n };\r\n}\r\n\r\n/**\r\n * Create a function() type test (supports function(*) wildcard).\r\n */\r\nexport function createFunctionTest(\r\n parameterTypes: SequenceType[] | null = null,\r\n returnType: SequenceType | null = null,\r\n opts?: { isWildcard?: boolean }\r\n): FunctionTestItemType {\r\n const isWildcard = opts?.isWildcard ?? (parameterTypes === null && returnType === null);\r\n const paramCount = Array.isArray(parameterTypes) ? parameterTypes.length : undefined;\r\n\r\n const typeName = isWildcard\r\n ? 'function(*)'\r\n : `function(${parameterTypes?.map((p) => p.toString()).join(', ') ?? ''})` +\r\n (returnType ? ` as ${returnType.toString()}` : '');\r\n\r\n return {\r\n name: typeName,\r\n isFunctionTest: true,\r\n isWildcard,\r\n parameterTypes: parameterTypes ?? undefined,\r\n returnType: returnType ?? undefined,\r\n matches(value: any): boolean {\r\n if (value === null || value === undefined) {\r\n return false;\r\n }\r\n\r\n const isFunctionItemLike =\r\n (typeof value === 'object' && value.__isFunctionItem === true) ||\r\n typeof value === 'function';\r\n\r\n // Maps and arrays are function items in XPath 3.1\r\n const isTypedMap = typeof value === 'object' && value?.__isMap === true;\r\n const isTypedArray = typeof value === 'object' && value?.__isArray === true;\r\n\r\n if (!isFunctionItemLike && !isTypedMap && !isTypedArray) {\r\n return false;\r\n }\r\n\r\n if (isWildcard) {\r\n return true;\r\n }\r\n\r\n // If we have parameter types, enforce arity equality when we can observe it\r\n if (paramCount !== undefined) {\r\n const observedArity =\r\n isTypedMap || isTypedArray\r\n ? 1\r\n : typeof value === 'function'\r\n ? value.length\r\n : typeof value?.arity === 'number'\r\n ? value.arity\r\n : undefined;\r\n\r\n if (observedArity !== undefined && observedArity !== paramCount) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Check if a value is a function item.\r\n */\r\nexport function isFunctionItem(value: any): value is FunctionItem {\r\n return value && typeof value === 'object' && value.__isFunctionItem === true;\r\n}\r\n\r\n/**\r\n * Create a function type from parameter and return types.\r\n */\r\nexport function createFunctionType(\r\n parameterTypes: SequenceType[],\r\n returnType: SequenceType\r\n): FunctionType {\r\n return {\r\n kind: 'function',\r\n parameterTypes,\r\n returnType,\r\n arity: parameterTypes.length,\r\n };\r\n}\r\n\r\n/**\r\n * Get a string representation of a function type.\r\n */\r\nexport function describeFunctionType(type: FunctionType): string {\r\n const params = type.parameterTypes.map((p) => String(p)).join(', ');\r\n return `function(${params}) as ${type.returnType}`;\r\n}\r\n\r\n/**\r\n * Default function namespace (fn)\r\n */\r\nexport const FN_NAMESPACE = 'http://www.w3.org/2005/xpath-functions';\r\n\r\n/**\r\n * Math function namespace\r\n */\r\nexport const MATH_NAMESPACE = 'http://www.w3.org/2005/xpath-functions/math';\r\n\r\n/**\r\n * Map function namespace (XPath 3.1)\r\n */\r\nexport const MAP_NAMESPACE = 'http://www.w3.org/2005/xpath-functions/map';\r\n\r\n/**\r\n * Array function namespace (XPath 3.1)\r\n */\r\nexport const ARRAY_NAMESPACE = 'http://www.w3.org/2005/xpath-functions/array';\r\n","/**\r\n * PSVI (Post-Schema-Validation Infoset) Support\r\n *\r\n * Implements type information attached to nodes after schema validation\r\n * Per XPath 2.0 Section 2.3.4\r\n */\r\n\r\nimport { XPathNode } from '../types/index';\r\nimport { SchemaType } from './validator';\r\n\r\n/**\r\n * PSVI information for a node\r\n */\r\nexport interface PSVI {\r\n // Schema-related properties\r\n schemaType?: SchemaType;\r\n schemaTypeName?: string;\r\n schemaElement?: string;\r\n schemaAttribute?: string;\r\n schemaTypeNamespace?: string;\r\n\r\n // Validation properties\r\n isValid: boolean;\r\n validationErrors: string[];\r\n\r\n // Type information\r\n typedValue?: any;\r\n typeCode?: string;\r\n\r\n // Ancestry information\r\n ancestry?: {\r\n parent?: PSVI;\r\n elementDeclaration?: string;\r\n };\r\n\r\n // Content model\r\n isNilled: boolean;\r\n contentType?: 'empty' | 'simple' | 'complex' | 'mixed';\r\n\r\n // Default/fixed values\r\n defaultValue?: string;\r\n fixedValue?: string;\r\n\r\n // Substitution information\r\n substitutionGroup?: string;\r\n isSubstitutableFor?: string;\r\n}\r\n\r\n/**\r\n * PSVI symbol for storing type information on nodes\r\n */\r\nconst PSVI_SYMBOL = Symbol.for('__xpath_psvi__');\r\n\r\n/**\r\n * Set PSVI information on a node\r\n */\r\nexport function setPSVI(node: XPathNode, psvi: PSVI): void {\r\n if (node && typeof node === 'object') {\r\n (node as any)[PSVI_SYMBOL] = psvi;\r\n }\r\n}\r\n\r\n/**\r\n * Get PSVI information from a node\r\n */\r\nexport function getPSVI(node: XPathNode): PSVI | undefined {\r\n if (node && typeof node === 'object') {\r\n return (node as any)[PSVI_SYMBOL];\r\n }\r\n return undefined;\r\n}\r\n\r\n/**\r\n * Check if node has PSVI information\r\n */\r\nexport function hasPSVI(node: XPathNode): boolean {\r\n return getPSVI(node) !== undefined;\r\n}\r\n\r\n/**\r\n * Get schema type of a node\r\n */\r\nexport function getSchemaType(node: XPathNode): SchemaType | undefined {\r\n const psvi = getPSVI(node);\r\n return psvi?.schemaType;\r\n}\r\n\r\n/**\r\n * Get schema type name of a node\r\n */\r\nexport function getSchemaTypeName(node: XPathNode): string | undefined {\r\n const psvi = getPSVI(node);\r\n return psvi?.schemaTypeName || psvi?.schemaType?.name;\r\n}\r\n\r\n/**\r\n * Check if node is schema-valid\r\n */\r\nexport function isSchemaValid(node: XPathNode): boolean {\r\n const psvi = getPSVI(node);\r\n return psvi?.isValid ?? true; // Default to valid if no PSVI\r\n}\r\n\r\n/**\r\n * Get schema validation errors\r\n */\r\nexport function getValidationErrors(node: XPathNode): string[] {\r\n const psvi = getPSVI(node);\r\n return psvi?.validationErrors ?? [];\r\n}\r\n\r\n/**\r\n * Get typed value of a node\r\n */\r\nexport function getTypedValue(node: XPathNode): any {\r\n const psvi = getPSVI(node);\r\n if (psvi?.typedValue !== undefined) {\r\n return psvi.typedValue;\r\n }\r\n\r\n // Fall back to string value\r\n return getStringValue(node);\r\n}\r\n\r\n/**\r\n * Get string value of a node\r\n */\r\nfunction getStringValue(node: XPathNode): string {\r\n if (node.nodeType === 'text' || node.nodeType === '3') {\r\n // Text node\r\n return node.value || (node as any).nodeValue || '';\r\n }\r\n if (node.nodeType === 'element' || node.nodeType === '1') {\r\n // Element node - concatenate all text descendants\r\n if (node.childNodes) {\r\n return node.childNodes\r\n .map((child) => getStringValue(child))\r\n .join('');\r\n }\r\n }\r\n return node.value || (node as any).nodeValue || '';\r\n}\r\n\r\n/**\r\n * Get content type of a node\r\n */\r\nexport function getContentType(node: XPathNode): string | undefined {\r\n const psvi = getPSVI(node);\r\n return psvi?.contentType;\r\n}\r\n\r\n/**\r\n * Check if node is nilled\r\n */\r\nexport function isNilled(node: XPathNode): boolean {\r\n const psvi = getPSVI(node);\r\n if (psvi?.isNilled) {\r\n return true;\r\n }\r\n\r\n // Check xsi:nil attribute\r\n if ((node.nodeType === 'element' || node.nodeType === '1') && node.attributes) {\r\n const nilAttrs = Object.entries(node.attributes);\r\n const nilAttr = nilAttrs.find(\r\n ([name, value]) =>\r\n name.endsWith('}nil') || name === 'xsi:nil' || name === 'nil'\r\n );\r\n if (nilAttr) {\r\n return String(nilAttr[1]).toLowerCase() === 'true';\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Create default PSVI for unvalidated node\r\n */\r\nexport function createDefaultPSVI(node: XPathNode): PSVI {\r\n return {\r\n isValid: true,\r\n validationErrors: [],\r\n isNilled: isNilled(node),\r\n contentType: getNodeContentType(node),\r\n };\r\n}\r\n\r\n/**\r\n * Determine content type from node structure\r\n */\r\nfunction getNodeContentType(node: XPathNode): 'empty' | 'simple' | 'complex' | 'mixed' {\r\n if (node.nodeType !== 'element' && node.nodeType !== '1') {\r\n return 'simple';\r\n }\r\n\r\n if (!node.childNodes || node.childNodes.length === 0) {\r\n return 'empty';\r\n }\r\n\r\n const hasElementChildren = node.childNodes.some((child) => child.nodeType === 'element' || child.nodeType === '1');\r\n const hasTextChildren = node.childNodes.some((child) => child.nodeType === 'text' || child.nodeType === '3');\r\n\r\n if (hasElementChildren && hasTextChildren) {\r\n return 'mixed';\r\n }\r\n if (hasElementChildren) {\r\n return 'complex';\r\n }\r\n return 'simple';\r\n}\r\n\r\n/**\r\n * Attach PSVI information to node tree\r\n */\r\nexport function attachPSVIToTree(rootNode: XPathNode, psviMap: Map<XPathNode, PSVI>): void {\r\n const psviArray = Array.from(psviMap);\r\n for (const [node, psvi] of psviArray) {\r\n setPSVI(node, psvi);\r\n }\r\n}\r\n\r\n/**\r\n * Extract PSVI information from node tree\r\n */\r\nexport function extractPSVIFromTree(rootNode: XPathNode): Map<XPathNode, PSVI> {\r\n const psviMap = new Map<XPathNode, PSVI>();\r\n const visited = new Set<XPathNode>();\r\n\r\n function traverse(node: XPathNode): void {\r\n if (visited.has(node)) {\r\n return;\r\n }\r\n visited.add(node);\r\n\r\n const psvi = getPSVI(node);\r\n if (psvi) {\r\n psviMap.set(node, psvi);\r\n }\r\n\r\n if (node.childNodes) {\r\n for (const child of node.childNodes) {\r\n traverse(child);\r\n }\r\n }\r\n }\r\n\r\n traverse(rootNode);\r\n return psviMap;\r\n}\r\n\r\n/**\r\n * Clear PSVI information from node tree\r\n */\r\nexport function clearPSVIFromTree(rootNode: XPathNode): void {\r\n const visited = new Set<XPathNode>();\r\n\r\n function traverse(node: XPathNode): void {\r\n if (visited.has(node)) {\r\n return;\r\n }\r\n visited.add(node);\r\n\r\n if (node && typeof node === 'object') {\r\n delete (node as any)[PSVI_SYMBOL];\r\n }\r\n\r\n if (node.childNodes) {\r\n for (const child of node.childNodes) {\r\n traverse(child);\r\n }\r\n }\r\n }\r\n\r\n traverse(rootNode);\r\n}\r\n","/**\r\n * Schema-Aware Type System\r\n *\r\n * Type annotations and checking that consider schema information\r\n * Implements XPath 2.0 schema-aware processing\r\n */\r\n\r\nimport { SchemaType, ElementDeclaration, AttributeDeclaration } from '../schema/validator';\r\nimport { XPathNode } from './index';\r\nimport { getPSVI, getSchemaType, getTypedValue } from '../schema/psvi';\r\n\r\n/**\r\n * Schema-aware type representation\r\n */\r\nexport interface SchemaAwareType {\r\n // Base type information\r\n name: string;\r\n namespace?: string;\r\n\r\n // Type hierarchy\r\n baseType?: SchemaAwareType;\r\n derivedTypes?: SchemaAwareType[];\r\n\r\n // Type properties\r\n isAtomic: boolean;\r\n isUnion: boolean;\r\n isList: boolean;\r\n isBuiltIn: boolean;\r\n\r\n // Restriction facets\r\n enumeration?: string[];\r\n minInclusive?: number | string;\r\n maxInclusive?: number | string;\r\n pattern?: string;\r\n minLength?: number;\r\n maxLength?: number;\r\n\r\n // Element/attribute declarations\r\n elementDeclarations?: Map<string, ElementDeclaration>;\r\n attributeDeclarations?: Map<string, AttributeDeclaration>;\r\n}\r\n\r\n/**\r\n * Schema-aware type information for expression result\r\n */\r\nexport interface SchemaAwareTypeInfo {\r\n type: SchemaAwareType;\r\n occurrence: 'one' | 'zero_or_one' | 'zero_or_more' | 'one_or_more';\r\n isNilled: boolean;\r\n}\r\n\r\n/**\r\n * Map of built-in types\r\n */\r\nconst BUILTIN_TYPES: Map<string, SchemaAwareType> = new Map([\r\n [\r\n 'string',\r\n {\r\n name: 'string',\r\n namespace: 'http://www.w3.org/2001/XMLSchema',\r\n isAtomic: true,\r\n isUnion: false,\r\n isList: false,\r\n isBuiltIn: true,\r\n },\r\n ],\r\n [\r\n 'integer',\r\n {\r\n name: 'integer',\r\n namespace: 'http://www.w3.org/2001/XMLSchema',\r\n isAtomic: true,\r\n isUnion: false,\r\n isList: false,\r\n isBuiltIn: true,\r\n },\r\n ],\r\n [\r\n 'decimal',\r\n {\r\n name: 'decimal',\r\n namespace: 'http://www.w3.org/2001/XMLSchema',\r\n isAtomic: true,\r\n isUnion: false,\r\n isList: false,\r\n isBuiltIn: true,\r\n },\r\n ],\r\n [\r\n 'boolean',\r\n {\r\n name: 'boolean',\r\n namespace: 'http://www.w3.org/2001/XMLSchema',\r\n isAtomic: true,\r\n isUnion: false,\r\n isList: false,\r\n isBuiltIn: true,\r\n },\r\n ],\r\n [\r\n 'date',\r\n {\r\n name: 'date',\r\n namespace: 'http://www.w3.org/2001/XMLSchema',\r\n isAtomic: true,\r\n isUnion: false,\r\n isList: false,\r\n isBuiltIn: true,\r\n },\r\n ],\r\n [\r\n 'dateTime',\r\n {\r\n name: 'dateTime',\r\n namespace: 'http://www.w3.org/2001/XMLSchema',\r\n isAtomic: true,\r\n isUnion: false,\r\n isList: false,\r\n isBuiltIn: true,\r\n },\r\n ],\r\n]);\r\n\r\n/**\r\n * Get schema-aware type for a value\r\n */\r\nexport function getSchemaAwareType(value: any): SchemaAwareType | null {\r\n // If value is a schema-validated node, get its type\r\n if (value && typeof value === 'object' && 'nodeType' in value) {\r\n const node = value as XPathNode;\r\n const schemaType = getSchemaType(node);\r\n if (schemaType) {\r\n return schemaTypeToSchemaAwareType(schemaType);\r\n }\r\n }\r\n\r\n // Otherwise infer from value\r\n if (typeof value === 'string') {\r\n return BUILTIN_TYPES.get('string') || null;\r\n }\r\n if (typeof value === 'number') {\r\n return Number.isInteger(value)\r\n ? BUILTIN_TYPES.get('integer') || null\r\n : BUILTIN_TYPES.get('decimal') || null;\r\n }\r\n if (typeof value === 'boolean') {\r\n return BUILTIN_TYPES.get('boolean') || null;\r\n }\r\n if (value instanceof Date) {\r\n return BUILTIN_TYPES.get('dateTime') || null;\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Convert schema type to schema-aware type\r\n */\r\nfunction schemaTypeToSchemaAwareType(schemaType: SchemaType): SchemaAwareType {\r\n return {\r\n name: schemaType.name,\r\n namespace: schemaType.namespace,\r\n isAtomic: !schemaType.extension,\r\n isUnion: false,\r\n isList: false,\r\n isBuiltIn: false,\r\n enumeration: schemaType.restriction?.enumeration,\r\n minInclusive: schemaType.restriction?.minInclusive,\r\n maxInclusive: schemaType.restriction?.maxInclusive,\r\n pattern: schemaType.restriction?.pattern,\r\n minLength: schemaType.restriction?.minLength,\r\n maxLength: schemaType.restriction?.maxLength,\r\n };\r\n}\r\n\r\n/**\r\n * Check type compatibility\r\n */\r\nexport function isTypeCompatible(\r\n valueType: SchemaAwareType | null,\r\n expectedType: SchemaAwareType\r\n): boolean {\r\n if (!valueType) {\r\n return false;\r\n }\r\n\r\n // Same type\r\n if (valueType.name === expectedType.name && valueType.namespace === expectedType.namespace) {\r\n return true;\r\n }\r\n\r\n // Check base types\r\n let current = valueType.baseType;\r\n while (current) {\r\n if (current.name === expectedType.name && current.namespace === expectedType.namespace) {\r\n return true;\r\n }\r\n current = current.baseType;\r\n }\r\n\r\n // Type promotion rules\r\n if (isNumericType(valueType) && isNumericType(expectedType)) {\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Check if type is numeric\r\n */\r\nfunction isNumericType(type: SchemaAwareType): boolean {\r\n const numericTypes = ['decimal', 'integer', 'float', 'double', 'long', 'int', 'short'];\r\n return numericTypes.includes(type.name);\r\n}\r\n\r\n/**\r\n * Validate value against schema-aware type\r\n */\r\nexport function validateValueAgainstType(value: any, type: SchemaAwareType): boolean {\r\n // Check enumeration\r\n if (type.enumeration && !type.enumeration.includes(String(value))) {\r\n return false;\r\n }\r\n\r\n // Check numeric constraints\r\n if (type.minInclusive !== undefined && Number(value) < Number(type.minInclusive)) {\r\n return false;\r\n }\r\n if (type.maxInclusive !== undefined && Number(value) > Number(type.maxInclusive)) {\r\n return false;\r\n }\r\n\r\n // Check string constraints\r\n const strValue = String(value);\r\n if (type.minLength !== undefined && strValue.length < type.minLength) {\r\n return false;\r\n }\r\n if (type.maxLength !== undefined && strValue.length > type.maxLength) {\r\n return false;\r\n }\r\n\r\n // Check pattern\r\n if (type.pattern) {\r\n const pattern = new RegExp(type.pattern);\r\n if (!pattern.test(strValue)) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n\r\n/**\r\n * Get typed value of node\r\n */\r\nexport function getNodeTypedValue(node: XPathNode): any {\r\n const psvi = getPSVI(node);\r\n if (psvi?.typedValue !== undefined) {\r\n return psvi.typedValue;\r\n }\r\n\r\n // Get default typed value based on schema type\r\n const schemaType = getSchemaType(node);\r\n if (schemaType) {\r\n const stringValue = getNodeStringValue(node);\r\n\r\n // Convert to appropriate type\r\n if (schemaType.name === 'boolean') {\r\n return stringValue.toLowerCase() === 'true';\r\n }\r\n if (schemaType.name === 'integer') {\r\n return parseInt(stringValue, 10);\r\n }\r\n if (schemaType.name === 'decimal' || schemaType.name === 'float' || schemaType.name === 'double') {\r\n return parseFloat(stringValue);\r\n }\r\n }\r\n\r\n return getTypedValue(node);\r\n}\r\n\r\n/**\r\n * Get string value of node\r\n */\r\nfunction getNodeStringValue(node: XPathNode): string {\r\n if (node.nodeType === 'text' || node.nodeType === '3') {\r\n return node.value || (node as any).nodeValue || '';\r\n }\r\n if ((node.nodeType === 'element' || node.nodeType === '1') && node.childNodes) {\r\n return node.childNodes\r\n .map((child) => getNodeStringValue(child))\r\n .join('');\r\n }\r\n return '';\r\n}\r\n\r\n/**\r\n * Create union type\r\n */\r\nexport function createUnionType(memberTypes: SchemaAwareType[]): SchemaAwareType {\r\n return {\r\n name: 'union',\r\n isAtomic: false,\r\n isUnion: true,\r\n isList: false,\r\n isBuiltIn: false,\r\n };\r\n}\r\n\r\n/**\r\n * Create list type\r\n */\r\nexport function createListType(itemType: SchemaAwareType): SchemaAwareType {\r\n return {\r\n name: `list_of_${itemType.name}`,\r\n isAtomic: false,\r\n isUnion: false,\r\n isList: true,\r\n isBuiltIn: false,\r\n };\r\n}\r\n\r\n/**\r\n * Get built-in type by name\r\n */\r\nexport function getBuiltInType(name: string): SchemaAwareType | null {\r\n return BUILTIN_TYPES.get(name) || null;\r\n}\r\n\r\n/**\r\n * Register custom type\r\n */\r\nexport function registerType(type: SchemaAwareType): void {\r\n const key = type.namespace ? `{${type.namespace}}${type.name}` : type.name;\r\n // Store in custom types (would be a separate map in production)\r\n}\r\n","/**\r\n * XPath 2.0 Atomic Types & SequenceType System Implementation\r\n * Provides the complete set of built-in atomic types as defined in W3C XML Schema Part 2\r\n * and the SequenceType system for sequence matching and cardinality checking\r\n */\r\n\r\n// Re-export base types and interfaces\r\nexport { AtomicType, XS_NAMESPACE, xsType } from './base';\r\nexport { AtomicTypeImpl } from './base';\r\n\r\n// Re-export SequenceType system\r\nexport {\r\n SequenceType,\r\n OccurrenceIndicator,\r\n ItemType,\r\n KindTest,\r\n ITEM_TYPE,\r\n createEmptySequenceType,\r\n createItemSequenceType,\r\n createAtomicSequenceType,\r\n} from './sequence-type';\r\n\r\n// Re-export KindTest implementations\r\nexport {\r\n NodeKindTest,\r\n ElementTest,\r\n AttributeTest,\r\n DocumentNodeTest,\r\n TextTest,\r\n CommentTest,\r\n ProcessingInstructionTest,\r\n SchemaElementTest,\r\n SchemaAttributeTest,\r\n KIND_TESTS,\r\n createElement,\r\n createAttribute,\r\n createDocumentNode,\r\n createProcessingInstruction,\r\n createSchemaElement,\r\n createSchemaAttribute,\r\n} from './kind-tests';\r\n\r\n// Re-export SequenceType matching functions\r\nexport {\r\n matchesSequenceType,\r\n matchesItemType,\r\n matches,\r\n findMismatch,\r\n countMatches,\r\n atomicTypeSatisfies,\r\n describeSequenceType,\r\n isSingleItem,\r\n isValidSequence,\r\n toSequence,\r\n itemTypesEquivalent,\r\n sequenceTypesEquivalent,\r\n MatchResult,\r\n} from './sequence-type-matcher';\r\n\r\n// Re-export Typed Collection Types (XPath 3.1)\r\nexport {\r\n TypedMapItemType,\r\n TypedArrayItemType,\r\n createTypedMapTest,\r\n createTypedArrayTest,\r\n isTypedMapTest,\r\n isTypedArrayTest,\r\n} from './typed-collection-types';\r\n\r\n// Re-export Union Types (XPath 3.1 Extension)\r\nexport { UnionItemType, createUnionType, isUnionType } from './union-type';\r\n\r\n// Re-export Type Promotion system\r\nexport {\r\n NumericTypeHierarchy,\r\n getNumericHierarchyLevel,\r\n canPromoteNumeric,\r\n promoteNumericValue,\r\n getCommonNumericType,\r\n canPromoteToString,\r\n promoteToString,\r\n promoteUntypedToNumeric,\r\n PromotionContext,\r\n promoteInContext,\r\n describePromotion,\r\n} from './type-promotion';\r\n\r\n// Re-export Atomization system\r\nexport {\r\n atomize,\r\n atomizeToSingleValue,\r\n extractStringValues,\r\n atomizationToSequence,\r\n isAtomizationSuccess,\r\n getAtomizationErrorDescription,\r\n isNode,\r\n hasElementOnlyContent,\r\n getNodeTypedValue,\r\n getNodeStringValue,\r\n createTestNode,\r\n createElementWithText,\r\n createElementWithChildren,\r\n AtomizationResult,\r\n XPathNode,\r\n} from './atomization';\r\n\r\n// Re-export all type implementations\r\nexport {\r\n AnyAtomicTypeImpl,\r\n UntypedAtomicImpl,\r\n StringTypeImpl,\r\n BooleanTypeImpl,\r\n} from './simple-types';\r\nexport { DecimalTypeImpl, FloatTypeImpl, DoubleTypeImpl, IntegerTypeImpl } from './numeric-types';\r\nexport { DurationTypeImpl, DateTimeTypeImpl, DateTypeImpl, TimeTypeImpl } from './datetime-types';\r\nexport { parseDuration, parseTime } from './datetime-types';\r\nexport {\r\n GYearMonthTypeImpl,\r\n GYearTypeImpl,\r\n GMonthDayTypeImpl,\r\n GDayTypeImpl,\r\n GMonthTypeImpl,\r\n} from './gregorian-types';\r\nexport { HexBinaryTypeImpl, Base64BinaryTypeImpl } from './binary-types';\r\nexport { AnyURITypeImpl, QNameTypeImpl } from './uri-qname-types';\r\nexport { IntegerDerivedTypeImpl } from './integer-derived-types';\r\n\r\n// XPath 3.0 Function Type System\r\nexport {\r\n FunctionType,\r\n FunctionItem,\r\n FunctionTestItemType,\r\n createFunctionItem,\r\n isFunctionItem,\r\n createFunctionType,\r\n createFunctionTest,\r\n describeFunctionType,\r\n FN_NAMESPACE,\r\n MATH_NAMESPACE,\r\n MAP_NAMESPACE,\r\n ARRAY_NAMESPACE,\r\n} from './function-type';\r\n\r\n// Schema-Aware Type System\r\nexport {\r\n SchemaAwareType,\r\n SchemaAwareTypeInfo,\r\n getSchemaAwareType,\r\n isTypeCompatible,\r\n validateValueAgainstType,\r\n getBuiltInType,\r\n createListType,\r\n registerType,\r\n} from './schema-aware-types';\r\n\r\n// Import all type implementations\r\nimport { AnyAtomicTypeImpl } from './simple-types';\r\nimport { UntypedAtomicImpl } from './simple-types';\r\nimport { StringTypeImpl } from './simple-types';\r\nimport { BooleanTypeImpl } from './simple-types';\r\nimport { DecimalTypeImpl } from './numeric-types';\r\nimport { FloatTypeImpl } from './numeric-types';\r\nimport { DoubleTypeImpl } from './numeric-types';\r\nimport { IntegerTypeImpl } from './numeric-types';\r\nimport { DurationTypeImpl } from './datetime-types';\r\nimport { DateTimeTypeImpl } from './datetime-types';\r\nimport { DateTypeImpl } from './datetime-types';\r\nimport { TimeTypeImpl } from './datetime-types';\r\nimport { GYearMonthTypeImpl } from './gregorian-types';\r\nimport { GYearTypeImpl } from './gregorian-types';\r\nimport { GMonthDayTypeImpl } from './gregorian-types';\r\nimport { GDayTypeImpl } from './gregorian-types';\r\nimport { GMonthTypeImpl } from './gregorian-types';\r\nimport { HexBinaryTypeImpl } from './binary-types';\r\nimport { Base64BinaryTypeImpl } from './binary-types';\r\nimport { AnyURITypeImpl } from './uri-qname-types';\r\nimport { QNameTypeImpl } from './uri-qname-types';\r\nimport { IntegerDerivedTypeImpl } from './integer-derived-types';\r\nimport { AtomicType } from './base';\r\n\r\n// ============================================================================\r\n// Type Registry and Exports\r\n// ============================================================================\r\n\r\n// Create type instances\r\nconst anyAtomicType = new AnyAtomicTypeImpl();\r\nconst untypedAtomic = new UntypedAtomicImpl(anyAtomicType);\r\nconst stringType = new StringTypeImpl(anyAtomicType);\r\nconst booleanType = new BooleanTypeImpl(anyAtomicType);\r\nconst decimalType = new DecimalTypeImpl(anyAtomicType);\r\nconst floatType = new FloatTypeImpl(anyAtomicType);\r\nconst doubleType = new DoubleTypeImpl(anyAtomicType);\r\nconst durationType = new DurationTypeImpl(anyAtomicType);\r\nconst dateTimeType = new DateTimeTypeImpl(anyAtomicType);\r\nconst dateType = new DateTypeImpl(dateTimeType, dateTimeType);\r\nconst timeType = new TimeTypeImpl(dateTimeType, dateTimeType);\r\nconst anyURIType = new AnyURITypeImpl(anyAtomicType);\r\nconst qnameType = new QNameTypeImpl(anyAtomicType);\r\n\r\n// Gregorian types\r\nconst gYearMonthType = new GYearMonthTypeImpl(anyAtomicType);\r\nconst gYearType = new GYearTypeImpl(anyAtomicType);\r\nconst gMonthDayType = new GMonthDayTypeImpl(anyAtomicType);\r\nconst gDayType = new GDayTypeImpl(anyAtomicType);\r\nconst gMonthType = new GMonthTypeImpl(anyAtomicType);\r\n\r\n// Binary types\r\nconst hexBinaryType = new HexBinaryTypeImpl(anyAtomicType);\r\nconst base64BinaryType = new Base64BinaryTypeImpl(anyAtomicType);\r\n\r\n// Integer is derived from decimal\r\nconst integerType = new IntegerTypeImpl(decimalType, decimalType);\r\n\r\n// Integer-derived types with ranges\r\n// Note: JavaScript numbers are 64-bit floats, so we use safe integer bounds\r\nconst longType = new IntegerDerivedTypeImpl(\r\n 'long',\r\n integerType,\r\n decimalType,\r\n -9223372036854775808,\r\n 9223372036854775807\r\n);\r\nconst intType = new IntegerDerivedTypeImpl('int', longType, decimalType, -2147483648, 2147483647);\r\nconst shortType = new IntegerDerivedTypeImpl('short', intType, decimalType, -32768, 32767);\r\nconst byteType = new IntegerDerivedTypeImpl('byte', shortType, decimalType, -128, 127);\r\n\r\nconst nonPositiveIntegerType = new IntegerDerivedTypeImpl(\r\n 'nonPositiveInteger',\r\n integerType,\r\n decimalType,\r\n undefined,\r\n 0\r\n);\r\nconst negativeIntegerType = new IntegerDerivedTypeImpl(\r\n 'negativeInteger',\r\n nonPositiveIntegerType,\r\n decimalType,\r\n undefined,\r\n -1\r\n);\r\n\r\nconst nonNegativeIntegerType = new IntegerDerivedTypeImpl(\r\n 'nonNegativeInteger',\r\n integerType,\r\n decimalType,\r\n 0,\r\n undefined\r\n);\r\nconst positiveIntegerType = new IntegerDerivedTypeImpl(\r\n 'positiveInteger',\r\n nonNegativeIntegerType,\r\n decimalType,\r\n 1,\r\n undefined\r\n);\r\n\r\nconst unsignedLongType = new IntegerDerivedTypeImpl(\r\n 'unsignedLong',\r\n nonNegativeIntegerType,\r\n decimalType,\r\n 0,\r\n 18446744073709551615\r\n);\r\nconst unsignedIntType = new IntegerDerivedTypeImpl(\r\n 'unsignedInt',\r\n unsignedLongType,\r\n decimalType,\r\n 0,\r\n 4294967295\r\n);\r\nconst unsignedShortType = new IntegerDerivedTypeImpl(\r\n 'unsignedShort',\r\n unsignedIntType,\r\n decimalType,\r\n 0,\r\n 65535\r\n);\r\nconst unsignedByteType = new IntegerDerivedTypeImpl(\r\n 'unsignedByte',\r\n unsignedShortType,\r\n decimalType,\r\n 0,\r\n 255\r\n);\r\n\r\n/**\r\n * Built-in atomic types registry\r\n */\r\nexport const ATOMIC_TYPES: Record<string, AtomicType> = {\r\n anyAtomicType: anyAtomicType,\r\n untypedAtomic: untypedAtomic,\r\n string: stringType,\r\n boolean: booleanType,\r\n decimal: decimalType,\r\n float: floatType,\r\n double: doubleType,\r\n integer: integerType,\r\n duration: durationType,\r\n dateTime: dateTimeType,\r\n date: dateType,\r\n time: timeType,\r\n anyURI: anyURIType,\r\n QName: qnameType,\r\n // Gregorian types\r\n gYearMonth: gYearMonthType,\r\n gYear: gYearType,\r\n gMonthDay: gMonthDayType,\r\n gDay: gDayType,\r\n gMonth: gMonthType,\r\n // Binary types\r\n hexBinary: hexBinaryType,\r\n base64Binary: base64BinaryType,\r\n // Integer-derived types\r\n long: longType,\r\n int: intType,\r\n short: shortType,\r\n byte: byteType,\r\n nonPositiveInteger: nonPositiveIntegerType,\r\n negativeInteger: negativeIntegerType,\r\n nonNegativeInteger: nonNegativeIntegerType,\r\n positiveInteger: positiveIntegerType,\r\n unsignedLong: unsignedLongType,\r\n unsignedInt: unsignedIntType,\r\n unsignedShort: unsignedShortType,\r\n unsignedByte: unsignedByteType,\r\n};\r\n\r\n/**\r\n * Get an atomic type by its local name\r\n */\r\nexport function getAtomicType(name: string): AtomicType | undefined {\r\n return ATOMIC_TYPES[name];\r\n}\r\n\r\n/**\r\n * Check if a value is an instance of a given atomic type\r\n */\r\nexport function isInstanceOf(value: any, typeName: string): boolean {\r\n const type = getAtomicType(typeName);\r\n if (!type) return false;\r\n return type.validate(value);\r\n}\r\n\r\n/**\r\n * Cast a value to a given atomic type\r\n */\r\nexport function castAs(value: any, typeName: string): any {\r\n const type = getAtomicType(typeName);\r\n if (!type) {\r\n throw new Error(`Unknown atomic type: ${typeName}`);\r\n }\r\n return type.cast(value);\r\n}\r\n\r\n/**\r\n * Check if a type is numeric (integer, decimal, float, double)\r\n */\r\nexport function isNumericType(type: AtomicType): boolean {\r\n return ['decimal', 'float', 'double', 'integer', 'long', 'int', 'short', 'byte'].includes(\r\n type.name\r\n );\r\n}\r\n","import { XPathContext } from '../context';\r\nimport { matchesSequenceType, SequenceType } from '../types';\r\nimport { XPathExpression } from './expression';\r\n\r\nexport class XPathInstanceOfExpression extends XPathExpression {\r\n constructor(\r\n private readonly expression: XPathExpression,\r\n private readonly sequenceType: SequenceType\r\n ) {\r\n super();\r\n }\r\n\r\n evaluate(context: XPathContext): boolean {\r\n const value = this.expression.evaluate(context);\r\n return matchesSequenceType(value, this.sequenceType).matches;\r\n }\r\n}\r\n","import { XPathContext } from '../context';\r\nimport { castAs } from '../types';\r\nimport { SequenceType, OccurrenceIndicator } from '../types/sequence-type';\r\nimport { XPathExpression } from './expression';\r\n\r\n/**\r\n * XPath 2.0 castable as expression (Section 3.10.3)\r\n * Returns true if a value can be cast to the given atomic SequenceType without raising an error.\r\n */\r\nexport class XPathCastableExpression extends XPathExpression {\r\n constructor(\r\n private readonly expression: XPathExpression,\r\n private readonly sequenceType: SequenceType\r\n ) {\r\n super();\r\n }\r\n\r\n evaluate(context: XPathContext): boolean {\r\n const value = this.expression.evaluate(context);\r\n const sequence = Array.isArray(value)\r\n ? value\r\n : value === undefined || value === null\r\n ? []\r\n : [value];\r\n\r\n // cardinality: only zero or one item allowed\r\n if (sequence.length > 1) {\r\n return false;\r\n }\r\n\r\n // empty sequence handling\r\n if (sequence.length === 0) {\r\n return this.sequenceType.getOccurrence() === OccurrenceIndicator.ZERO_OR_ONE;\r\n }\r\n\r\n const item = sequence[0];\r\n const itemType = this.sequenceType.getItemType();\r\n\r\n // Only atomic types supported for casting here\r\n if (itemType === 'empty' || !itemType.atomicType) {\r\n return false;\r\n }\r\n\r\n try {\r\n castAs(item, itemType.atomicType.name);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n}\r\n","import { XPathContext } from '../context';\r\nimport { XPathExpression } from './expression';\r\nimport { SequenceType } from '../types';\r\nimport { matchesSequenceType } from '../types/sequence-type-matcher';\r\n\r\n/**\r\n * XPath 2.0 Treat Expression (Section 3.10.5)\r\n * Dynamically asserts that the operand matches a SequenceType; throws on mismatch.\r\n */\r\nexport class XPathTreatExpression extends XPathExpression {\r\n constructor(\r\n private readonly expression: XPathExpression,\r\n private readonly sequenceType: SequenceType\r\n ) {\r\n super();\r\n }\r\n\r\n evaluate(context: XPathContext): any {\r\n const value = this.expression.evaluate(context);\r\n const result = matchesSequenceType(value, this.sequenceType);\r\n\r\n if (!result.matches) {\r\n const reason = result.reason ?? `Value does not match ${this.sequenceType.toString()}`;\r\n throw new Error(`Treat expression type mismatch: ${reason}`);\r\n }\r\n\r\n return value;\r\n }\r\n}\r\n","import { XPathExpression } from './expression';\r\n\r\nexport class XPathUnionExpression extends XPathExpression {\r\n left: XPathExpression;\r\n right: XPathExpression;\r\n\r\n constructor(left: XPathExpression, right: XPathExpression) {\r\n super();\r\n this.left = left;\r\n this.right = right;\r\n }\r\n\r\n evaluate(context: any): any[] {\r\n const leftResult = this.left.evaluate(context);\r\n const rightResult = this.right.evaluate(context);\r\n\r\n // Both operands must be node-sets\r\n const leftNodes = Array.isArray(leftResult) ? leftResult : [];\r\n const rightNodes = Array.isArray(rightResult) ? rightResult : [];\r\n\r\n // Combine and remove duplicates, preserving document order\r\n return this.unionNodes(leftNodes, rightNodes);\r\n }\r\n\r\n private unionNodes(left: any[], right: any[]): any[] {\r\n const seen = new Set();\r\n const result: any[] = [];\r\n\r\n // Add left nodes\r\n for (const node of left) {\r\n if (!seen.has(node)) {\r\n seen.add(node);\r\n result.push(node);\r\n }\r\n }\r\n\r\n // Add right nodes not already in result\r\n for (const node of right) {\r\n if (!seen.has(node)) {\r\n seen.add(node);\r\n result.push(node);\r\n }\r\n }\r\n\r\n // Sort by document order\r\n return this.sortByDocumentOrder(result);\r\n }\r\n\r\n private sortByDocumentOrder(nodes: any[]): any[] {\r\n return nodes.sort((a, b) => {\r\n if (a === b) return 0;\r\n\r\n // Use compareDocumentPosition if available (DOM Level 3)\r\n if (typeof a.compareDocumentPosition === 'function') {\r\n const position = a.compareDocumentPosition(b);\r\n if (position & 4) return -1; // b follows a\r\n if (position & 2) return 1; // a follows b\r\n }\r\n\r\n return 0;\r\n });\r\n }\r\n}\r\n","/**\r\n * XPath 2.0 Sequence Construction (Section 3.3.1)\r\n * https://www.w3.org/TR/xpath20/#construct\r\n *\r\n * Sequence construction creates sequences using:\r\n * 1. Comma operator: concatenates operand sequences into a single sequence\r\n * 2. Range expressions: creates sequences of integers (e.g., 1 to 10)\r\n * 3. Parenthesized expressions: groups sequences\r\n * 4. Empty sequence: represents the absence of a value\r\n *\r\n * Key rules:\r\n * - Sequences are automatically flattened (no nested sequences)\r\n * - Comma has lowest precedence\r\n * - Range expressions require integers\r\n * - Empty sequence has zero length\r\n */\r\n\r\nimport { XPathExpression } from './expression';\r\nimport { XPathContext } from '../context';\r\n\r\n/**\r\n * CommaExpression - concatenates sequences\r\n * Syntax: expr1 , expr2 , ...\r\n *\r\n * The comma operator has the lowest precedence and concatenates\r\n * all operand sequences into a single flat sequence.\r\n *\r\n * Example:\r\n * 1, 2, 3 → (1, 2, 3)\r\n * (1 to 3), (5 to 7) → (1, 2, 3, 5, 6, 7)\r\n * $x, $y, $z → concatenated sequence of all three variables\r\n */\r\nexport class CommaExpression extends XPathExpression {\r\n constructor(private operands: XPathExpression[]) {\r\n super();\r\n if (operands.length < 2) {\r\n throw new Error('CommaExpression requires at least 2 operands');\r\n }\r\n }\r\n\r\n evaluate(context: XPathContext): any {\r\n // Concatenate all operand results into a single sequence\r\n const result: any[] = [];\r\n\r\n for (const operand of this.operands) {\r\n const value = operand.evaluate(context);\r\n\r\n // Flatten sequences\r\n if (Array.isArray(value)) {\r\n result.push(...value);\r\n } else if (value !== undefined && value !== null) {\r\n result.push(value);\r\n }\r\n // null/undefined are not added to the sequence\r\n }\r\n\r\n // Return the flattened sequence\r\n return result.length > 0 ? result : [];\r\n }\r\n\r\n getOperands(): XPathExpression[] {\r\n return this.operands;\r\n }\r\n\r\n toString(): string {\r\n return this.operands.map((op) => op.toString()).join(', ');\r\n }\r\n}\r\n\r\n/**\r\n * RangeExpression - creates a sequence of consecutive integers\r\n * Syntax: expr1 to expr2\r\n *\r\n * Both operands must evaluate to single integers.\r\n * Creates a sequence from expr1 to expr2 (inclusive).\r\n * If expr1 > expr2, the result is an empty sequence.\r\n *\r\n * Examples:\r\n * 1 to 5 → (1, 2, 3, 4, 5)\r\n * 5 to 1 → () empty sequence\r\n * 1 to 1 → (1)\r\n * -2 to 2 → (-2, -1, 0, 1, 2)\r\n */\r\nexport class RangeExpression extends XPathExpression {\r\n constructor(\r\n private startExpr: XPathExpression,\r\n private endExpr: XPathExpression\r\n ) {\r\n super();\r\n }\r\n\r\n evaluate(context: XPathContext): any {\r\n // Evaluate both operands\r\n const startValue = this.startExpr.evaluate(context);\r\n const endValue = this.endExpr.evaluate(context);\r\n\r\n // Convert to single values (atomization)\r\n let start: number;\r\n let end: number;\r\n\r\n try {\r\n // Handle arrays/sequences - take first item\r\n const startItem = Array.isArray(startValue) ? startValue[0] : startValue;\r\n const endItem = Array.isArray(endValue) ? endValue[0] : endValue;\r\n\r\n start = this.toInteger(startItem);\r\n end = this.toInteger(endItem);\r\n } catch (e) {\r\n throw new Error(`Range expression operands must be integers: ${String(e)}`);\r\n }\r\n\r\n // Create the range\r\n if (start > end) {\r\n return []; // Empty sequence\r\n }\r\n\r\n const result: number[] = [];\r\n for (let i = start; i <= end; i++) {\r\n result.push(i);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n private toInteger(value: any): number {\r\n if (typeof value === 'number') {\r\n // Truncate to integer\r\n return Math.trunc(value);\r\n }\r\n\r\n if (typeof value === 'string') {\r\n const num = parseInt(value, 10);\r\n if (isNaN(num)) {\r\n throw new Error(`Cannot convert \"${value}\" to integer`);\r\n }\r\n return num;\r\n }\r\n\r\n if (typeof value === 'boolean') {\r\n return value ? 1 : 0;\r\n }\r\n\r\n throw new Error(`Cannot convert ${typeof value} to integer`);\r\n }\r\n\r\n toString(): string {\r\n return `${this.startExpr.toString()} to ${this.endExpr.toString()}`;\r\n }\r\n}\r\n\r\n/**\r\n * EmptySequenceExpression - represents the empty sequence\r\n * Syntax: empty-sequence()\r\n *\r\n * The empty sequence has zero length and represents the absence of a value.\r\n * It's used in contexts where a sequence is required but no value is available.\r\n * It's different from null/undefined - it's an explicit empty sequence type.\r\n *\r\n * Example:\r\n * empty-sequence() → ()\r\n */\r\nexport class EmptySequenceExpression extends XPathExpression {\r\n evaluate(context: XPathContext): any {\r\n // Return empty array representing the empty sequence\r\n return [];\r\n }\r\n\r\n toString(): string {\r\n return 'empty-sequence()';\r\n }\r\n}\r\n\r\n/**\r\n * ParenthesizedExpression - groups an expression\r\n * Syntax: ( expr )\r\n *\r\n * Parentheses are used to override operator precedence.\r\n * A parenthesized expression returns the value of its operand.\r\n *\r\n * Example:\r\n * (1 to 3) → (1, 2, 3)\r\n * (1 + 2) * 3 → 9\r\n * (1, 2), (3, 4) → (1, 2, 3, 4)\r\n */\r\nexport class ParenthesizedExpression extends XPathExpression {\r\n constructor(private operand: XPathExpression) {\r\n super();\r\n }\r\n\r\n evaluate(context: XPathContext): any {\r\n return this.operand.evaluate(context);\r\n }\r\n\r\n getOperand(): XPathExpression {\r\n return this.operand;\r\n }\r\n\r\n toString(): string {\r\n return `(${this.operand.toString()})`;\r\n }\r\n}\r\n\r\n/**\r\n * Sequence - represents a value that could be empty, single, or multiple items\r\n * Used internally for sequence operations\r\n */\r\nexport interface Sequence {\r\n /**\r\n * The items in the sequence\r\n */\r\n items: any[];\r\n\r\n /**\r\n * Check if sequence is empty\r\n */\r\n isEmpty(): boolean;\r\n\r\n /**\r\n * Get first item, or undefined if empty\r\n */\r\n first(): any | undefined;\r\n\r\n /**\r\n * Get last item, or undefined if empty\r\n */\r\n last(): any | undefined;\r\n\r\n /**\r\n * Get length of sequence\r\n */\r\n length(): number;\r\n}\r\n\r\n/**\r\n * Helper function to create a sequence from any value\r\n */\r\nexport function createSequence(value: any): Sequence {\r\n let items: any[];\r\n\r\n if (value === undefined || value === null) {\r\n items = [];\r\n } else if (Array.isArray(value)) {\r\n items = value;\r\n } else {\r\n items = [value];\r\n }\r\n\r\n return {\r\n items,\r\n isEmpty: () => items.length === 0,\r\n first: () => items[0],\r\n last: () => items[items.length - 1],\r\n length: () => items.length,\r\n };\r\n}\r\n\r\n/**\r\n * Helper function to flatten nested sequences\r\n * XPath 2.0 sequences are always flat (no nested arrays)\r\n */\r\nexport function flattenSequence(value: any): any[] {\r\n if (value === undefined || value === null) {\r\n return [];\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n return value;\r\n }\r\n\r\n return [value];\r\n}\r\n\r\n/**\r\n * Helper function to concatenate sequences\r\n */\r\nexport function concatenateSequences(...sequences: any[]): any[] {\r\n const result: any[] = [];\r\n\r\n for (const seq of sequences) {\r\n if (Array.isArray(seq)) {\r\n result.push(...seq);\r\n } else if (seq !== undefined && seq !== null) {\r\n result.push(seq);\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Helper function to check if a value is a node\r\n * Used for node operations (union, intersect, except)\r\n */\r\nexport function isXPathNode(value: any): boolean {\r\n if (!value || typeof value !== 'object') {\r\n return false;\r\n }\r\n\r\n // Check for node-like properties\r\n return (\r\n typeof value.nodeType === 'string' ||\r\n typeof value.nodeName === 'string' ||\r\n typeof value.textContent === 'string'\r\n );\r\n}\r\n\r\n/**\r\n * Helper function to get a unique identifier for a node\r\n * Used for deduplication in union/intersect/except\r\n */\r\nexport function getNodeId(node: any): string {\r\n if (!isXPathNode(node)) {\r\n return String(node);\r\n }\r\n\r\n // Use nodeType + nodeName + position for unique identification\r\n return `${node.nodeType}:${node.nodeName || node.localName || ''}:${node.__id || ''}`;\r\n}\r\n","import { XPathExpression } from './expression';\r\n\r\nexport class XPathPredicate extends XPathExpression {\r\n expression: XPathExpression;\r\n\r\n constructor(expression: XPathExpression) {\r\n super();\r\n this.expression = expression;\r\n }\r\n\r\n evaluate(context: any): any {\r\n return this.expression.evaluate(context);\r\n }\r\n\r\n test(context: any): boolean {\r\n const result = this.evaluate(context);\r\n\r\n // If the result is a number, compare with position\r\n if (typeof result === 'number') {\r\n return result === context?.position;\r\n }\r\n\r\n // Otherwise convert to boolean\r\n return this.toBoolean(result);\r\n }\r\n\r\n private toBoolean(value: any): boolean {\r\n if (typeof value === 'boolean') return value;\r\n if (typeof value === 'number') return value !== 0 && !isNaN(value);\r\n if (typeof value === 'string') return value.length > 0;\r\n if (Array.isArray(value)) return value.length > 0;\r\n return !!value;\r\n }\r\n}\r\n","/**\r\n * XPath 2.0 Value Comparisons (Section 3.5.1)\r\n * https://www.w3.org/TR/xpath20/#id-value-comparisons\r\n *\r\n * Value comparisons use special operators (eq, ne, lt, le, gt, ge) that:\r\n * 1. Atomize both operands\r\n * 2. Work on single atomic values\r\n * 3. Raise an error on empty sequences or multiple items\r\n * 4. Perform type checking and conversions\r\n * 5. Return boolean results\r\n *\r\n * Key differences from general comparisons:\r\n * - Must have exactly one atomic value on each side\r\n * - Empty sequence raises an error\r\n * - Type promotion may be applied\r\n * - Not compatible with XPath 1.0\r\n */\r\n\r\nimport { XPathExpression } from './expression';\r\nimport { XPathContext } from '../context';\r\n\r\nexport type ValueComparisonOperator = 'eq' | 'ne' | 'lt' | 'le' | 'gt' | 'ge';\r\n\r\n/**\r\n * ValueComparisonExpression - XPath 2.0 value comparison\r\n *\r\n * Syntax: expr1 eq expr2 | expr1 ne expr2 | expr1 lt expr2 | expr1 le expr2 | expr1 gt expr2 | expr1 ge expr2\r\n *\r\n * Examples:\r\n * 5 eq 5 → true\r\n * \"a\" ne \"b\" → true\r\n * 10 lt 20 → true\r\n * 3.14 ge 3 → true\r\n */\r\nexport class ValueComparisonExpression extends XPathExpression {\r\n constructor(\r\n private left: XPathExpression,\r\n private operator: ValueComparisonOperator,\r\n private right: XPathExpression\r\n ) {\r\n super();\r\n }\r\n\r\n evaluate(context: XPathContext): boolean {\r\n // Evaluate both operands\r\n const leftValue = this.left.evaluate(context);\r\n const rightValue = this.right.evaluate(context);\r\n\r\n // Atomize operands\r\n const leftAtom = this.atomize(leftValue);\r\n const rightAtom = this.atomize(rightValue);\r\n\r\n // Both must be single values (error on empty or multiple)\r\n if (leftAtom === undefined || rightAtom === undefined) {\r\n throw new Error('Value comparison requires non-empty sequences');\r\n }\r\n\r\n // Perform comparison based on operator\r\n return this.compare(leftAtom, rightAtom, this.operator);\r\n }\r\n\r\n /**\r\n * Atomize a value - convert to single atomic value\r\n */\r\n private atomize(value: any): any {\r\n if (value === undefined || value === null) {\r\n return undefined;\r\n }\r\n\r\n // If array, must have exactly one item\r\n if (Array.isArray(value)) {\r\n if (value.length === 0) {\r\n return undefined;\r\n }\r\n if (value.length === 1) {\r\n return value[0];\r\n }\r\n // Multiple items - error\r\n throw new Error('Value comparison requires single atomic values');\r\n }\r\n\r\n // If node, extract typed value\r\n if (this.isNode(value)) {\r\n // For nodes, extract string value\r\n return this.getNodeStringValue(value);\r\n }\r\n\r\n return value;\r\n }\r\n\r\n /**\r\n * Compare two atomic values\r\n */\r\n private compare(left: any, right: any, operator: ValueComparisonOperator): boolean {\r\n // Perform type promotion and conversion\r\n const [promotedLeft, promotedRight] = this.promoteTypes(left, right);\r\n\r\n // Compare based on operator\r\n switch (operator) {\r\n case 'eq':\r\n return this.equal(promotedLeft, promotedRight);\r\n case 'ne':\r\n return !this.equal(promotedLeft, promotedRight);\r\n case 'lt':\r\n return this.lessThan(promotedLeft, promotedRight);\r\n case 'le':\r\n return (\r\n this.lessThan(promotedLeft, promotedRight) ||\r\n this.equal(promotedLeft, promotedRight)\r\n );\r\n case 'gt':\r\n return this.greaterThan(promotedLeft, promotedRight);\r\n case 'ge':\r\n return (\r\n this.greaterThan(promotedLeft, promotedRight) ||\r\n this.equal(promotedLeft, promotedRight)\r\n );\r\n default:\r\n throw new Error(`Unknown comparison operator: ${operator}`);\r\n }\r\n }\r\n\r\n /**\r\n * Promote types to common type for comparison\r\n */\r\n private promoteTypes(left: any, right: any): [any, any] {\r\n // If both are numbers, use numeric comparison\r\n if (typeof left === 'number' && typeof right === 'number') {\r\n return [left, right];\r\n }\r\n\r\n // If either is a number, convert the other to number\r\n if (typeof left === 'number') {\r\n return [left, this.toNumber(right)];\r\n }\r\n if (typeof right === 'number') {\r\n return [this.toNumber(left), right];\r\n }\r\n\r\n // If both are strings, use string comparison\r\n if (typeof left === 'string' && typeof right === 'string') {\r\n return [left, right];\r\n }\r\n\r\n // If either is a string, convert to string\r\n if (typeof left === 'string') {\r\n return [left, this.valueToString(right)];\r\n }\r\n if (typeof right === 'string') {\r\n return [this.valueToString(left), right];\r\n }\r\n\r\n // Boolean comparisons\r\n if (typeof left === 'boolean' || typeof right === 'boolean') {\r\n return [this.toBoolean(left), this.toBoolean(right)];\r\n }\r\n\r\n return [left, right];\r\n }\r\n\r\n /**\r\n * Check equality of two values\r\n */\r\n private equal(left: any, right: any): boolean {\r\n if (typeof left !== typeof right) {\r\n return false;\r\n }\r\n\r\n if (typeof left === 'number') {\r\n // Handle NaN comparison\r\n if (isNaN(left) && isNaN(right)) {\r\n return false; // NaN != NaN in XPath\r\n }\r\n return left === right;\r\n }\r\n\r\n return left === right;\r\n }\r\n\r\n /**\r\n * Check if left < right\r\n */\r\n private lessThan(left: any, right: any): boolean {\r\n if (typeof left === 'number' && typeof right === 'number') {\r\n return left < right;\r\n }\r\n if (typeof left === 'string' && typeof right === 'string') {\r\n return left < right;\r\n }\r\n throw new Error(`Cannot compare ${typeof left} with ${typeof right}`);\r\n }\r\n\r\n /**\r\n * Check if left > right\r\n */\r\n private greaterThan(left: any, right: any): boolean {\r\n if (typeof left === 'number' && typeof right === 'number') {\r\n return left > right;\r\n }\r\n if (typeof left === 'string' && typeof right === 'string') {\r\n return left > right;\r\n }\r\n throw new Error(`Cannot compare ${typeof left} with ${typeof right}`);\r\n }\r\n\r\n /**\r\n * Convert value to number\r\n */\r\n private toNumber(value: any): number {\r\n if (typeof value === 'number') return value;\r\n if (typeof value === 'boolean') return value ? 1 : 0;\r\n if (typeof value === 'string') {\r\n const num = parseFloat(value);\r\n return isNaN(num) ? NaN : num;\r\n }\r\n return NaN;\r\n }\r\n\r\n /**\r\n * Convert value to string\r\n */\r\n private valueToString(value: any): string {\r\n if (typeof value === 'string') return value;\r\n if (typeof value === 'number') return String(value);\r\n if (typeof value === 'boolean') return value ? 'true' : 'false';\r\n if (this.isNode(value)) return this.getNodeStringValue(value);\r\n return String(value);\r\n }\r\n\r\n /**\r\n * Convert value to boolean\r\n */\r\n private toBoolean(value: any): boolean {\r\n if (typeof value === 'boolean') return value;\r\n if (typeof value === 'number') return value !== 0 && !isNaN(value);\r\n if (typeof value === 'string') return value.length > 0;\r\n if (Array.isArray(value)) return value.length > 0;\r\n return !!value;\r\n }\r\n\r\n /**\r\n * Check if value is a node\r\n */\r\n private isNode(value: any): boolean {\r\n return value && typeof value === 'object' && ('nodeType' in value || 'nodeName' in value);\r\n }\r\n\r\n /**\r\n * Get string value of a node\r\n */\r\n private getNodeStringValue(node: any): string {\r\n if (node.textContent !== undefined) return String(node.textContent);\r\n if (node.nodeValue !== undefined) return String(node.nodeValue);\r\n if (node.value !== undefined) return String(node.value);\r\n return '';\r\n }\r\n\r\n toString(): string {\r\n return `${this.left.toString()} ${this.operator} ${this.right.toString()}`;\r\n }\r\n}\r\n","/**\r\n * XPath 2.0 General Comparisons (Section 3.5.2)\r\n * https://www.w3.org/TR/xpath20/#id-general-comparisons\r\n *\r\n * General comparisons use standard operators (=, !=, <, <=, >, >=) that:\r\n * 1. Work on sequences (not just single values)\r\n * 2. Use existential quantification\r\n * 3. Flatten sequences\r\n * 4. Work with XPath 1.0 compatibility mode\r\n * 5. Return boolean results\r\n *\r\n * Key differences from value comparisons:\r\n * - Can work with sequences and multiple items\r\n * - Uses existential semantics (there exists one pair that matches)\r\n * - Empty sequences are allowed\r\n * - XPath 1.0 compatible\r\n */\r\n\r\nimport { XPathExpression } from './expression';\r\nimport { XPathContext } from '../context';\r\n\r\nexport type GeneralComparisonOperator = '=' | '!=' | '<' | '<=' | '>' | '>=';\r\n\r\n/**\r\n * GeneralComparisonExpression - XPath 2.0 general comparison with sequences\r\n *\r\n * Syntax: expr1 = expr2 | expr1 != expr2 | expr1 < expr2 | expr1 <= expr2 | expr1 > expr2 | expr1 >= expr2\r\n *\r\n * Semantics: Returns true if there exists at least one pair of values (one from each operand)\r\n * where the comparison is true.\r\n *\r\n * Examples:\r\n * (1, 2, 3) = 2 → true (2 = 2)\r\n * (1, 2) < 5 → true (1 < 5 and 2 < 5)\r\n * (4, 5) = (5, 6) → true (5 = 5)\r\n */\r\nexport class GeneralComparisonExpression extends XPathExpression {\r\n constructor(\r\n private left: XPathExpression,\r\n private operator: GeneralComparisonOperator,\r\n private right: XPathExpression\r\n ) {\r\n super();\r\n }\r\n\r\n evaluate(context: XPathContext): boolean {\r\n // Evaluate both operands\r\n let leftValue = this.left.evaluate(context);\r\n let rightValue = this.right.evaluate(context);\r\n\r\n // Flatten sequences\r\n const leftItems = this.flatten(leftValue);\r\n const rightItems = this.flatten(rightValue);\r\n\r\n // Empty sequences are false\r\n if (leftItems.length === 0 || rightItems.length === 0) {\r\n return false;\r\n }\r\n\r\n // Use existential quantification\r\n // Return true if at least one pair satisfies the condition\r\n for (const left of leftItems) {\r\n for (const right of rightItems) {\r\n if (this.compareValues(left, right, this.operator)) {\r\n return true;\r\n }\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Flatten a value into an array\r\n */\r\n private flatten(value: any): any[] {\r\n if (value === undefined || value === null) {\r\n return [];\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n const result: any[] = [];\r\n for (const item of value) {\r\n if (item !== undefined && item !== null) {\r\n result.push(item);\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n return [value];\r\n }\r\n\r\n /**\r\n * Compare two values from the existential quantification\r\n */\r\n private compareValues(left: any, right: any, operator: GeneralComparisonOperator): boolean {\r\n // Get comparable values (atomize/extract if needed)\r\n const leftVal = this.getComparableValue(left);\r\n const rightVal = this.getComparableValue(right);\r\n\r\n // Perform type promotion\r\n const [promotedLeft, promotedRight] = this.promoteTypes(leftVal, rightVal);\r\n\r\n // Compare based on operator\r\n switch (operator) {\r\n case '=':\r\n return this.equal(promotedLeft, promotedRight);\r\n case '!=':\r\n return !this.equal(promotedLeft, promotedRight);\r\n case '<':\r\n return this.lessThan(promotedLeft, promotedRight);\r\n case '<=':\r\n return (\r\n this.lessThan(promotedLeft, promotedRight) ||\r\n this.equal(promotedLeft, promotedRight)\r\n );\r\n case '>':\r\n return this.greaterThan(promotedLeft, promotedRight);\r\n case '>=':\r\n return (\r\n this.greaterThan(promotedLeft, promotedRight) ||\r\n this.equal(promotedLeft, promotedRight)\r\n );\r\n default:\r\n throw new Error(`Unknown comparison operator: ${operator}`);\r\n }\r\n }\r\n\r\n /**\r\n * Get comparable value (extract from nodes if needed)\r\n */\r\n private getComparableValue(value: any): any {\r\n if (value === undefined || value === null) {\r\n return undefined;\r\n }\r\n\r\n // If node, extract string value\r\n if (this.isNode(value)) {\r\n return this.getNodeStringValue(value);\r\n }\r\n\r\n return value;\r\n }\r\n\r\n /**\r\n * Promote types to common type for comparison\r\n */\r\n private promoteTypes(left: any, right: any): [any, any] {\r\n // If both are numbers, use numeric comparison\r\n if (typeof left === 'number' && typeof right === 'number') {\r\n return [left, right];\r\n }\r\n\r\n // If either is a number, convert the other to number\r\n if (typeof left === 'number') {\r\n return [left, this.toNumber(right)];\r\n }\r\n if (typeof right === 'number') {\r\n return [this.toNumber(left), right];\r\n }\r\n\r\n // If both are strings, use string comparison\r\n if (typeof left === 'string' && typeof right === 'string') {\r\n return [left, right];\r\n }\r\n\r\n // If either is a string, convert to string\r\n if (typeof left === 'string') {\r\n return [left, this.valueToString(right)];\r\n }\r\n if (typeof right === 'string') {\r\n return [this.valueToString(left), right];\r\n }\r\n\r\n // Boolean comparisons\r\n if (typeof left === 'boolean' || typeof right === 'boolean') {\r\n return [this.toBoolean(left), this.toBoolean(right)];\r\n }\r\n\r\n return [left, right];\r\n }\r\n\r\n /**\r\n * Check equality of two values\r\n */\r\n private equal(left: any, right: any): boolean {\r\n if (typeof left !== typeof right) {\r\n return false;\r\n }\r\n\r\n if (typeof left === 'number') {\r\n // Handle NaN comparison - NaN != NaN\r\n if (isNaN(left) && isNaN(right)) {\r\n return false;\r\n }\r\n return left === right;\r\n }\r\n\r\n return left === right;\r\n }\r\n\r\n /**\r\n * Check if left < right\r\n */\r\n private lessThan(left: any, right: any): boolean {\r\n if (typeof left === 'number' && typeof right === 'number') {\r\n return left < right;\r\n }\r\n if (typeof left === 'string' && typeof right === 'string') {\r\n return left < right;\r\n }\r\n throw new Error(`Cannot compare ${typeof left} with ${typeof right}`);\r\n }\r\n\r\n /**\r\n * Check if left > right\r\n */\r\n private greaterThan(left: any, right: any): boolean {\r\n if (typeof left === 'number' && typeof right === 'number') {\r\n return left > right;\r\n }\r\n if (typeof left === 'string' && typeof right === 'string') {\r\n return left > right;\r\n }\r\n throw new Error(`Cannot compare ${typeof left} with ${typeof right}`);\r\n }\r\n\r\n /**\r\n * Convert value to number\r\n */\r\n private toNumber(value: any): number {\r\n if (typeof value === 'number') return value;\r\n if (typeof value === 'boolean') return value ? 1 : 0;\r\n if (typeof value === 'string') {\r\n const num = parseFloat(value);\r\n return isNaN(num) ? NaN : num;\r\n }\r\n return NaN;\r\n }\r\n\r\n /**\r\n * Convert value to string\r\n */\r\n private valueToString(value: any): string {\r\n if (typeof value === 'string') return value;\r\n if (typeof value === 'number') return String(value);\r\n if (typeof value === 'boolean') return value ? 'true' : 'false';\r\n if (this.isNode(value)) return this.getNodeStringValue(value);\r\n return String(value);\r\n }\r\n\r\n /**\r\n * Convert value to boolean\r\n */\r\n private toBoolean(value: any): boolean {\r\n if (typeof value === 'boolean') return value;\r\n if (typeof value === 'number') return value !== 0 && !isNaN(value);\r\n if (typeof value === 'string') return value.length > 0;\r\n if (Array.isArray(value)) return value.length > 0;\r\n return !!value;\r\n }\r\n\r\n /**\r\n * Check if value is a node\r\n */\r\n private isNode(value: any): boolean {\r\n return value && typeof value === 'object' && ('nodeType' in value || 'nodeName' in value);\r\n }\r\n\r\n /**\r\n * Get string value of a node\r\n */\r\n private getNodeStringValue(node: any): string {\r\n if (node.textContent !== undefined) return String(node.textContent);\r\n if (node.nodeValue !== undefined) return String(node.nodeValue);\r\n if (node.value !== undefined) return String(node.value);\r\n return '';\r\n }\r\n\r\n toString(): string {\r\n return `${this.left.toString()} ${this.operator} ${this.right.toString()}`;\r\n }\r\n}\r\n","/**\r\n * XPath 2.0 Node Comparisons (Section 3.5.3)\r\n * https://www.w3.org/TR/xpath20/#id-node-comparisons\r\n *\r\n * Node comparisons use special operators that work on nodes:\r\n * 1. `is` - tests node identity (same node)\r\n * 2. `<<` - tests document order (left node comes before right)\r\n * 3. `>>` - tests document order (left node comes after right)\r\n *\r\n * These operators:\r\n * - Work only on nodes\r\n * - Return boolean results\r\n * - Use object identity for node comparison\r\n * - Are not available in XPath 1.0\r\n */\r\n\r\nimport { XPathExpression } from './expression';\r\nimport { XPathContext } from '../context';\r\n\r\nexport type NodeComparisonOperator = 'is' | '<<' | '>>';\r\n\r\n/**\r\n * NodeComparisonExpression - XPath 2.0 node comparison\r\n *\r\n * Syntax:\r\n * expr1 is expr2 // node identity\r\n * expr1 << expr2 // document order (left before right)\r\n * expr1 >> expr2 // document order (left after right)\r\n *\r\n * Examples:\r\n * $node1 is $node2 → true if same node\r\n * $a << $b → true if $a comes before $b in document\r\n * $a >> $b → true if $a comes after $b in document\r\n */\r\nexport class NodeComparisonExpression extends XPathExpression {\r\n constructor(\r\n private left: XPathExpression,\r\n private operator: NodeComparisonOperator,\r\n private right: XPathExpression\r\n ) {\r\n super();\r\n }\r\n\r\n evaluate(context: XPathContext): boolean {\r\n // Evaluate both operands\r\n const leftValue = this.left.evaluate(context);\r\n const rightValue = this.right.evaluate(context);\r\n\r\n // Extract single nodes from sequences\r\n const leftNode = this.extractNode(leftValue);\r\n const rightNode = this.extractNode(rightValue);\r\n\r\n // Both must be nodes\r\n if (!this.isNode(leftNode) || !this.isNode(rightNode)) {\r\n throw new Error('Node comparison requires node operands');\r\n }\r\n\r\n // Perform comparison based on operator\r\n switch (this.operator) {\r\n case 'is':\r\n return this.isIdentical(leftNode, rightNode);\r\n case '<<':\r\n return this.isDocumentOrderBefore(leftNode, rightNode);\r\n case '>>':\r\n return this.isDocumentOrderAfter(leftNode, rightNode);\r\n default:\r\n throw new Error(`Unknown node comparison operator: ${this.operator}`);\r\n }\r\n }\r\n\r\n /**\r\n * Extract single node from a value\r\n */\r\n private extractNode(value: any): any {\r\n if (value === undefined || value === null) {\r\n return undefined;\r\n }\r\n\r\n // Single node\r\n if (this.isNode(value)) {\r\n return value;\r\n }\r\n\r\n // Array of nodes\r\n if (Array.isArray(value)) {\r\n if (value.length === 0) {\r\n return undefined;\r\n }\r\n if (value.length === 1) {\r\n return value[0];\r\n }\r\n // Multiple nodes - use first\r\n return value[0];\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Check if two nodes are identical (same object)\r\n */\r\n private isIdentical(left: any, right: any): boolean {\r\n // If both have __id, use that\r\n if (left.__id !== undefined && right.__id !== undefined) {\r\n return left.__id === right.__id;\r\n }\r\n\r\n // Otherwise use object identity\r\n return left === right;\r\n }\r\n\r\n /**\r\n * Check if left node comes before right node in document order\r\n */\r\n private isDocumentOrderBefore(left: any, right: any): boolean {\r\n // Try to determine document order\r\n const leftPos = this.getDocumentPosition(left);\r\n const rightPos = this.getDocumentPosition(right);\r\n\r\n if (leftPos !== -1 && rightPos !== -1) {\r\n return leftPos < rightPos;\r\n }\r\n\r\n // Fallback: use depth-first traversal comparison\r\n return this.compareDocumentOrder(left, right) < 0;\r\n }\r\n\r\n /**\r\n * Check if left node comes after right node in document order\r\n */\r\n private isDocumentOrderAfter(left: any, right: any): boolean {\r\n // Try to determine document order\r\n const leftPos = this.getDocumentPosition(left);\r\n const rightPos = this.getDocumentPosition(right);\r\n\r\n if (leftPos !== -1 && rightPos !== -1) {\r\n return leftPos > rightPos;\r\n }\r\n\r\n // Fallback: use depth-first traversal comparison\r\n return this.compareDocumentOrder(left, right) > 0;\r\n }\r\n\r\n /**\r\n * Get document position if available (optional optimization)\r\n */\r\n private getDocumentPosition(node: any): number {\r\n if (node.__documentPosition !== undefined) {\r\n return node.__documentPosition;\r\n }\r\n return -1; // Not available\r\n }\r\n\r\n /**\r\n * Compare nodes by walking up to ancestors and comparing positions\r\n * Returns: -1 if left before right, 0 if same, 1 if left after right\r\n */\r\n private compareDocumentOrder(left: any, right: any): number {\r\n // If same node, they're not in document order relative to each other\r\n if (left === right) {\r\n return 0;\r\n }\r\n\r\n // Get ancestors for both nodes\r\n const leftAncestors = this.getAncestors(left);\r\n const rightAncestors = this.getAncestors(right);\r\n\r\n // Find common ancestor\r\n let i = 0;\r\n while (\r\n i < leftAncestors.length &&\r\n i < rightAncestors.length &&\r\n leftAncestors[i] === rightAncestors[i]\r\n ) {\r\n i++;\r\n }\r\n\r\n // If one is ancestor of the other\r\n if (i === leftAncestors.length) {\r\n // left is ancestor of right (comes before)\r\n return -1;\r\n }\r\n if (i === rightAncestors.length) {\r\n // right is ancestor of left (left comes after)\r\n return 1;\r\n }\r\n\r\n // Compare children of common ancestor\r\n const leftChild = leftAncestors[i];\r\n const rightChild = rightAncestors[i];\r\n\r\n const leftPosition = this.getChildPosition(leftChild);\r\n const rightPosition = this.getChildPosition(rightChild);\r\n\r\n if (leftPosition < rightPosition) {\r\n return -1;\r\n } else if (leftPosition > rightPosition) {\r\n return 1;\r\n }\r\n\r\n return 0;\r\n }\r\n\r\n /**\r\n * Get ancestors of a node (from root to node)\r\n */\r\n private getAncestors(node: any): any[] {\r\n const ancestors: any[] = [node];\r\n let current = node;\r\n\r\n while (current && current.parentNode) {\r\n current = current.parentNode;\r\n ancestors.unshift(current);\r\n }\r\n\r\n return ancestors;\r\n }\r\n\r\n /**\r\n * Get position of a node among its siblings\r\n */\r\n private getChildPosition(node: any): number {\r\n if (!node.parentNode) {\r\n return 0;\r\n }\r\n\r\n const parent = node.parentNode;\r\n const children = parent.childNodes || [];\r\n\r\n for (let i = 0; i < children.length; i++) {\r\n if (children[i] === node) {\r\n return i;\r\n }\r\n }\r\n\r\n return -1;\r\n }\r\n\r\n /**\r\n * Check if value is a node\r\n */\r\n private isNode(value: any): boolean {\r\n return value && typeof value === 'object' && ('nodeType' in value || 'nodeName' in value);\r\n }\r\n\r\n toString(): string {\r\n return `${this.left.toString()} ${this.operator} ${this.right.toString()}`;\r\n }\r\n}\r\n","import { XPathNode } from '../node';\r\nimport { NodeType } from '../constants';\r\n\r\n/**\r\n * Options for JSON-to-XML conversion\r\n */\r\nexport interface JsonToXmlOptions {\r\n /**\r\n * Allow non-strict JSON parsing. Default: false\r\n */\r\n liberal?: boolean;\r\n\r\n /**\r\n * How to handle duplicate keys: 'reject', 'use-first', or 'retain'. Default: 'reject'\r\n */\r\n duplicates?: 'reject' | 'use-first' | 'retain';\r\n\r\n /**\r\n * Whether to validate JSON schema. Default: false\r\n */\r\n validate?: boolean;\r\n\r\n /**\r\n * Whether to handle escape sequences. Default: true\r\n */\r\n escape?: boolean;\r\n\r\n /**\r\n * Custom fallback function for invalid JSON\r\n */\r\n fallback?: (json: string) => any;\r\n}\r\n\r\n/**\r\n * Converts JSON strings to XML document representations.\r\n * Implements W3C XPath 3.1 json-to-xml() function behavior.\r\n */\r\nexport class JsonToXmlConverter {\r\n private elementId: number = 0;\r\n\r\n /**\r\n * Convert JSON string to XML document node\r\n * @param jsonText - JSON string to convert\r\n * @param options - Conversion options\r\n * @returns XML document node or null if input is null/empty\r\n */\r\n convert(jsonText: string | null | undefined, options?: JsonToXmlOptions): XPathNode | null {\r\n if (jsonText === null || jsonText === undefined) {\r\n return null;\r\n }\r\n\r\n if (typeof jsonText !== 'string') {\r\n jsonText = String(jsonText);\r\n }\r\n\r\n const trimmedText = jsonText.trim();\r\n if (trimmedText === '') {\r\n return null;\r\n }\r\n\r\n try {\r\n const jsonValue = JSON.parse(trimmedText);\r\n return this.createDocumentNode(jsonValue, options);\r\n } catch (error) {\r\n // Handle fallback option\r\n if (options?.fallback && typeof options.fallback === 'function') {\r\n try {\r\n const fallbackValue = options.fallback(trimmedText);\r\n return this.createDocumentNode(fallbackValue, options);\r\n } catch (fallbackError) {\r\n return null;\r\n }\r\n }\r\n\r\n // Strict mode - return null on parse error\r\n if (!options?.liberal) {\r\n return null;\r\n }\r\n\r\n // Liberal mode - attempt lenient parsing\r\n return this.liberalParse(trimmedText, options);\r\n }\r\n }\r\n\r\n /**\r\n * Create a document node wrapping the JSON value\r\n */\r\n private createDocumentNode(value: any, options?: JsonToXmlOptions): XPathNode {\r\n this.elementId = 0; // Reset ID counter\r\n\r\n const rootElement = this.valueToElement(value, 'root', options);\r\n\r\n // Create document node wrapper\r\n const documentNode: XPathNode = {\r\n nodeType: NodeType.DOCUMENT_NODE,\r\n nodeName: '#document',\r\n localName: '#document',\r\n childNodes: [rootElement],\r\n documentElement: rootElement,\r\n };\r\n\r\n // Store reference but avoid circular parent reference\r\n rootElement.ownerDocument = documentNode;\r\n return documentNode;\r\n }\r\n\r\n /**\r\n * Convert a JSON value to an XML element\r\n */\r\n private valueToElement(\r\n value: any,\r\n elementName: string,\r\n options?: JsonToXmlOptions,\r\n parent?: XPathNode\r\n ): XPathNode {\r\n const element: XPathNode = {\r\n nodeType: NodeType.ELEMENT_NODE,\r\n nodeName: elementName,\r\n localName: elementName,\r\n childNodes: [],\r\n attributes: [],\r\n // Don't set parentNode to avoid circular reference issues with testing/serialization\r\n // parentNode: parent,\r\n };\r\n\r\n if (value === null || value === undefined) {\r\n // Empty element for null\r\n return element;\r\n }\r\n\r\n if (typeof value === 'object' && !Array.isArray(value)) {\r\n // Object: create child elements for each property\r\n const childNodes: XPathNode[] = [];\r\n const seenKeys = new Set<string>();\r\n\r\n for (const key in value) {\r\n if (Object.prototype.hasOwnProperty.call(value, key)) {\r\n // Handle duplicate keys based on options\r\n if (seenKeys.has(key)) {\r\n if (options?.duplicates === 'reject') {\r\n throw new Error(`Duplicate key: ${key}`);\r\n } else if (options?.duplicates === 'use-first') {\r\n continue;\r\n }\r\n // 'retain' - allow duplicates\r\n }\r\n seenKeys.add(key);\r\n\r\n const sanitizedKey = this.sanitizeElementName(key);\r\n const childElement = this.valueToElement(\r\n value[key],\r\n sanitizedKey,\r\n options,\r\n element\r\n );\r\n childNodes.push(childElement);\r\n }\r\n }\r\n\r\n element.childNodes = childNodes;\r\n } else if (Array.isArray(value)) {\r\n // Array: create multiple child elements with same name\r\n const childNodes: XPathNode[] = value.map((item, index) => {\r\n const itemElement = this.valueToElement(item, 'item', options, element);\r\n return itemElement;\r\n });\r\n element.childNodes = childNodes;\r\n } else if (typeof value === 'string') {\r\n // String: text content\r\n const textNode: XPathNode = {\r\n nodeType: NodeType.TEXT_NODE,\r\n nodeName: '#text',\r\n localName: '#text',\r\n textContent: value,\r\n // Don't set parentNode to avoid circular reference\r\n // parentNode: element,\r\n };\r\n element.childNodes = [textNode];\r\n element.textContent = value;\r\n } else if (typeof value === 'number') {\r\n // Number: text content\r\n const textValue = String(value);\r\n const textNode: XPathNode = {\r\n nodeType: NodeType.TEXT_NODE,\r\n nodeName: '#text',\r\n localName: '#text',\r\n textContent: textValue,\r\n // Don't set parentNode to avoid circular reference\r\n // parentNode: element,\r\n };\r\n element.childNodes = [textNode];\r\n element.textContent = textValue;\r\n } else if (typeof value === 'boolean') {\r\n // Boolean: text content\r\n const textValue = value ? 'true' : 'false';\r\n const textNode: XPathNode = {\r\n nodeType: NodeType.TEXT_NODE,\r\n nodeName: '#text',\r\n localName: '#text',\r\n textContent: textValue,\r\n // Don't set parentNode to avoid circular reference\r\n // parentNode: element,\r\n };\r\n element.childNodes = [textNode];\r\n element.textContent = textValue;\r\n }\r\n\r\n return element;\r\n }\r\n\r\n /**\r\n * Sanitize a JSON key to be a valid XML element name\r\n * XML names must start with letter/underscore and contain only valid characters\r\n */\r\n private sanitizeElementName(name: string): string {\r\n // If name is a valid XML name, return as-is\r\n if (/^[a-zA-Z_][\\w.-]*$/.test(name)) {\r\n return name;\r\n }\r\n\r\n // Replace invalid characters with underscores\r\n let sanitized = name.replace(/[^a-zA-Z0-9_.-]/g, '_');\r\n\r\n // Ensure it starts with letter or underscore\r\n if (!/^[a-zA-Z_]/.test(sanitized)) {\r\n sanitized = '_' + sanitized;\r\n }\r\n\r\n // If still empty or too similar to reserved names, use default\r\n if (!sanitized || sanitized === '_') {\r\n sanitized = 'item';\r\n }\r\n\r\n return sanitized;\r\n }\r\n\r\n /**\r\n * Liberal JSON parsing - attempts to parse loosely formatted JSON\r\n */\r\n private liberalParse(jsonText: string, options?: JsonToXmlOptions): XPathNode | null {\r\n try {\r\n // Try common lenient parsing approaches\r\n // Remove trailing commas\r\n let lenient = jsonText.replace(/,(\\s*[}\\]])/g, '$1');\r\n\r\n // Allow single quotes\r\n lenient = lenient.replace(/'/g, '\"');\r\n\r\n // Try parsing with lenient version\r\n const value = JSON.parse(lenient);\r\n return this.createDocumentNode(value, options);\r\n } catch {\r\n // If all else fails, return null\r\n return null;\r\n }\r\n }\r\n}\r\n","/**\r\n * XPath 3.0 Higher-Order Functions\r\n *\r\n * Functions that take other functions as arguments or return functions.\r\n *\r\n * Reference: https://www.w3.org/TR/xpath-functions-30/#higher-order-functions\r\n */\r\n\r\nimport { XPathContext, XPathResult, XPathFunctionItem } from '../context';\r\nimport { isFunctionItem } from '../types/function-type';\r\n\r\n/**\r\n * fn:for-each($seq as item()*, $action as function(item()) as item()*) as item()*\r\n *\r\n * Applies the function $action to every item in the sequence $seq, returning\r\n * the concatenation of the resulting sequences.\r\n *\r\n * Example: fn:for-each((1, 2, 3), function($x) { $x * 2 }) => (2, 4, 6)\r\n */\r\nexport function forEach(context: XPathContext, seq: any, action: any): XPathResult {\r\n if (!isFunctionItem(action)) {\r\n throw new Error('fn:for-each: second argument must be a function');\r\n }\r\n\r\n const funcItem = action as XPathFunctionItem;\r\n\r\n // Handle empty sequence\r\n if (seq === null || seq === undefined) {\r\n return [];\r\n }\r\n\r\n // Ensure seq is an array\r\n const items = Array.isArray(seq) ? seq : [seq];\r\n\r\n // Apply function to each item and flatten results\r\n const results: any[] = [];\r\n for (const item of items) {\r\n const result = funcItem.implementation(item);\r\n if (Array.isArray(result)) {\r\n results.push(...result);\r\n } else if (result !== null && result !== undefined) {\r\n results.push(result);\r\n }\r\n }\r\n\r\n return results.length === 0 ? [] : results;\r\n}\r\n\r\n/**\r\n * fn:filter($seq as item()*, $predicate as function(item()) as xs:boolean) as item()*\r\n *\r\n * Returns those items from the sequence $seq for which the function $predicate\r\n * returns true.\r\n *\r\n * Example: fn:filter((1, 2, 3, 4, 5), function($x) { $x mod 2 = 0 }) => (2, 4)\r\n */\r\nexport function filter(context: XPathContext, seq: any, predicate: any): XPathResult {\r\n if (!isFunctionItem(predicate)) {\r\n throw new Error('fn:filter: second argument must be a function');\r\n }\r\n\r\n const funcItem = predicate as XPathFunctionItem;\r\n\r\n // Handle empty sequence\r\n if (seq === null || seq === undefined) {\r\n return [];\r\n }\r\n\r\n // Ensure seq is an array\r\n const items = Array.isArray(seq) ? seq : [seq];\r\n\r\n // Filter items based on predicate\r\n const results = items.filter((item) => {\r\n const result = funcItem.implementation(item);\r\n // Convert result to boolean\r\n return Boolean(result);\r\n });\r\n\r\n return results.length === 0 ? [] : results;\r\n}\r\n\r\n/**\r\n * fn:fold-left($seq as item()*, $zero as item()*, $f as function(item()*, item()) as item()*) as item()*\r\n *\r\n * Processes the items in $seq from left to right, applying the function $f\r\n * to each item in turn, together with an accumulated result.\r\n *\r\n * Example: fn:fold-left((1, 2, 3, 4), 0, function($acc, $x) { $acc + $x }) => 10\r\n */\r\nexport function foldLeft(context: XPathContext, seq: any, zero: any, f: any): XPathResult {\r\n if (!isFunctionItem(f)) {\r\n throw new Error('fn:fold-left: third argument must be a function');\r\n }\r\n\r\n const funcItem = f as XPathFunctionItem;\r\n\r\n // Handle empty sequence - return zero value\r\n if (seq === null || seq === undefined) {\r\n return zero;\r\n }\r\n\r\n // Ensure seq is an array\r\n const items = Array.isArray(seq) ? seq : [seq];\r\n\r\n // Fold from left\r\n let accumulator = zero;\r\n for (const item of items) {\r\n accumulator = funcItem.implementation(accumulator, item);\r\n }\r\n\r\n return accumulator;\r\n}\r\n\r\n/**\r\n * fn:fold-right($seq as item()*, $zero as item()*, $f as function(item(), item()*) as item()*) as item()*\r\n *\r\n * Processes the items in $seq from right to left, applying the function $f\r\n * to each item in turn, together with an accumulated result.\r\n *\r\n * Example: fn:fold-right((1, 2, 3, 4), 0, function($x, $acc) { $acc + $x }) => 10\r\n */\r\nexport function foldRight(context: XPathContext, seq: any, zero: any, f: any): XPathResult {\r\n if (!isFunctionItem(f)) {\r\n throw new Error('fn:fold-right: third argument must be a function');\r\n }\r\n\r\n const funcItem = f as XPathFunctionItem;\r\n\r\n // Handle empty sequence - return zero value\r\n if (seq === null || seq === undefined) {\r\n return zero;\r\n }\r\n\r\n // Ensure seq is an array\r\n const items = Array.isArray(seq) ? seq : [seq];\r\n\r\n // Fold from right\r\n let accumulator = zero;\r\n for (let i = items.length - 1; i >= 0; i--) {\r\n accumulator = funcItem.implementation(items[i], accumulator);\r\n }\r\n\r\n return accumulator;\r\n}\r\n\r\n/**\r\n * fn:for-each-pair($seq1 as item()*, $seq2 as item()*, $action as function(item(), item()) as item()*) as item()*\r\n *\r\n * Applies the function $action to successive pairs of items taken one from $seq1\r\n * and one from $seq2, returning the concatenation of the resulting sequences.\r\n *\r\n * Example: fn:for-each-pair((1, 2, 3), (4, 5, 6), function($a, $b) { $a + $b }) => (5, 7, 9)\r\n */\r\nexport function forEachPair(context: XPathContext, seq1: any, seq2: any, action: any): XPathResult {\r\n if (!isFunctionItem(action)) {\r\n throw new Error('fn:for-each-pair: third argument must be a function');\r\n }\r\n\r\n const funcItem = action as XPathFunctionItem;\r\n\r\n // Handle empty sequences\r\n if (seq1 === null || seq1 === undefined || seq2 === null || seq2 === undefined) {\r\n return [];\r\n }\r\n\r\n // Ensure both are arrays\r\n const items1 = Array.isArray(seq1) ? seq1 : [seq1];\r\n const items2 = Array.isArray(seq2) ? seq2 : [seq2];\r\n\r\n // Process pairs up to the length of the shorter sequence\r\n const results: any[] = [];\r\n const minLength = Math.min(items1.length, items2.length);\r\n\r\n for (let i = 0; i < minLength; i++) {\r\n const result = funcItem.implementation(items1[i], items2[i]);\r\n if (Array.isArray(result)) {\r\n results.push(...result);\r\n } else if (result !== null && result !== undefined) {\r\n results.push(result);\r\n }\r\n }\r\n\r\n return results.length === 0 ? [] : results;\r\n}\r\n/**\r\n * fn:apply($function as function(*) as item()*, $array as array(*)) as item()*\r\n *\r\n * Calls the function $function with arguments taken from the array $array.\r\n * For now, we accept an array or sequence of arguments.\r\n *\r\n * Example: fn:apply(fn:concat#3, [\"a\", \"b\", \"c\"]) => \"abc\"\r\n */\r\nexport function apply(context: XPathContext, func: any, array: any): XPathResult {\r\n if (!isFunctionItem(func)) {\r\n throw new Error('fn:apply: first argument must be a function');\r\n }\r\n\r\n const funcItem = func as XPathFunctionItem;\r\n\r\n // Handle empty array\r\n if (array === null || array === undefined) {\r\n return funcItem.implementation();\r\n }\r\n\r\n // Ensure array is an array\r\n const args = Array.isArray(array) ? array : [array];\r\n\r\n // Apply function with arguments\r\n return funcItem.implementation(...args);\r\n}\r\n\r\n/**\r\n * fn:function-name($func as function(*)) as xs:QName?\r\n *\r\n * Returns the name of the function, or an empty sequence if it's anonymous.\r\n *\r\n * Example: fn:function-name(fn:concat#2) => QName(\"http://www.w3.org/2005/xpath-functions\", \"concat\")\r\n */\r\nexport function functionName(context: XPathContext, func: any): XPathResult {\r\n if (!isFunctionItem(func)) {\r\n throw new Error('fn:function-name: argument must be a function');\r\n }\r\n\r\n const funcItem = func as XPathFunctionItem;\r\n\r\n // Return the name if available, otherwise empty sequence\r\n if (funcItem.name) {\r\n // Return as QName string (simplified - in full implementation would return QName object)\r\n if (funcItem.namespace) {\r\n return `Q{${funcItem.namespace}}${funcItem.name}`;\r\n }\r\n return funcItem.name;\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * fn:function-arity($func as function(*)) as xs:integer\r\n *\r\n * Returns the arity (number of parameters) of the function.\r\n *\r\n * Example: fn:function-arity(fn:concat#2) => 2\r\n */\r\nexport function functionArity(context: XPathContext, func: any): XPathResult {\r\n if (!isFunctionItem(func)) {\r\n throw new Error('fn:function-arity: argument must be a function');\r\n }\r\n\r\n const funcItem = func as XPathFunctionItem;\r\n return funcItem.arity;\r\n}\r\n","/**\r\n * XPath 3.0 Math Functions\r\n *\r\n * Implements functions from the math namespace:\r\n * http://www.w3.org/2005/xpath-functions/math\r\n *\r\n * Reference: https://www.w3.org/TR/xpath-functions-30/#math-functions\r\n */\r\n\r\nimport { XPathContext } from '../context';\r\n\r\nconst MATH_NAMESPACE = 'http://www.w3.org/2005/xpath-functions/math';\r\n\r\n/**\r\n * math:pi() - Returns the mathematical constant π\r\n * @returns The value of π (approximately 3.141592653589793)\r\n */\r\nexport function pi(context: XPathContext): number {\r\n return Math.PI;\r\n}\r\n\r\n/**\r\n * math:exp($arg) - Returns e raised to the power of $arg\r\n * @param context XPath context\r\n * @param arg The exponent\r\n * @returns e^arg\r\n */\r\nexport function exp(context: XPathContext, arg: any): number {\r\n const value = toNumber(arg);\r\n return Math.exp(value);\r\n}\r\n\r\n/**\r\n * math:exp10($arg) - Returns 10 raised to the power of $arg\r\n * @param context XPath context\r\n * @param arg The exponent\r\n * @returns 10^arg\r\n */\r\nexport function exp10(context: XPathContext, arg: any): number {\r\n const value = toNumber(arg);\r\n return Math.pow(10, value);\r\n}\r\n\r\n/**\r\n * math:log($arg) - Returns the natural logarithm of $arg\r\n * @param context XPath context\r\n * @param arg The value\r\n * @returns Natural logarithm (base e) of arg\r\n */\r\nexport function log(context: XPathContext, arg: any): number {\r\n const value = toNumber(arg);\r\n return Math.log(value);\r\n}\r\n\r\n/**\r\n * math:log10($arg) - Returns the base-10 logarithm of $arg\r\n * @param context XPath context\r\n * @param arg The value\r\n * @returns Base-10 logarithm of arg\r\n */\r\nexport function log10(context: XPathContext, arg: any): number {\r\n const value = toNumber(arg);\r\n return Math.log10(value);\r\n}\r\n\r\n/**\r\n * math:pow($x, $y) - Returns $x raised to the power of $y\r\n * @param context XPath context\r\n * @param x The base\r\n * @param y The exponent\r\n * @returns x^y\r\n */\r\nexport function pow(context: XPathContext, x: any, y: any): number {\r\n const base = toNumber(x);\r\n const exponent = toNumber(y);\r\n return Math.pow(base, exponent);\r\n}\r\n\r\n/**\r\n * math:sqrt($arg) - Returns the square root of $arg\r\n * @param context XPath context\r\n * @param arg The value\r\n * @returns Square root of arg\r\n */\r\nexport function sqrt(context: XPathContext, arg: any): number {\r\n const value = toNumber(arg);\r\n return Math.sqrt(value);\r\n}\r\n\r\n/**\r\n * math:sin($arg) - Returns the sine of $arg (in radians)\r\n * @param context XPath context\r\n * @param arg The angle in radians\r\n * @returns Sine of arg\r\n */\r\nexport function sin(context: XPathContext, arg: any): number {\r\n const value = toNumber(arg);\r\n return Math.sin(value);\r\n}\r\n\r\n/**\r\n * math:cos($arg) - Returns the cosine of $arg (in radians)\r\n * @param context XPath context\r\n * @param arg The angle in radians\r\n * @returns Cosine of arg\r\n */\r\nexport function cos(context: XPathContext, arg: any): number {\r\n const value = toNumber(arg);\r\n return Math.cos(value);\r\n}\r\n\r\n/**\r\n * math:tan($arg) - Returns the tangent of $arg (in radians)\r\n * @param context XPath context\r\n * @param arg The angle in radians\r\n * @returns Tangent of arg\r\n */\r\nexport function tan(context: XPathContext, arg: any): number {\r\n const value = toNumber(arg);\r\n return Math.tan(value);\r\n}\r\n\r\n/**\r\n * math:asin($arg) - Returns the arc sine of $arg\r\n * @param context XPath context\r\n * @param arg The value (must be in range [-1, 1])\r\n * @returns Arc sine of arg in radians\r\n */\r\nexport function asin(context: XPathContext, arg: any): number {\r\n const value = toNumber(arg);\r\n return Math.asin(value);\r\n}\r\n\r\n/**\r\n * math:acos($arg) - Returns the arc cosine of $arg\r\n * @param context XPath context\r\n * @param arg The value (must be in range [-1, 1])\r\n * @returns Arc cosine of arg in radians\r\n */\r\nexport function acos(context: XPathContext, arg: any): number {\r\n const value = toNumber(arg);\r\n return Math.acos(value);\r\n}\r\n\r\n/**\r\n * math:atan($arg) - Returns the arc tangent of $arg\r\n * @param context XPath context\r\n * @param arg The value\r\n * @returns Arc tangent of arg in radians\r\n */\r\nexport function atan(context: XPathContext, arg: any): number {\r\n const value = toNumber(arg);\r\n return Math.atan(value);\r\n}\r\n\r\n/**\r\n * math:atan2($y, $x) - Returns the angle (in radians) from the X axis to the point (x,y)\r\n * @param context XPath context\r\n * @param y The y-coordinate\r\n * @param x The x-coordinate\r\n * @returns Arc tangent of y/x in radians, range [-π, π]\r\n */\r\nexport function atan2(context: XPathContext, y: any, x: any): number {\r\n const yValue = toNumber(y);\r\n const xValue = toNumber(x);\r\n return Math.atan2(yValue, xValue);\r\n}\r\n\r\n/**\r\n * Helper function to convert a value to a number\r\n * Handles empty sequences and converts basic values\r\n */\r\nfunction toNumber(value: any): number {\r\n // Handle null/undefined/empty sequence\r\n if (value === null || value === undefined) {\r\n return NaN;\r\n }\r\n\r\n // Handle arrays (take first item or return NaN for empty)\r\n if (Array.isArray(value)) {\r\n if (value.length === 0) {\r\n return NaN;\r\n }\r\n return toNumber(value[0]);\r\n }\r\n\r\n // Convert to number directly\r\n const num = Number(value);\r\n return num;\r\n}\r\n\r\n// Export all math functions\r\nexport const MATH_FUNCTIONS = {\r\n pi,\r\n exp,\r\n exp10,\r\n log,\r\n log10,\r\n pow,\r\n sqrt,\r\n sin,\r\n cos,\r\n tan,\r\n asin,\r\n acos,\r\n atan,\r\n atan2,\r\n};\r\n","/**\r\n * XPath 2.0 Sequence Functions\r\n *\r\n * Reference: https://www.w3.org/TR/xpath-functions/#sequence-functions\r\n */\r\n\r\nimport { XPathResult } from '../context';\r\nimport { typeMismatch } from '../errors';\r\n\r\n/**\r\n * fn:empty($arg as item()*) as xs:boolean\r\n * Returns true if the argument is an empty sequence.\r\n */\r\nexport function empty(arg: XPathResult): boolean {\r\n if (arg === null || arg === undefined) return true;\r\n if (Array.isArray(arg)) return arg.length === 0;\r\n return false;\r\n}\r\n\r\n/**\r\n * fn:exists($arg as item()*) as xs:boolean\r\n * Returns true if the argument is a non-empty sequence.\r\n */\r\nexport function exists(arg: XPathResult): boolean {\r\n return !empty(arg);\r\n}\r\n\r\n/**\r\n * fn:head($arg as item()*) as item()?\r\n * Returns the first item in a sequence, or empty sequence if empty.\r\n */\r\nexport function head(arg: XPathResult): XPathResult {\r\n if (arg === null || arg === undefined) return null;\r\n if (Array.isArray(arg)) {\r\n return arg.length > 0 ? arg[0] : null;\r\n }\r\n return arg;\r\n}\r\n\r\n/**\r\n * fn:tail($arg as item()*) as item()*\r\n * Returns all items except the first in a sequence.\r\n */\r\nexport function tail(arg: XPathResult): XPathResult[] {\r\n if (arg === null || arg === undefined) return [];\r\n if (Array.isArray(arg)) {\r\n return arg.length > 1 ? arg.slice(1) : [];\r\n }\r\n return [];\r\n}\r\n\r\n/**\r\n * fn:insert-before($target as item()*, $position as xs:integer, $inserts as item()*) as item()*\r\n * Returns a new sequence with items inserted before the specified position.\r\n */\r\nexport function insertBefore(\r\n target: XPathResult,\r\n position: XPathResult,\r\n inserts: XPathResult\r\n): XPathResult[] {\r\n const targetSeq = toSequence(target);\r\n const insertSeq = toSequence(inserts);\r\n let pos = Math.floor(Number(position));\r\n\r\n // Adjust position (XPath is 1-based)\r\n if (pos < 1) pos = 1;\r\n if (pos > targetSeq.length) pos = targetSeq.length + 1;\r\n\r\n const result: XPathResult[] = [];\r\n for (let i = 0; i < targetSeq.length; i++) {\r\n if (i === pos - 1) {\r\n result.push(...insertSeq);\r\n }\r\n result.push(targetSeq[i]);\r\n }\r\n\r\n // If position is after the end\r\n if (pos > targetSeq.length) {\r\n result.push(...insertSeq);\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * fn:remove($target as item()*, $position as xs:integer) as item()*\r\n * Returns a new sequence with the item at the specified position removed.\r\n */\r\nexport function remove(target: XPathResult, position: XPathResult): XPathResult[] {\r\n const targetSeq = toSequence(target);\r\n const pos = Math.floor(Number(position));\r\n\r\n // Position out of range: return original sequence\r\n if (pos < 1 || pos > targetSeq.length) {\r\n return targetSeq;\r\n }\r\n\r\n const result: XPathResult[] = [];\r\n for (let i = 0; i < targetSeq.length; i++) {\r\n if (i !== pos - 1) {\r\n result.push(targetSeq[i]);\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * fn:reverse($arg as item()*) as item()*\r\n * Reverses the order of items in a sequence.\r\n */\r\nexport function reverse(arg: XPathResult): XPathResult[] {\r\n const seq = toSequence(arg);\r\n return seq.slice().reverse();\r\n}\r\n\r\n/**\r\n * fn:subsequence($sourceSeq as item()*, $startingLoc as xs:double) as item()*\r\n * fn:subsequence($sourceSeq as item()*, $startingLoc as xs:double, $length as xs:double) as item()*\r\n * Returns a contiguous sequence of items from a source sequence.\r\n */\r\nexport function subsequence(\r\n sourceSeq: XPathResult,\r\n startingLoc: XPathResult,\r\n length?: XPathResult\r\n): XPathResult[] {\r\n const seq = toSequence(sourceSeq);\r\n let start = Number(startingLoc);\r\n\r\n // Handle special cases\r\n if (isNaN(start)) return [];\r\n\r\n // XPath uses 1-based indexing and rounds\r\n start = Math.round(start);\r\n\r\n if (length === undefined) {\r\n // No length specified: return from start to end\r\n if (start < 1) start = 1;\r\n if (start > seq.length) return [];\r\n return seq.slice(start - 1);\r\n }\r\n\r\n let len = Number(length);\r\n if (isNaN(len) || len < 0) return [];\r\n\r\n len = Math.round(len);\r\n\r\n // Handle negative start\r\n if (start < 1) {\r\n len = len + start - 1;\r\n start = 1;\r\n }\r\n\r\n if (len <= 0 || start > seq.length) return [];\r\n\r\n return seq.slice(start - 1, start - 1 + len);\r\n}\r\n\r\n/**\r\n * fn:unordered($sourceSeq as item()*) as item()*\r\n * Returns the items of $sourceSeq in an implementation-dependent order.\r\n * In this implementation, we simply return them in the same order.\r\n */\r\nexport function unordered(sourceSeq: XPathResult): XPathResult[] {\r\n return toSequence(sourceSeq);\r\n}\r\n\r\n/**\r\n * fn:distinct-values($arg as xs:anyAtomicType*) as xs:anyAtomicType*\r\n * fn:distinct-values($arg as xs:anyAtomicType*, $collation as xs:string) as xs:anyAtomicType*\r\n * Returns the distinct values from a sequence.\r\n */\r\nexport function distinctValues(arg: XPathResult, collation?: XPathResult): XPathResult[] {\r\n const seq = toSequence(arg);\r\n if (seq.length === 0) return [];\r\n\r\n const seen = new Set<string>();\r\n const result: XPathResult[] = [];\r\n\r\n for (const item of seq) {\r\n // Create a comparable key\r\n const key = getComparisonKey(item);\r\n if (!seen.has(key)) {\r\n seen.add(key);\r\n result.push(atomize(item));\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * fn:index-of($seqParam as xs:anyAtomicType*, $srchParam as xs:anyAtomicType) as xs:integer*\r\n * fn:index-of($seqParam as xs:anyAtomicType*, $srchParam as xs:anyAtomicType, $collation as xs:string) as xs:integer*\r\n * Returns a sequence of integers giving the positions of matching items.\r\n */\r\nexport function indexOf(\r\n seqParam: XPathResult,\r\n srchParam: XPathResult,\r\n collation?: XPathResult\r\n): number[] {\r\n const seq = toSequence(seqParam);\r\n if (seq.length === 0) return [];\r\n\r\n const searchKey = getComparisonKey(srchParam);\r\n const result: number[] = [];\r\n\r\n for (let i = 0; i < seq.length; i++) {\r\n const itemKey = getComparisonKey(seq[i]);\r\n if (itemKey === searchKey) {\r\n result.push(i + 1); // 1-based index\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * fn:deep-equal($parameter1 as item()*, $parameter2 as item()*) as xs:boolean\r\n * fn:deep-equal($parameter1 as item()*, $parameter2 as item()*, $collation as xs:string) as xs:boolean\r\n * Returns true if the two sequences are deep-equal.\r\n */\r\nexport function deepEqual(\r\n parameter1: XPathResult,\r\n parameter2: XPathResult,\r\n collation?: XPathResult\r\n): boolean {\r\n const seq1 = toSequence(parameter1);\r\n const seq2 = toSequence(parameter2);\r\n\r\n if (seq1.length !== seq2.length) return false;\r\n\r\n for (let i = 0; i < seq1.length; i++) {\r\n if (!itemsDeepEqual(seq1[i], seq2[i])) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n\r\n/**\r\n * fn:zero-or-one($arg as item()*) as item()?\r\n * Returns $arg if it contains zero or one items. Otherwise raises an error.\r\n */\r\nexport function zeroOrOne(arg: XPathResult): XPathResult {\r\n const seq = toSequence(arg);\r\n if (seq.length > 1) {\r\n throw typeMismatch('zero or one item', `sequence of ${seq.length} items`, 'fn:zero-or-one');\r\n }\r\n return seq.length === 0 ? null : seq[0];\r\n}\r\n\r\n/**\r\n * fn:one-or-more($arg as item()*) as item()+\r\n * Returns $arg if it contains one or more items. Otherwise raises an error.\r\n */\r\nexport function oneOrMore(arg: XPathResult): XPathResult[] {\r\n const seq = toSequence(arg);\r\n if (seq.length === 0) {\r\n throw typeMismatch('one or more items', 'empty sequence', 'fn:one-or-more');\r\n }\r\n return seq;\r\n}\r\n\r\n/**\r\n * fn:exactly-one($arg as item()*) as item()\r\n * Returns $arg if it contains exactly one item. Otherwise raises an error.\r\n */\r\nexport function exactlyOne(arg: XPathResult): XPathResult {\r\n const seq = toSequence(arg);\r\n if (seq.length !== 1) {\r\n throw typeMismatch(\r\n 'exactly one item',\r\n seq.length === 0 ? 'empty sequence' : `sequence of ${seq.length} items`,\r\n 'fn:exactly-one'\r\n );\r\n }\r\n return seq[0];\r\n}\r\n\r\n/**\r\n * fn:count($arg as item()*) as xs:integer\r\n * Returns the number of items in a sequence.\r\n */\r\nexport function count(arg: XPathResult): number {\r\n if (arg === null || arg === undefined) return 0;\r\n if (Array.isArray(arg)) return arg.length;\r\n return 1;\r\n}\r\n\r\n/**\r\n * fn:sum($arg as xs:anyAtomicType*) as xs:anyAtomicType\r\n * fn:sum($arg as xs:anyAtomicType*, $zero as xs:anyAtomicType?) as xs:anyAtomicType?\r\n * Returns the sum of the values in the input sequence.\r\n */\r\nexport function sum(arg: XPathResult, zero?: XPathResult): number {\r\n const seq = toSequence(arg);\r\n if (seq.length === 0) {\r\n return zero !== undefined ? Number(zero) : 0;\r\n }\r\n\r\n let total = 0;\r\n for (const item of seq) {\r\n const value = atomize(item);\r\n const num = Number(value);\r\n if (isNaN(num)) {\r\n return NaN;\r\n }\r\n total += num;\r\n }\r\n\r\n return total;\r\n}\r\n\r\n// ============================================================================\r\n// Helper Functions\r\n// ============================================================================\r\n\r\n/**\r\n * Converts a value to a sequence (array).\r\n */\r\nfunction toSequence(value: XPathResult): XPathResult[] {\r\n if (value === null || value === undefined) return [];\r\n if (Array.isArray(value)) return value as XPathResult[];\r\n return [value];\r\n}\r\n\r\n/**\r\n * Gets a comparable key for a value.\r\n */\r\nfunction getComparisonKey(value: XPathResult): string {\r\n if (value === null || value === undefined) return 'null';\r\n\r\n const atomized = atomize(value);\r\n\r\n if (typeof atomized === 'number') {\r\n if (isNaN(atomized)) return 'NaN';\r\n return `n:${atomized}`;\r\n }\r\n if (typeof atomized === 'boolean') {\r\n return `b:${atomized}`;\r\n }\r\n return `s:${String(atomized)}`;\r\n}\r\n\r\n/**\r\n * Atomizes a value (extracts the typed value).\r\n */\r\nfunction atomize(value: XPathResult): string | number | boolean {\r\n if (value === null || value === undefined) return '';\r\n if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'string') {\r\n return value;\r\n }\r\n if (typeof value === 'object' && 'textContent' in value) {\r\n return (value as { textContent?: string }).textContent ?? '';\r\n }\r\n if (Array.isArray(value)) {\r\n return value.length > 0 ? atomize(value[0]) : '';\r\n }\r\n return String(value);\r\n}\r\n\r\n/**\r\n * Compares two items for deep equality.\r\n */\r\nfunction itemsDeepEqual(item1: XPathResult, item2: XPathResult): boolean {\r\n // Both null/undefined\r\n if ((item1 === null || item1 === undefined) && (item2 === null || item2 === undefined)) {\r\n return true;\r\n }\r\n\r\n // One null, other not\r\n if (item1 === null || item1 === undefined || item2 === null || item2 === undefined) {\r\n return false;\r\n }\r\n\r\n // Both nodes\r\n if (isNode(item1) && isNode(item2)) {\r\n return nodesDeepEqual(item1, item2);\r\n }\r\n\r\n // Both atomic values\r\n const atom1 = atomize(item1);\r\n const atom2 = atomize(item2);\r\n\r\n // NaN handling\r\n if (typeof atom1 === 'number' && typeof atom2 === 'number') {\r\n if (isNaN(atom1) && isNaN(atom2)) return true;\r\n }\r\n\r\n return atom1 === atom2;\r\n}\r\n\r\n/**\r\n * Checks if a value is a node.\r\n */\r\nfunction isNode(value: XPathResult): boolean {\r\n return typeof value === 'object' && value !== null && 'nodeType' in value;\r\n}\r\n\r\n/**\r\n * Deep equality comparison for nodes.\r\n */\r\nfunction nodesDeepEqual(node1: XPathResult, node2: XPathResult): boolean {\r\n const n1 = node1 as {\r\n nodeType?: number;\r\n nodeName?: string;\r\n textContent?: string;\r\n childNodes?: any[];\r\n };\r\n const n2 = node2 as {\r\n nodeType?: number;\r\n nodeName?: string;\r\n textContent?: string;\r\n childNodes?: any[];\r\n };\r\n\r\n // Different node types\r\n if (n1.nodeType !== n2.nodeType) return false;\r\n\r\n // Different names\r\n if (n1.nodeName !== n2.nodeName) return false;\r\n\r\n // For text, comment, etc.: compare text content\r\n if (n1.nodeType === 3 || n1.nodeType === 8) {\r\n // Text or Comment\r\n return n1.textContent === n2.textContent;\r\n }\r\n\r\n // For elements: compare children\r\n if (n1.nodeType === 1) {\r\n const children1 = n1.childNodes ?? [];\r\n const children2 = n2.childNodes ?? [];\r\n\r\n if (children1.length !== children2.length) return false;\r\n\r\n for (let i = 0; i < children1.length; i++) {\r\n if (!nodesDeepEqual(children1[i], children2[i])) {\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n","/**\r\n * XPath 3.0 Sequence Functions\r\n *\r\n * Implements additional sequence manipulation functions for XPath 3.0:\r\n * https://www.w3.org/TR/xpath-functions-30/#sequence\r\n */\r\n\r\nimport { XPathContext, XPathResult } from '../context';\r\nimport { XPathNode } from '../node';\r\nimport { head as seqHead, tail as seqTail } from './sequence-functions';\r\n\r\n/**\r\n * fn:innermost($nodes as node()*) as node()*\r\n * Returns nodes that have no descendant in the input sequence.\r\n * Most deeply nested nodes (no children in the input).\r\n */\r\nexport function innermost(context: XPathContext, nodes: any): XPathResult {\r\n const nodeList = Array.isArray(nodes) ? nodes : nodes ? [nodes] : [];\r\n\r\n if (nodeList.length === 0) {\r\n return [];\r\n }\r\n\r\n // For each node, check if any descendant is in the set\r\n return nodeList.filter((node) => {\r\n // Skip non-nodes\r\n if (!isNode(node)) {\r\n return false;\r\n }\r\n\r\n // Check if any other node in the list is a descendant\r\n return !nodeList.some((otherNode) => {\r\n if (!isNode(otherNode) || node === otherNode) {\r\n return false;\r\n }\r\n // Check if otherNode is a descendant of node\r\n return isAncestor(node, otherNode);\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * fn:outermost($nodes as node()*) as node()*\r\n * Returns nodes that have no ancestor in the input sequence.\r\n * Least deeply nested nodes (no parents in the input).\r\n */\r\nexport function outermost(context: XPathContext, nodes: any): XPathResult {\r\n const nodeList = Array.isArray(nodes) ? nodes : nodes ? [nodes] : [];\r\n\r\n if (nodeList.length === 0) {\r\n return [];\r\n }\r\n\r\n // For each node, check if any ancestor is in the set\r\n return nodeList.filter((node) => {\r\n // Skip non-nodes\r\n if (!isNode(node)) {\r\n return false;\r\n }\r\n\r\n // Check if any other node in the list is an ancestor\r\n return !nodeList.some((otherNode) => {\r\n if (!isNode(otherNode) || node === otherNode) {\r\n return false;\r\n }\r\n // Check if otherNode is an ancestor of node\r\n return isAncestor(otherNode, node);\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * fn:sort($input as item()*, $collation as xs:string?, $key as function(item()) as xs:anyAtomicType*) as item()*\r\n * Sorts a sequence with optional collation and key function.\r\n *\r\n * For now, we implement the basic version without collation support.\r\n * Key function version will be added when needed.\r\n */\r\nexport function sort(context: XPathContext, input: any, collation?: any, keyFn?: any): XPathResult {\r\n const items = Array.isArray(input) ? input : input ? [input] : [];\r\n\r\n if (items.length <= 1) {\r\n return input;\r\n }\r\n\r\n // Create array with index tracking for stable sort\r\n const indexed = items.map((item, index) => ({ item, index }));\r\n\r\n // Sort based on whether we have a key function\r\n if (keyFn && typeof keyFn === 'object' && keyFn.__isFunctionItem) {\r\n // Sort using key function\r\n indexed.sort((a, b) => {\r\n const keyA = keyFn.implementation(a.item);\r\n const keyB = keyFn.implementation(b.item);\r\n return compareValues(keyA, keyB);\r\n });\r\n } else {\r\n // Direct comparison sort\r\n indexed.sort((a, b) => {\r\n return compareValues(a.item, b.item);\r\n });\r\n }\r\n\r\n return indexed.map((x) => x.item);\r\n}\r\n\r\n/**\r\n * Helper: Check if value is a node\r\n */\r\nfunction isNode(value: any): boolean {\r\n return (\r\n value !== null &&\r\n value !== undefined &&\r\n typeof value === 'object' &&\r\n ('nodeType' in value || 'localName' in value)\r\n );\r\n}\r\n\r\n/**\r\n * Helper: Check if first node is an ancestor of second node\r\n */\r\nfunction isAncestor(potential: any, node: any): boolean {\r\n if (!isNode(potential) || !isNode(node)) {\r\n return false;\r\n }\r\n\r\n // Check parent chain with cycle detection\r\n let current = node.parent || node.parentNode;\r\n let depth = 0;\r\n const MAX_DEPTH = 10000;\r\n const visited = new Set<any>();\r\n\r\n while (current && depth < MAX_DEPTH) {\r\n if (visited.has(current)) {\r\n // Circular reference detected\r\n break;\r\n }\r\n visited.add(current);\r\n\r\n if (current === potential) {\r\n return true;\r\n }\r\n\r\n current = current.parent || current.parentNode;\r\n depth++;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Helper: Compare two values for sorting\r\n */\r\nfunction compareValues(a: any, b: any): number {\r\n // Handle arrays (take first item)\r\n if (Array.isArray(a) && a.length > 0) {\r\n a = a[0];\r\n }\r\n if (Array.isArray(b) && b.length > 0) {\r\n b = b[0];\r\n }\r\n\r\n // Handle null/undefined\r\n if (a == null && b == null) return 0;\r\n if (a == null) return -1;\r\n if (b == null) return 1;\r\n\r\n // Numeric comparison\r\n if (typeof a === 'number' && typeof b === 'number') {\r\n return a - b;\r\n }\r\n\r\n // String comparison\r\n const aStr = String(a);\r\n const bStr = String(b);\r\n return aStr.localeCompare(bStr);\r\n}\r\n\r\n// Export all sequence functions\r\nexport const SEQUENCE_FUNCTIONS_30 = {\r\n head: seqHead,\r\n tail: seqTail,\r\n innermost,\r\n outermost,\r\n sort,\r\n};\r\n","/**\r\n * XPath 3.0 Environment Functions\r\n *\r\n * Implements environment variable access functions:\r\n * https://www.w3.org/TR/xpath-functions-30/#environment\r\n */\r\n\r\nimport { XPathContext, XPathResult } from '../context';\r\n\r\n/**\r\n * fn:environment-variable($name as xs:string) as xs:string?\r\n * Returns the value of an environment variable, or empty if not found.\r\n */\r\nexport function environmentVariable(context: XPathContext, name: any): XPathResult {\r\n const varName = String(name);\r\n\r\n // In Node.js, access process.env\r\n if (typeof process !== 'undefined' && process.env) {\r\n const value = process.env[varName];\r\n return value !== undefined ? value : null;\r\n }\r\n\r\n // In browser environment, return null (no env vars available)\r\n return null;\r\n}\r\n\r\n/**\r\n * fn:available-environment-variables() as xs:string*\r\n * Returns a sequence of all available environment variable names.\r\n */\r\nexport function availableEnvironmentVariables(context: XPathContext): XPathResult {\r\n // In Node.js, return keys from process.env\r\n if (typeof process !== 'undefined' && process.env) {\r\n return Object.keys(process.env);\r\n }\r\n\r\n // In browser environment, return empty sequence\r\n return [];\r\n}\r\n\r\n// Export all environment functions\r\nexport const ENVIRONMENT_FUNCTIONS = {\r\n 'environment-variable': environmentVariable,\r\n 'available-environment-variables': availableEnvironmentVariables,\r\n};\r\n","/**\r\n * XPath 3.0 String Functions (Additional)\r\n *\r\n * Implements additional string manipulation functions for XPath 3.0:\r\n * https://www.w3.org/TR/xpath-functions-30/#string-functions\r\n */\r\n\r\nimport { XPathContext, XPathResult } from '../context';\r\n\r\n/**\r\n * fn:analyze-string($input as xs:string?, $pattern as xs:string) as element()*\r\n * fn:analyze-string($input as xs:string?, $pattern as xs:string, $flags as xs:string) as element()*\r\n *\r\n * Analyzes a string using a regular expression and returns a sequence of elements.\r\n * For now, we return a simplified result as building proper XML elements requires more infrastructure.\r\n * Basic implementation: Returns array of match and non-match objects.\r\n */\r\nexport function analyzeString(\r\n context: XPathContext,\r\n input: any,\r\n pattern: any,\r\n flags?: any\r\n): XPathResult {\r\n const str = input === null || input === undefined ? '' : String(input);\r\n const pat = String(pattern);\r\n const flgs = flags ? String(flags) : '';\r\n\r\n try {\r\n // Build regex with flags\r\n let regexFlags = '';\r\n if (flgs.includes('i')) regexFlags += 'i';\r\n if (flgs.includes('m')) regexFlags += 'm';\r\n if (flgs.includes('s')) regexFlags += 's';\r\n if (flgs.includes('x')) regexFlags += 'x'; // Verbose flag (minimal support)\r\n\r\n const regex = new RegExp(pat, regexFlags + 'g');\r\n const result: any[] = [];\r\n let lastIndex = 0;\r\n let match;\r\n\r\n while ((match = regex.exec(str)) !== null) {\r\n // Add non-match text before this match\r\n if (match.index > lastIndex) {\r\n result.push({\r\n type: 'non-match',\r\n value: str.substring(lastIndex, match.index),\r\n });\r\n }\r\n\r\n // Add the match\r\n result.push({\r\n type: 'match',\r\n value: match[0],\r\n groups: match.slice(1).map((g) => g || ''),\r\n });\r\n\r\n lastIndex = regex.lastIndex;\r\n }\r\n\r\n // Add remaining non-match text\r\n if (lastIndex < str.length) {\r\n result.push({\r\n type: 'non-match',\r\n value: str.substring(lastIndex),\r\n });\r\n }\r\n\r\n // If no matches, return single non-match with full string\r\n if (result.length === 0) {\r\n result.push({\r\n type: 'non-match',\r\n value: str,\r\n });\r\n }\r\n\r\n return result;\r\n } catch (e) {\r\n // Invalid regex pattern\r\n throw new Error(`Invalid regular expression: ${pat}`);\r\n }\r\n}\r\n\r\n/**\r\n * fn:format-integer($value as xs:integer?, $picture as xs:string) as xs:string\r\n * fn:format-integer($value as xs:integer?, $picture as xs:string, $lang as xs:string?) as xs:string\r\n *\r\n * Formats an integer according to a picture string.\r\n * Simplified implementation supporting basic patterns like \"1\", \"01\", \"a\", \"A\", etc.\r\n */\r\nexport function formatInteger(\r\n context: XPathContext,\r\n value: any,\r\n picture: any,\r\n lang?: any\r\n): XPathResult {\r\n // Handle null/undefined input\r\n if (value === null || value === undefined) {\r\n return '';\r\n }\r\n\r\n const num = Array.isArray(value) ? (value.length > 0 ? Number(value[0]) : 0) : Number(value);\r\n const pic = String(picture);\r\n\r\n // Extract the integer part\r\n const intValue = Math.floor(num);\r\n const isNegative = intValue < 0;\r\n const absValue = Math.abs(intValue);\r\n\r\n // Determine format type from picture\r\n if (pic === '1') {\r\n return String(intValue);\r\n } else if (pic === '01') {\r\n // Zero-padded to match picture length\r\n return String(Math.abs(intValue)).padStart(2, '0');\r\n } else if (pic === 'a') {\r\n // Lowercase letters: a=1, b=2, ... z=26, aa=27, etc.\r\n return toLetters(absValue, 'a');\r\n } else if (pic === 'A') {\r\n // Uppercase letters: A=1, B=2, ... Z=26, AA=27, etc.\r\n return toLetters(absValue, 'A');\r\n } else if (pic === 'i') {\r\n // Lowercase Roman numerals\r\n return toRoman(absValue).toLowerCase();\r\n } else if (pic === 'I') {\r\n // Uppercase Roman numerals\r\n return toRoman(absValue);\r\n } else if (pic === 'w') {\r\n // Word: one, two, three, ... (English only for now)\r\n return toWords(absValue);\r\n } else if (pic === 'W') {\r\n // Capitalized words\r\n return toWords(absValue).replace(/^\\w/, (c) => c.toUpperCase());\r\n }\r\n\r\n // Default: treat as numeric with padding\r\n const paddingMatch = pic.match(/^(0+)$/);\r\n if (paddingMatch) {\r\n const padLength = paddingMatch[1].length;\r\n return String(absValue).padStart(padLength, '0');\r\n }\r\n\r\n // Fallback to simple number format\r\n return String(intValue);\r\n}\r\n\r\n/**\r\n * fn:format-number($value as xs:number?, $picture as xs:string) as xs:string\r\n * fn:format-number($value as xs:number?, $picture as xs:string, $format-name as xs:string?) as xs:string\r\n *\r\n * Formats a number according to a picture string.\r\n * Simplified implementation supporting basic decimal formats.\r\n */\r\nexport function formatNumber(\r\n context: XPathContext,\r\n value: any,\r\n picture: any,\r\n formatName?: any\r\n): XPathResult {\r\n // Handle null/undefined input\r\n if (value === null || value === undefined) {\r\n return 'NaN';\r\n }\r\n\r\n const num = Array.isArray(value) ? (value.length > 0 ? Number(value[0]) : NaN) : Number(value);\r\n\r\n // Handle special cases\r\n if (isNaN(num)) {\r\n return 'NaN';\r\n }\r\n if (!isFinite(num)) {\r\n return num > 0 ? 'Infinity' : '-Infinity';\r\n }\r\n\r\n const pic = String(picture);\r\n\r\n // Parse picture format: 0.00, #,##0.00, etc.\r\n // Simplified: extract integer and decimal places\r\n const parts = pic.split('.');\r\n const integerPart = parts[0] || '0';\r\n const decimalPart = parts[1] || '';\r\n\r\n // Count zeros for padding\r\n const minIntDigits = (integerPart.match(/0/g) || []).length;\r\n const minDecDigits = (decimalPart.match(/0/g) || []).length;\r\n const maxDecDigits = decimalPart.length;\r\n\r\n // Format the number\r\n let result: string;\r\n if (minDecDigits > 0 || maxDecDigits > 0) {\r\n const decimals = Math.max(minDecDigits, Math.min(maxDecDigits, 6));\r\n result = num.toFixed(decimals);\r\n } else {\r\n result = String(Math.round(num));\r\n }\r\n\r\n // Pad integer part if needed\r\n const [intPart, decPart] = result.split('.');\r\n const paddedInt = intPart.padStart(minIntDigits, '0');\r\n\r\n return decPart !== undefined ? `${paddedInt}.${decPart}` : paddedInt;\r\n}\r\n\r\n/**\r\n * Helper: Convert number to letter sequence (a=1, b=2, ..., z=26, aa=27, etc.)\r\n */\r\nfunction toLetters(num: number, baseChar: string): string {\r\n if (num <= 0) return '';\r\n\r\n const base = baseChar.charCodeAt(0);\r\n let result = '';\r\n let n = num;\r\n\r\n while (n > 0) {\r\n n--; // Adjust for 0-based indexing\r\n result = String.fromCharCode(base + (n % 26)) + result;\r\n n = Math.floor(n / 26);\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Helper: Convert number to Roman numerals\r\n */\r\nfunction toRoman(num: number): string {\r\n if (num <= 0 || num >= 4000) return String(num);\r\n\r\n const romanMap = [\r\n { value: 1000, numeral: 'M' },\r\n { value: 900, numeral: 'CM' },\r\n { value: 500, numeral: 'D' },\r\n { value: 400, numeral: 'CD' },\r\n { value: 100, numeral: 'C' },\r\n { value: 90, numeral: 'XC' },\r\n { value: 50, numeral: 'L' },\r\n { value: 40, numeral: 'XL' },\r\n { value: 10, numeral: 'X' },\r\n { value: 9, numeral: 'IX' },\r\n { value: 5, numeral: 'V' },\r\n { value: 4, numeral: 'IV' },\r\n { value: 1, numeral: 'I' },\r\n ];\r\n\r\n let result = '';\r\n let n = num;\r\n\r\n for (const { value, numeral } of romanMap) {\r\n while (n >= value) {\r\n result += numeral;\r\n n -= value;\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Helper: Convert number to English words\r\n */\r\nfunction toWords(num: number): string {\r\n if (num === 0) return 'zero';\r\n if (num < 0) return 'negative ' + toWords(-num);\r\n\r\n const ones = ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];\r\n const teens = [\r\n 'ten',\r\n 'eleven',\r\n 'twelve',\r\n 'thirteen',\r\n 'fourteen',\r\n 'fifteen',\r\n 'sixteen',\r\n 'seventeen',\r\n 'eighteen',\r\n 'nineteen',\r\n ];\r\n const tens = [\r\n '',\r\n '',\r\n 'twenty',\r\n 'thirty',\r\n 'forty',\r\n 'fifty',\r\n 'sixty',\r\n 'seventy',\r\n 'eighty',\r\n 'ninety',\r\n ];\r\n const scales = ['', 'thousand', 'million', 'billion', 'trillion'];\r\n\r\n let result = '';\r\n let scaleIndex = 0;\r\n\r\n while (num > 0) {\r\n const chunk = num % 1000;\r\n if (chunk !== 0) {\r\n result =\r\n convertHundreds(chunk, ones, teens, tens) +\r\n (scales[scaleIndex] ? ' ' + scales[scaleIndex] : '') +\r\n (result ? ' ' : '') +\r\n result;\r\n }\r\n num = Math.floor(num / 1000);\r\n scaleIndex++;\r\n }\r\n\r\n return result.trim();\r\n}\r\n\r\n/**\r\n * Helper: Convert 0-999 to words\r\n */\r\nfunction convertHundreds(num: number, ones: string[], teens: string[], tens: string[]): string {\r\n let result = '';\r\n\r\n const hundreds = Math.floor(num / 100);\r\n if (hundreds > 0) {\r\n result += ones[hundreds] + ' hundred';\r\n }\r\n\r\n const remainder = num % 100;\r\n if (remainder >= 20) {\r\n if (result) result += ' ';\r\n const tenDigit = Math.floor(remainder / 10);\r\n const oneDigit = remainder % 10;\r\n result += tens[tenDigit];\r\n if (oneDigit > 0) {\r\n result += ' ' + ones[oneDigit];\r\n }\r\n } else if (remainder >= 10) {\r\n if (result) result += ' ';\r\n result += teens[remainder - 10];\r\n } else if (remainder > 0) {\r\n if (result) result += ' ';\r\n result += ones[remainder];\r\n }\r\n\r\n return result;\r\n}\r\n\r\n// Export all string functions for XPath 3.0\r\nexport const STRING_FUNCTIONS_30 = {\r\n 'analyze-string': analyzeString,\r\n 'format-integer': formatInteger,\r\n 'format-number': formatNumber,\r\n};\r\n","/**\r\n * XPath 3.1 Array Functions\r\n *\r\n * Functions for working with XPath arrays.\r\n * All functions are in the \"array:\" namespace.\r\n *\r\n * Reference: https://www.w3.org/TR/xpath-functions-31/#array-functions\r\n */\r\n\r\nimport { XPathContext } from '../context';\r\nimport {\r\n isXPathArray,\r\n XPathArray,\r\n createXPathArray,\r\n getArrayMember,\r\n getArraySize,\r\n} from '../expressions/array-constructor-expression';\r\n\r\n/**\r\n * Check if a value is an XPath array and throw error if not.\r\n * Handles single-item sequences (unwraps them).\r\n */\r\nfunction requireArray(value: any, funcName: string): XPathArray {\r\n // Unwrap single-item sequences (e.g., from . expression)\r\n if (Array.isArray(value) && !isXPathArray(value)) {\r\n if (value.length === 1) {\r\n value = value[0];\r\n } else if (value.length === 0) {\r\n throw new Error(`XPTY0004: ${funcName} requires an array, got empty sequence`);\r\n } else {\r\n throw new Error(\r\n `XPTY0004: ${funcName} requires a single array, got sequence of ${value.length} items`\r\n );\r\n }\r\n }\r\n\r\n if (!isXPathArray(value)) {\r\n throw new Error(`XPTY0004: ${funcName} requires an array, got ${typeof value}`);\r\n }\r\n return value;\r\n}\r\n\r\n/**\r\n * Validate array position (1-based).\r\n */\r\nfunction validatePosition(arr: XPathArray, position: number, funcName: string): void {\r\n if (!Number.isInteger(position)) {\r\n throw new Error(`XPTY0004: ${funcName} position must be an integer, got ${position}`);\r\n }\r\n if (position < 1 || position > arr.members.length) {\r\n throw new Error(\r\n `FOAY0001: ${funcName} position ${position} is out of bounds (array size: ${arr.members.length})`\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * array:size($array as array(*)) as xs:integer\r\n *\r\n * Returns the number of members in the array.\r\n */\r\nexport function arraySize(context: XPathContext, array: any): number {\r\n const arr = requireArray(array, 'array:size');\r\n return arr.members.length;\r\n}\r\n\r\n/**\r\n * array:get($array as array(*), $position as xs:integer) as item()*\r\n *\r\n * Returns the member at the specified position (1-based).\r\n * Equivalent to $array($position).\r\n */\r\nexport function arrayGet(context: XPathContext, array: any, position: number): any {\r\n const arr = requireArray(array, 'array:get');\r\n validatePosition(arr, position, 'array:get');\r\n return arr.members[position - 1];\r\n}\r\n\r\n/**\r\n * array:put($array as array(*), $position as xs:integer, $member as item()*) as array(*)\r\n *\r\n * Returns a new array with the member at position replaced.\r\n */\r\nexport function arrayPut(\r\n context: XPathContext,\r\n array: any,\r\n position: number,\r\n member: any\r\n): XPathArray {\r\n const arr = requireArray(array, 'array:put');\r\n validatePosition(arr, position, 'array:put');\r\n\r\n const newMembers = [...arr.members];\r\n newMembers[position - 1] = member;\r\n return createXPathArray(newMembers);\r\n}\r\n\r\n/**\r\n * array:append($array as array(*), $appendage as item()*) as array(*)\r\n *\r\n * Returns a new array with the appendage added as the last member.\r\n */\r\nexport function arrayAppend(context: XPathContext, array: any, appendage: any): XPathArray {\r\n const arr = requireArray(array, 'array:append');\r\n return createXPathArray([...arr.members, appendage]);\r\n}\r\n\r\n/**\r\n * array:subarray($array as array(*), $start as xs:integer) as array(*)\r\n * array:subarray($array as array(*), $start as xs:integer, $length as xs:integer) as array(*)\r\n *\r\n * Returns a contiguous portion of the array.\r\n */\r\nexport function arraySubarray(\r\n context: XPathContext,\r\n array: any,\r\n start: number,\r\n length?: number\r\n): XPathArray {\r\n const arr = requireArray(array, 'array:subarray');\r\n\r\n if (!Number.isInteger(start)) {\r\n throw new Error(`XPTY0004: array:subarray start must be an integer, got ${start}`);\r\n }\r\n\r\n if (start < 1) {\r\n throw new Error(`FOAY0001: array:subarray start ${start} must be >= 1`);\r\n }\r\n\r\n if (start > arr.members.length + 1) {\r\n throw new Error(\r\n `FOAY0001: array:subarray start ${start} is out of bounds (array size: ${arr.members.length})`\r\n );\r\n }\r\n\r\n const startIdx = start - 1;\r\n\r\n if (length === undefined) {\r\n // Return from start to end\r\n return createXPathArray(arr.members.slice(startIdx));\r\n }\r\n\r\n if (!Number.isInteger(length)) {\r\n throw new Error(`XPTY0004: array:subarray length must be an integer, got ${length}`);\r\n }\r\n\r\n if (length < 0) {\r\n throw new Error(`FOAY0002: array:subarray length ${length} must be >= 0`);\r\n }\r\n\r\n if (startIdx + length > arr.members.length) {\r\n throw new Error(\r\n `FOAY0001: array:subarray range [${start}, ${start + length - 1}] exceeds array bounds`\r\n );\r\n }\r\n\r\n return createXPathArray(arr.members.slice(startIdx, startIdx + length));\r\n}\r\n\r\n/**\r\n * array:remove($array as array(*), $positions as xs:integer*) as array(*)\r\n *\r\n * Returns a new array with members at specified positions removed.\r\n */\r\nexport function arrayRemove(\r\n context: XPathContext,\r\n array: any,\r\n positions: number | number[]\r\n): XPathArray {\r\n const arr = requireArray(array, 'array:remove');\r\n\r\n // Normalize positions to array\r\n const posArray = Array.isArray(positions) ? positions : [positions];\r\n\r\n // Validate all positions\r\n for (const pos of posArray) {\r\n if (!Number.isInteger(pos)) {\r\n throw new Error(`XPTY0004: array:remove position must be an integer, got ${pos}`);\r\n }\r\n if (pos < 1 || pos > arr.members.length) {\r\n throw new Error(\r\n `FOAY0001: array:remove position ${pos} is out of bounds (array size: ${arr.members.length})`\r\n );\r\n }\r\n }\r\n\r\n // Convert to 0-based indices and create a set for O(1) lookup\r\n const indicesToRemove = new Set(posArray.map((p) => p - 1));\r\n\r\n const newMembers = arr.members.filter((_, idx) => !indicesToRemove.has(idx));\r\n return createXPathArray(newMembers);\r\n}\r\n\r\n/**\r\n * array:insert-before($array as array(*), $position as xs:integer, $member as item()*) as array(*)\r\n *\r\n * Returns a new array with a new member inserted before the specified position.\r\n */\r\nexport function arrayInsertBefore(\r\n context: XPathContext,\r\n array: any,\r\n position: number,\r\n member: any\r\n): XPathArray {\r\n const arr = requireArray(array, 'array:insert-before');\r\n\r\n if (!Number.isInteger(position)) {\r\n throw new Error(\r\n `XPTY0004: array:insert-before position must be an integer, got ${position}`\r\n );\r\n }\r\n\r\n // Position can be from 1 to length + 1 (insert at end)\r\n if (position < 1 || position > arr.members.length + 1) {\r\n throw new Error(\r\n `FOAY0001: array:insert-before position ${position} is out of bounds (valid range: 1 to ${arr.members.length + 1})`\r\n );\r\n }\r\n\r\n const newMembers = [...arr.members];\r\n newMembers.splice(position - 1, 0, member);\r\n return createXPathArray(newMembers);\r\n}\r\n\r\n/**\r\n * array:head($array as array(*)) as item()*\r\n *\r\n * Returns the first member of the array.\r\n * Error if array is empty.\r\n */\r\nexport function arrayHead(context: XPathContext, array: any): any {\r\n const arr = requireArray(array, 'array:head');\r\n\r\n if (arr.members.length === 0) {\r\n throw new Error(`FOAY0001: array:head called on empty array`);\r\n }\r\n\r\n return arr.members[0];\r\n}\r\n\r\n/**\r\n * array:tail($array as array(*)) as array(*)\r\n *\r\n * Returns all members except the first.\r\n * Error if array is empty.\r\n */\r\nexport function arrayTail(context: XPathContext, array: any): XPathArray {\r\n const arr = requireArray(array, 'array:tail');\r\n\r\n if (arr.members.length === 0) {\r\n throw new Error(`FOAY0001: array:tail called on empty array`);\r\n }\r\n\r\n return createXPathArray(arr.members.slice(1));\r\n}\r\n\r\n/**\r\n * array:reverse($array as array(*)) as array(*)\r\n *\r\n * Returns a new array with members in reverse order.\r\n */\r\nexport function arrayReverse(context: XPathContext, array: any): XPathArray {\r\n const arr = requireArray(array, 'array:reverse');\r\n return createXPathArray([...arr.members].reverse());\r\n}\r\n\r\n/**\r\n * array:join($arrays as array(*)*) as array(*)\r\n *\r\n * Concatenates multiple arrays into a single array.\r\n */\r\nexport function arrayJoin(context: XPathContext, arrays: any | any[]): XPathArray {\r\n // Normalize to array\r\n const arrList = Array.isArray(arrays) ? arrays : [arrays];\r\n\r\n const allMembers: any[] = [];\r\n\r\n for (const arr of arrList) {\r\n if (arr === null || arr === undefined) continue;\r\n\r\n const xpathArr = requireArray(arr, 'array:join');\r\n allMembers.push(...xpathArr.members);\r\n }\r\n\r\n return createXPathArray(allMembers);\r\n}\r\n\r\n/**\r\n * array:flatten($input as item()*) as item()*\r\n *\r\n * Flattens an array or sequence, recursively extracting array members.\r\n * Non-array items are returned as-is.\r\n */\r\nexport function arrayFlatten(context: XPathContext, input: any): any[] {\r\n const result: any[] = [];\r\n\r\n const flatten = (item: any) => {\r\n if (isXPathArray(item)) {\r\n // Recursively flatten array members\r\n for (const member of item.members) {\r\n flatten(member);\r\n }\r\n } else if (Array.isArray(item)) {\r\n // Flatten sequences\r\n for (const elem of item) {\r\n flatten(elem);\r\n }\r\n } else {\r\n // Non-array items are kept as-is\r\n result.push(item);\r\n }\r\n };\r\n\r\n flatten(input);\r\n return result;\r\n}\r\n\r\n/**\r\n * array:for-each($array as array(*), $action as function(item()*) as item()*) as array(*)\r\n *\r\n * Applies a function to each member of the array and returns a new array.\r\n */\r\nexport function arrayForEach(context: XPathContext, array: any, action: any): XPathArray {\r\n const arr = requireArray(array, 'array:for-each');\r\n\r\n if (!action || (typeof action !== 'function' && !action.__isFunctionItem)) {\r\n throw new Error(`XPTY0004: array:for-each requires a function as second argument`);\r\n }\r\n\r\n const fn = action.__isFunctionItem ? action.implementation : action;\r\n\r\n const newMembers = arr.members.map((member, index) => {\r\n // Inline function implementations don't expect context as first arg\r\n return fn(member);\r\n });\r\n\r\n return createXPathArray(newMembers);\r\n}\r\n\r\n/**\r\n * array:filter($array as array(*), $predicate as function(item()*) as xs:boolean) as array(*)\r\n *\r\n * Returns a new array containing only members for which the predicate returns true.\r\n */\r\nexport function arrayFilter(context: XPathContext, array: any, predicate: any): XPathArray {\r\n const arr = requireArray(array, 'array:filter');\r\n\r\n if (!predicate || (typeof predicate !== 'function' && !predicate.__isFunctionItem)) {\r\n throw new Error(`XPTY0004: array:filter requires a function as second argument`);\r\n }\r\n\r\n const fn = predicate.__isFunctionItem ? predicate.implementation : predicate;\r\n\r\n const filteredMembers = arr.members.filter((member) => {\r\n // Inline function implementations don't expect context as first arg\r\n const result = fn(member);\r\n // Convert to boolean\r\n if (typeof result === 'boolean') return result;\r\n if (typeof result === 'number') return result !== 0 && !isNaN(result);\r\n if (typeof result === 'string') return result.length > 0;\r\n if (Array.isArray(result)) return result.length > 0;\r\n return !!result;\r\n });\r\n\r\n return createXPathArray(filteredMembers);\r\n}\r\n\r\n/**\r\n * array:fold-left($array as array(*), $zero as item()*, $f as function(item()*, item()*) as item()*) as item()*\r\n *\r\n * Applies a function cumulatively from left to right.\r\n */\r\nexport function arrayFoldLeft(context: XPathContext, array: any, zero: any, f: any): any {\r\n const arr = requireArray(array, 'array:fold-left');\r\n\r\n if (!f || (typeof f !== 'function' && !f.__isFunctionItem)) {\r\n throw new Error(`XPTY0004: array:fold-left requires a function as third argument`);\r\n }\r\n\r\n const fn = f.__isFunctionItem ? f.implementation : f;\r\n\r\n let accumulator = zero;\r\n for (const member of arr.members) {\r\n // Inline function implementations don't expect context as first arg\r\n accumulator = fn(accumulator, member);\r\n }\r\n\r\n return accumulator;\r\n}\r\n\r\n/**\r\n * array:fold-right($array as array(*), $zero as item()*, $f as function(item()*, item()*) as item()*) as item()*\r\n *\r\n * Applies a function cumulatively from right to left.\r\n */\r\nexport function arrayFoldRight(context: XPathContext, array: any, zero: any, f: any): any {\r\n const arr = requireArray(array, 'array:fold-right');\r\n\r\n if (!f || (typeof f !== 'function' && !f.__isFunctionItem)) {\r\n throw new Error(`XPTY0004: array:fold-right requires a function as third argument`);\r\n }\r\n\r\n const fn = f.__isFunctionItem ? f.implementation : f;\r\n\r\n let accumulator = zero;\r\n for (let i = arr.members.length - 1; i >= 0; i--) {\r\n // Inline function implementations don't expect context as first arg\r\n accumulator = fn(arr.members[i], accumulator);\r\n }\r\n\r\n return accumulator;\r\n}\r\n\r\n/**\r\n * array:sort($array as array(*)) as array(*)\r\n * array:sort($array as array(*), $collation as xs:string?) as array(*)\r\n * array:sort($array as array(*), $collation as xs:string?, $key as function(item()*) as xs:anyAtomicType*) as array(*)\r\n *\r\n * Returns a new array with members sorted.\r\n */\r\nexport function arraySort(\r\n context: XPathContext,\r\n array: any,\r\n collation?: string,\r\n key?: any\r\n): XPathArray {\r\n const arr = requireArray(array, 'array:sort');\r\n\r\n // Get key function if provided\r\n const keyFn = key && (key.__isFunctionItem ? key.implementation : key);\r\n\r\n // Create copy with indices for stable sort\r\n const indexedMembers = arr.members.map((member, idx) => ({ member, idx }));\r\n\r\n indexedMembers.sort((a, b) => {\r\n // Inline function implementations don't expect context as first arg\r\n let aKey = keyFn ? keyFn(a.member) : a.member;\r\n let bKey = keyFn ? keyFn(b.member) : b.member;\r\n\r\n // Handle arrays/sequences - use first item for comparison\r\n if (Array.isArray(aKey)) aKey = aKey[0];\r\n if (Array.isArray(bKey)) bKey = bKey[0];\r\n\r\n // Compare based on type\r\n if (typeof aKey === 'number' && typeof bKey === 'number') {\r\n return aKey - bKey;\r\n }\r\n\r\n // Convert to strings for comparison\r\n const aStr = String(aKey ?? '');\r\n const bStr = String(bKey ?? '');\r\n\r\n // Use localeCompare for string comparison\r\n const result = aStr.localeCompare(bStr);\r\n\r\n // Stable sort: preserve original order for equal elements\r\n return result !== 0 ? result : a.idx - b.idx;\r\n });\r\n\r\n return createXPathArray(indexedMembers.map((item) => item.member));\r\n}\r\n\r\n/**\r\n * Register all array functions in the function registry.\r\n */\r\nexport const ARRAY_FUNCTIONS: Record<string, (...args: any[]) => any> = {\r\n 'array:size': arraySize,\r\n 'array:get': arrayGet,\r\n 'array:put': arrayPut,\r\n 'array:append': arrayAppend,\r\n 'array:subarray': arraySubarray,\r\n 'array:remove': arrayRemove,\r\n 'array:insert-before': arrayInsertBefore,\r\n 'array:head': arrayHead,\r\n 'array:tail': arrayTail,\r\n 'array:reverse': arrayReverse,\r\n 'array:join': arrayJoin,\r\n 'array:flatten': arrayFlatten,\r\n 'array:for-each': arrayForEach,\r\n 'array:filter': arrayFilter,\r\n 'array:fold-left': arrayFoldLeft,\r\n 'array:fold-right': arrayFoldRight,\r\n 'array:sort': arraySort,\r\n};\r\n","/**\r\n * XPath 3.1 Map Functions\r\n *\r\n * Functions for working with XPath maps.\r\n * All functions are in the \"map:\" namespace.\r\n *\r\n * Reference: https://www.w3.org/TR/xpath-functions-31/#map-functions\r\n */\r\n\r\nimport { XPathContext } from '../context';\r\nimport { isXPathMap } from '../expressions/map-constructor-expression';\r\n\r\nfunction requireMap(value: any, funcName: string): any {\r\n // Unwrap single-item sequences (e.g., from . expression)\r\n if (Array.isArray(value) && !isXPathMap(value)) {\r\n if (value.length === 1) {\r\n value = value[0];\r\n } else if (value.length === 0) {\r\n throw new Error(`XPTY0004: ${funcName} requires a map, got empty sequence`);\r\n } else {\r\n throw new Error(\r\n `XPTY0004: ${funcName} requires a single map, got sequence of ${value.length} items`\r\n );\r\n }\r\n }\r\n\r\n if (!isXPathMap(value)) {\r\n throw new Error(`XPTY0004: ${funcName} requires a map, got ${typeof value}`);\r\n }\r\n return value;\r\n}\r\n\r\nfunction cloneMap(map: any): any {\r\n const newMap = Object.create(null);\r\n newMap.__isMap = true;\r\n Object.assign(newMap, map);\r\n return newMap;\r\n}\r\n\r\nexport function mapSize(context: XPathContext, map: any): number {\r\n const m = requireMap(map, 'map:size');\r\n return Object.keys(m).filter((k) => !k.startsWith('__')).length;\r\n}\r\n\r\nexport function mapKeys(context: XPathContext, map: any): string[] {\r\n const m = requireMap(map, 'map:keys');\r\n return Object.keys(m).filter((k) => !k.startsWith('__'));\r\n}\r\n\r\nexport function mapContains(context: XPathContext, map: any, key: any): boolean {\r\n const m = requireMap(map, 'map:contains');\r\n const k = String(key);\r\n return Object.prototype.hasOwnProperty.call(m, k);\r\n}\r\n\r\nexport function mapGet(context: XPathContext, map: any, key: any): any {\r\n const m = requireMap(map, 'map:get');\r\n const k = String(key);\r\n if (Object.prototype.hasOwnProperty.call(m, k)) {\r\n return m[k];\r\n }\r\n // Missing key -> empty sequence (undefined in JS)\r\n return undefined;\r\n}\r\n\r\nexport function mapPut(context: XPathContext, map: any, key: any, value: any): any {\r\n const m = requireMap(map, 'map:put');\r\n const k = String(key);\r\n const newMap = cloneMap(m);\r\n newMap[k] = value;\r\n return newMap;\r\n}\r\n\r\nexport function mapEntry(context: XPathContext, key: any, value: any): any {\r\n const k = String(key);\r\n const newMap = Object.create(null);\r\n newMap.__isMap = true;\r\n newMap[k] = value;\r\n return newMap;\r\n}\r\n\r\nexport function mapMerge(context: XPathContext, maps: any | any[], options?: any): any {\r\n // Normalize to array of maps\r\n const mapList = Array.isArray(maps) ? maps : [maps];\r\n\r\n // Parse options\r\n let duplicateHandling = 'use-last'; // default per spec\r\n if (options && isXPathMap(options)) {\r\n if (options.duplicates !== undefined) {\r\n duplicateHandling = String(options.duplicates);\r\n }\r\n }\r\n\r\n // Validate duplicateHandling option\r\n const validOptions = ['use-first', 'use-last', 'combine', 'reject'];\r\n if (!validOptions.includes(duplicateHandling)) {\r\n throw new Error(\r\n `XPST0003: Invalid duplicates option '${duplicateHandling}'. ` +\r\n `Must be one of: ${validOptions.join(', ')}`\r\n );\r\n }\r\n\r\n const result = Object.create(null);\r\n result.__isMap = true;\r\n\r\n // Track which keys are duplicates (for 'reject' option)\r\n const keyOccurrences: Record<string, number> = {};\r\n\r\n for (const m of mapList) {\r\n const mm = requireMap(m, 'map:merge');\r\n for (const k of Object.keys(mm)) {\r\n if (k.startsWith('__')) continue;\r\n\r\n // Track occurrences for duplicate handling\r\n if (!keyOccurrences[k]) {\r\n keyOccurrences[k] = 0;\r\n }\r\n keyOccurrences[k]++;\r\n\r\n // Handle duplicates based on option\r\n if (duplicateHandling === 'use-first') {\r\n // Only set if not already set\r\n if (!(k in result)) {\r\n result[k] = mm[k];\r\n }\r\n } else if (duplicateHandling === 'use-last') {\r\n // Always overwrite (default behavior)\r\n result[k] = mm[k];\r\n } else if (duplicateHandling === 'combine') {\r\n // Combine values into array\r\n if (k in result) {\r\n // Convert to array if not already\r\n if (Array.isArray(result[k])) {\r\n result[k].push(mm[k]);\r\n } else {\r\n result[k] = [result[k], mm[k]];\r\n }\r\n } else {\r\n result[k] = mm[k];\r\n }\r\n } else if (duplicateHandling === 'reject') {\r\n // Will check for duplicates after scanning all maps\r\n result[k] = mm[k];\r\n }\r\n }\r\n }\r\n\r\n // Check for duplicates with 'reject' option\r\n if (duplicateHandling === 'reject') {\r\n for (const k in keyOccurrences) {\r\n if (keyOccurrences[k] > 1) {\r\n throw new Error(\r\n `XUST0003: Duplicate key '${k}' found in map:merge with duplicates='reject'`\r\n );\r\n }\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport function mapForEach(context: XPathContext, map: any, fn: any): any {\r\n const m = requireMap(map, 'map:for-each');\r\n\r\n if (!fn || (typeof fn !== 'function' && !fn.__isFunctionItem)) {\r\n throw new Error(`XPTY0004: map:for-each requires a function as second argument`);\r\n }\r\n\r\n const impl = fn.__isFunctionItem ? fn.implementation : fn;\r\n\r\n const result = Object.create(null);\r\n result.__isMap = true;\r\n\r\n for (const k of Object.keys(m)) {\r\n if (k.startsWith('__')) continue;\r\n const v = m[k];\r\n // Inline function implementations don't expect context as first arg\r\n // Call with key and value\r\n result[k] = impl(k, v);\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport function mapRemove(context: XPathContext, map: any, keys: any | any[]): any {\r\n const m = requireMap(map, 'map:remove');\r\n const keyList = Array.isArray(keys) ? keys : [keys];\r\n\r\n const toRemove = new Set(keyList.map((k) => String(k)));\r\n\r\n const result = cloneMap(m);\r\n // Iterate over array of keys for compatibility with TS downlevel iteration\r\n for (const k of Array.from(toRemove)) {\r\n if (Object.prototype.hasOwnProperty.call(result, k)) {\r\n delete result[k];\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n","// src/functions/json-functions.ts\r\n// XPath 3.1: JSON Functions\r\n// Implements fn:parse-json($json-string as xs:string) as item()?\r\n// and fn:parse-json($json-string as xs:string, $options as map(*)) as item()?\r\n// Implements fn:serialize($value as item()*) as xs:string\r\n// and fn:serialize($value as item()*, $options as map(*)) as xs:string\r\n// Implements fn:json-to-xml($json-string as xs:string?) as node()?\r\n// and fn:json-to-xml($json-string as xs:string?, $options as map(*)) as node()?\r\n// Implements fn:xml-to-json($node-sequence as node()*) as xs:string?\r\n// Spec: https://www.w3.org/TR/xpath-functions-31/#func-parse-json\r\n// https://www.w3.org/TR/xpath-functions-31/#func-serialize\r\n// https://www.w3.org/TR/xpath-functions-31/#func-json-to-xml\r\n// https://www.w3.org/TR/xpath-functions-31/#func-xml-to-json\r\n\r\nimport { XPathMap, isXPathMap } from '../expressions/map-constructor-expression';\r\nimport {\r\n XPathArray,\r\n isXPathArray,\r\n createXPathArray,\r\n} from '../expressions/array-constructor-expression';\r\nimport { XPathError } from '../errors';\r\nimport { JsonToXmlConverter } from '../expressions/json-to-xml-converter';\r\nimport { XPathNode } from '../node';\r\nimport { NodeType } from '../constants';\r\nimport { XPathContext } from '../context';\r\n\r\n// Helper: Convert JS value to XPath map/array/atomic\r\nfunction jsToXPath(value: any): any {\r\n if (value === null) return null;\r\n if (Array.isArray(value)) return createXPathArray(value.map(jsToXPath));\r\n if (typeof value === 'object') {\r\n // Convert to XPathMap\r\n const map: XPathMap = Object.create(null);\r\n map.__isMap = true;\r\n for (const [k, v] of Object.entries(value)) {\r\n map[k] = jsToXPath(v);\r\n }\r\n return map;\r\n }\r\n // Atomic values: string, number, boolean\r\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean')\r\n return value;\r\n throw new XPathError('FOJS0001', 'Unsupported JSON value type');\r\n}\r\n\r\n// Helper: Process JSON string in liberal mode\r\n// Removes comments and trailing commas to make it valid JSON\r\nfunction processLiberalJson(json: string): string {\r\n let result = '';\r\n let i = 0;\r\n let inString = false;\r\n let stringChar = '';\r\n let escaped = false;\r\n\r\n while (i < json.length) {\r\n const char = json[i];\r\n const nextChar = i + 1 < json.length ? json[i + 1] : '';\r\n\r\n // Handle string state\r\n if (inString) {\r\n if (escaped) {\r\n result += char;\r\n escaped = false;\r\n i++;\r\n continue;\r\n }\r\n if (char === '\\\\') {\r\n result += char;\r\n escaped = true;\r\n i++;\r\n continue;\r\n }\r\n if (char === stringChar) {\r\n // End of string - convert single quotes to double quotes\r\n result += '\"';\r\n inString = false;\r\n i++;\r\n continue;\r\n }\r\n // Regular string character - if we're in single-quoted string, escape internal double quotes\r\n if (stringChar === \"'\" && char === '\"') {\r\n result += '\\\\\"';\r\n } else {\r\n result += char;\r\n }\r\n i++;\r\n continue;\r\n }\r\n\r\n // Not in string - check for string start\r\n if (char === '\"' || char === \"'\") {\r\n inString = true;\r\n stringChar = char;\r\n result += '\"'; // Always use double quotes in output\r\n i++;\r\n continue;\r\n }\r\n\r\n // Handle comments (// and /* */)\r\n if (char === '/' && nextChar === '/') {\r\n // Single-line comment - skip until newline\r\n i += 2;\r\n while (i < json.length && json[i] !== '\\n' && json[i] !== '\\r') {\r\n i++;\r\n }\r\n continue;\r\n }\r\n\r\n if (char === '/' && nextChar === '*') {\r\n // Multi-line comment - skip until */\r\n i += 2;\r\n while (i < json.length - 1) {\r\n if (json[i] === '*' && json[i + 1] === '/') {\r\n i += 2;\r\n break;\r\n }\r\n i++;\r\n }\r\n continue;\r\n }\r\n\r\n // Handle trailing commas - check if next non-whitespace is ] or }\r\n if (char === ',') {\r\n // Look ahead to see if this is a trailing comma\r\n let j = i + 1;\r\n // Skip all whitespace including newlines\r\n while (j < json.length && /[\\s\\n\\r\\t]/.test(json[j])) {\r\n j++;\r\n }\r\n // Also skip any comments after the comma\r\n while (j < json.length) {\r\n if (json[j] === '/' && j + 1 < json.length && json[j + 1] === '/') {\r\n // Skip single-line comment\r\n j += 2;\r\n while (j < json.length && json[j] !== '\\n' && json[j] !== '\\r') {\r\n j++;\r\n }\r\n // Skip whitespace after comment\r\n while (j < json.length && /[\\s\\n\\r\\t]/.test(json[j])) {\r\n j++;\r\n }\r\n } else if (json[j] === '/' && j + 1 < json.length && json[j + 1] === '*') {\r\n // Skip multi-line comment\r\n j += 2;\r\n while (j < json.length - 1) {\r\n if (json[j] === '*' && json[j + 1] === '/') {\r\n j += 2;\r\n break;\r\n }\r\n j++;\r\n }\r\n // Skip whitespace after comment\r\n while (j < json.length && /[\\s\\n\\r\\t]/.test(json[j])) {\r\n j++;\r\n }\r\n } else {\r\n break;\r\n }\r\n }\r\n\r\n if (j < json.length && (json[j] === '}' || json[j] === ']')) {\r\n // Trailing comma - skip it and preserve whitespace\r\n i++;\r\n // Add whitespace between comma position and closing bracket\r\n while (i < j) {\r\n if (/[\\s\\n\\r\\t]/.test(json[i])) {\r\n result += json[i];\r\n }\r\n i++;\r\n }\r\n continue;\r\n }\r\n }\r\n\r\n // Regular character\r\n result += char;\r\n i++;\r\n }\r\n\r\n return result;\r\n}\r\n\r\n// Main: fn:parse-json($json-string as xs:string, $options as map(*)?) as item()?\r\n// Internal implementation (doesn't take context parameter)\r\nfunction parseJsonImpl(jsonString: any, options?: any): any {\r\n if (typeof jsonString !== 'string')\r\n throw new XPathError('XPTY0004', 'parse-json: first argument must be a string');\r\n let opts = { liberal: false, duplicates: 'use-last' };\r\n if (options && isXPathMap(options)) {\r\n const lib = options['liberal'];\r\n if (lib === true) opts.liberal = true;\r\n const dups = options['duplicates'];\r\n if (typeof dups === 'string') opts.duplicates = dups;\r\n }\r\n try {\r\n // Duplicates: only 'use-last' supported (per spec, others error)\r\n if (opts.duplicates !== 'use-last')\r\n throw new XPathError('FOJS0001', 'Only duplicates=\"use-last\" is supported');\r\n\r\n // Liberal mode: preprocess to handle comments, trailing commas, and single quotes\r\n const processedJson = opts.liberal ? processLiberalJson(jsonString) : jsonString;\r\n const parsed = JSON.parse(processedJson);\r\n return jsToXPath(parsed);\r\n } catch (e: any) {\r\n throw new XPathError('FOJS0001', 'parse-json: ' + (e && e.message ? e.message : String(e)));\r\n }\r\n}\r\n\r\n// Exported with overloads to support both XPath system (with context) and direct calls (without context)\r\nexport function parseJson(jsonString: any, options?: any): any;\r\nexport function parseJson(_context: XPathContext, jsonString: any, options?: any): any;\r\nexport function parseJson(_contextOrJson: any, jsonStringOrOptions?: any, options?: any): any {\r\n // If first arg is a string, it's direct call (no context)\r\n if (typeof _contextOrJson === 'string') {\r\n return parseJsonImpl(_contextOrJson, jsonStringOrOptions);\r\n }\r\n // Otherwise first arg is context, shift parameters\r\n return parseJsonImpl(jsonStringOrOptions, options);\r\n}\r\n\r\n// Helper: Convert XPath value to JSON-serializable JS value\r\nfunction xpathToJs(value: any): any {\r\n if (value === null || value === undefined) return null;\r\n if (isXPathArray(value)) {\r\n return value.members.map(xpathToJs);\r\n }\r\n if (isXPathMap(value)) {\r\n const obj: Record<string, any> = {};\r\n for (const [k, v] of Object.entries(value)) {\r\n if (!k.startsWith('__')) {\r\n obj[k] = xpathToJs(v);\r\n }\r\n }\r\n return obj;\r\n }\r\n // Atomic values: string, number, boolean pass through\r\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean')\r\n return value;\r\n // Arrays (plain JS arrays from sequences)\r\n if (Array.isArray(value)) {\r\n return value.map(xpathToJs);\r\n }\r\n throw new XPathError('FOJS0002', `Cannot serialize value of type ${typeof value}`);\r\n}\r\n\r\n// Main: fn:serialize($value as item()*, $options as map(*)?) as xs:string\r\n// Serializes XPath values to JSON string representation\r\n// Internal implementation\r\nfunction serializeImpl(value: any, options?: any): string {\r\n let opts = { indent: undefined, method: 'json' };\r\n if (options && isXPathMap(options)) {\r\n const ind = options['indent'];\r\n if (typeof ind === 'number') opts.indent = ind;\r\n const meth = options['method'];\r\n if (typeof meth === 'string') opts.method = meth;\r\n }\r\n\r\n try {\r\n // Handle sequences: convert to array if needed\r\n let toSerialize: any;\r\n if (Array.isArray(value)) {\r\n if (value.length === 0) {\r\n toSerialize = null;\r\n } else if (value.length === 1) {\r\n toSerialize = value[0];\r\n } else {\r\n toSerialize = value;\r\n }\r\n } else {\r\n toSerialize = value;\r\n }\r\n\r\n // Convert to JS value\r\n const jsValue = xpathToJs(toSerialize);\r\n\r\n // Serialize to JSON string\r\n const indent = opts.indent !== undefined ? opts.indent : undefined;\r\n return JSON.stringify(jsValue, null, indent);\r\n } catch (e: any) {\r\n if (e instanceof XPathError) throw e;\r\n throw new XPathError('FOJS0002', 'serialize: ' + (e && e.message ? e.message : String(e)));\r\n }\r\n}\r\n\r\n// Exported with overloads to support both XPath system (with context) and direct calls (without context)\r\nexport function serialize(value: any, options?: any): string;\r\nexport function serialize(_context: XPathContext, value: any, options?: any): string;\r\nexport function serialize(_contextOrValue: any, valueOrOptions?: any, options?: any): string {\r\n // If we have 3 parameters, first is context\r\n if (options !== undefined) {\r\n return serializeImpl(valueOrOptions, options);\r\n }\r\n // If first arg is an object without data properties (__isMap, __isArray, or other keys),\r\n // and we have a second arg, then first is likely context\r\n if (_contextOrValue && typeof _contextOrValue === 'object' &&\r\n !('__isMap' in _contextOrValue) &&\r\n !('__isArray' in _contextOrValue) &&\r\n valueOrOptions !== undefined) {\r\n // First arg appears to be context (empty {} or context object), second is the value\r\n return serializeImpl(valueOrOptions, options);\r\n }\r\n // Otherwise first arg is the value to serialize\r\n return serializeImpl(_contextOrValue, valueOrOptions);\r\n}\r\n\r\n// Export for function registry\r\nexport const jsonFunctions = {\r\n 'parse-json': parseJson,\r\n};\r\n\r\n// Main: fn:json-to-xml($json-string as xs:string?, $options as map(*)?) as node()?\r\n// Converts JSON string to XML document representation\r\n// Internal implementation\r\nfunction jsonToXmlImpl(jsonString: any, options?: any): XPathNode | null {\r\n // Handle null/empty input\r\n if (jsonString === null || jsonString === undefined || jsonString === '') {\r\n return null;\r\n }\r\n\r\n if (typeof jsonString !== 'string') {\r\n throw new XPathError('XPTY0004', 'json-to-xml: first argument must be a string or null');\r\n }\r\n\r\n // Parse options parameter\r\n let opts: any = { liberal: false, duplicates: 'reject' };\r\n if (options && isXPathMap(options)) {\r\n const lib = options['liberal'];\r\n if (lib === true) opts.liberal = true;\r\n const dups = options['duplicates'];\r\n if (typeof dups === 'string') opts.duplicates = dups;\r\n }\r\n\r\n try {\r\n const converter = new JsonToXmlConverter();\r\n return converter.convert(jsonString, opts);\r\n } catch (e: any) {\r\n throw new XPathError(\r\n 'FOJS0001',\r\n 'json-to-xml: ' + (e && e.message ? e.message : String(e))\r\n );\r\n }\r\n}\r\n\r\n// Exported with overloads to support both XPath system (with context) and direct calls (without context)\r\nexport function jsonToXml(jsonString: any, options?: any): XPathNode | null;\r\nexport function jsonToXml(_context: XPathContext, jsonString: any, options?: any): XPathNode | null;\r\nexport function jsonToXml(_contextOrJson: any, jsonStringOrOptions?: any, options?: any): XPathNode | null {\r\n // If first arg is a string or null/undefined, it's direct call (no context)\r\n if (typeof _contextOrJson === 'string' || _contextOrJson === null || _contextOrJson === undefined) {\r\n return jsonToXmlImpl(_contextOrJson, jsonStringOrOptions);\r\n }\r\n // If first arg is a number or other non-string/non-object, it's an error in direct call\r\n if (typeof _contextOrJson !== 'object') {\r\n throw new XPathError('XPTY0004', 'json-to-xml: first argument must be a string or null');\r\n }\r\n // First arg is an object (context), shift parameters\r\n return jsonToXmlImpl(jsonStringOrOptions, options);\r\n}\r\n\r\n// Helper: Convert XML node tree back to JSON representation\r\nfunction nodeToJsonValue(node: XPathNode | null): any {\r\n if (!node) return null;\r\n\r\n // Document node: recurse to document element\r\n if (node.nodeType === NodeType.DOCUMENT_NODE) {\r\n if (node.documentElement) {\r\n return nodeToJsonValue(node.documentElement);\r\n }\r\n return null;\r\n }\r\n\r\n // Element node\r\n if (node.nodeType === NodeType.ELEMENT_NODE) {\r\n // Handle special structure: check if this is a map-like or array-like element\r\n const childNodesArrayLike = node.childNodes || [];\r\n const children = Array.from(childNodesArrayLike);\r\n\r\n // If no children: return null or empty object based on element name\r\n if (children.length === 0) {\r\n return null;\r\n }\r\n\r\n // If all children are text nodes: concatenate text\r\n const allText = children.every((n) => n.nodeType === NodeType.TEXT_NODE);\r\n if (allText) {\r\n const text = children.map((n) => n.textContent || '').join('');\r\n // Try to parse as number or boolean\r\n if (text === 'true') return true;\r\n if (text === 'false') return false;\r\n if (text === 'null') return null;\r\n const num = Number(text);\r\n if (!Number.isNaN(num)) return num;\r\n return text;\r\n }\r\n\r\n // If children are mixed or all elements: treat as object\r\n const obj: Record<string, any> = {};\r\n const seenKeys = new Set<string>();\r\n\r\n for (const child of children) {\r\n if (child.nodeType === NodeType.ELEMENT_NODE) {\r\n const key = child.localName || child.nodeName || '';\r\n const value = nodeToJsonValue(child);\r\n\r\n if (seenKeys.has(key)) {\r\n // Duplicate key: handle per W3C spec (allow)\r\n if (Array.isArray(obj[key])) {\r\n obj[key].push(value);\r\n } else {\r\n obj[key] = [obj[key], value];\r\n }\r\n } else {\r\n obj[key] = value;\r\n }\r\n seenKeys.add(key);\r\n }\r\n }\r\n\r\n return obj;\r\n }\r\n\r\n // Text node\r\n if (node.nodeType === NodeType.TEXT_NODE) {\r\n return node.textContent || '';\r\n }\r\n\r\n // Other node types: skip\r\n return null;\r\n}\r\n\r\n// Main: fn:xml-to-json($node-sequence as node()*) as xs:string?\r\n// Converts XML nodes to JSON string representation (inverse of json-to-xml)\r\n// Note: First parameter is context for BUILT_IN_FUNCTIONS compatibility\r\nexport function xmlToJson(context: any, nodes?: any): string | null {\r\n // When called from BUILT_IN_FUNCTIONS, context is always first parameter\r\n // When called directly, first arg could be the nodes\r\n // We check if second parameter exists - if so, first is context\r\n let actualNodes: any;\r\n if (nodes !== undefined) {\r\n // context + nodes provided\r\n actualNodes = nodes;\r\n } else {\r\n // Only one arg - treat as nodes (direct call)\r\n actualNodes = context;\r\n }\r\n\r\n // Handle empty sequence or null\r\n if (actualNodes === null || actualNodes === undefined) {\r\n return null;\r\n }\r\n\r\n // Convert to array if not already\r\n let nodeList: any[] = Array.isArray(actualNodes) ? actualNodes : [actualNodes];\r\n\r\n // Filter out non-nodes\r\n nodeList = nodeList.filter((n) => n && typeof n === 'object' && 'nodeType' in n);\r\n\r\n if (nodeList.length === 0) {\r\n return null;\r\n }\r\n\r\n try {\r\n // If multiple nodes: wrap in array\r\n let toSerialize: any;\r\n if (nodeList.length === 1) {\r\n toSerialize = nodeToJsonValue(nodeList[0]);\r\n } else {\r\n toSerialize = nodeList.map((n) => nodeToJsonValue(n));\r\n }\r\n\r\n // Serialize to JSON\r\n return JSON.stringify(toSerialize);\r\n } catch (e: any) {\r\n throw new XPathError(\r\n 'FOJS0002',\r\n 'xml-to-json: ' + (e && e.message ? e.message : String(e))\r\n );\r\n }\r\n}\r\n// Exported with overloads to support both XPath system (with context) and direct calls (without context)","/**\r\n * XPath 2.0 QName Functions\r\n *\r\n * Reference: https://www.w3.org/TR/xpath-functions/#QName-funcs\r\n */\r\n\r\nimport { NodeType } from '../constants';\r\nimport { XPathResult } from '../context';\r\nimport { XPathNode } from '../node';\r\n\r\n/**\r\n * fn:QName($paramURI as xs:string?, $paramQName as xs:string) as xs:QName\r\n * Returns an xs:QName with the namespace URI given in $paramURI.\r\n */\r\nexport function QName(paramURI: XPathResult, paramQName: XPathResult): string {\r\n const uri = toString(paramURI);\r\n const qname = toString(paramQName);\r\n\r\n if (!qname) {\r\n throw new Error('FOCA0002: Invalid QName: empty string');\r\n }\r\n\r\n // Validate QName format (prefix:localName or just localName)\r\n const colonIndex = qname.indexOf(':');\r\n if (colonIndex !== -1) {\r\n const prefix = qname.substring(0, colonIndex);\r\n const localName = qname.substring(colonIndex + 1);\r\n\r\n // Validate prefix and local name as NCNames\r\n if (!isValidNCName(prefix) || !isValidNCName(localName)) {\r\n throw new Error(`FOCA0002: Invalid QName: ${qname}`);\r\n }\r\n\r\n // If there's a prefix, there must be a URI\r\n if (!uri) {\r\n throw new Error(`FONS0004: No namespace for prefix: ${prefix}`);\r\n }\r\n } else {\r\n // No prefix - validate as NCName\r\n if (!isValidNCName(qname)) {\r\n throw new Error(`FOCA0002: Invalid QName: ${qname}`);\r\n }\r\n }\r\n\r\n // Return as a string representation\r\n // In a full implementation, this would return a proper QName object\r\n return uri ? `{${uri}}${qname}` : qname;\r\n}\r\n\r\n/**\r\n * fn:resolve-QName($qname as xs:string?, $element as element()) as xs:QName?\r\n * Returns an xs:QName value by taking an xs:string that has the lexical form of an xs:QName\r\n * and resolving it using the in-scope namespaces for a given element.\r\n */\r\nexport function resolveQName(qname: XPathResult, element: XPathResult): string | null {\r\n const qnameStr = toString(qname);\r\n if (!qnameStr) return null;\r\n\r\n const elem = getElement(element);\r\n if (!elem) {\r\n throw new Error('FORG0001: Second argument to resolve-QName must be an element');\r\n }\r\n\r\n const colonIndex = qnameStr.indexOf(':');\r\n if (colonIndex === -1) {\r\n // No prefix - use default namespace\r\n const defaultNS = elem.getAttribute?.('xmlns') ?? '';\r\n return defaultNS ? `{${defaultNS}}${qnameStr}` : qnameStr;\r\n }\r\n\r\n const prefix = qnameStr.substring(0, colonIndex);\r\n const localName = qnameStr.substring(colonIndex + 1);\r\n\r\n // Find namespace for prefix\r\n const ns = getNamespaceForPrefix(elem, prefix);\r\n if (!ns) {\r\n throw new Error(`FONS0004: No namespace for prefix: ${prefix}`);\r\n }\r\n\r\n return `{${ns}}${qnameStr}`;\r\n}\r\n\r\n/**\r\n * fn:prefix-from-QName($arg as xs:QName?) as xs:NCName?\r\n * Returns the prefix of the xs:QName argument.\r\n */\r\nexport function prefixFromQName(arg: XPathResult): string | null {\r\n const qname = toString(arg);\r\n if (!qname) return null;\r\n\r\n // Handle Clark notation {uri}prefix:local\r\n let effectiveQName = qname;\r\n if (qname.startsWith('{')) {\r\n const closeBrace = qname.indexOf('}');\r\n if (closeBrace !== -1) {\r\n effectiveQName = qname.substring(closeBrace + 1);\r\n }\r\n }\r\n\r\n const colonIndex = effectiveQName.indexOf(':');\r\n if (colonIndex === -1) return null;\r\n\r\n return effectiveQName.substring(0, colonIndex);\r\n}\r\n\r\n/**\r\n * fn:local-name-from-QName($arg as xs:QName?) as xs:NCName?\r\n * Returns the local name of the xs:QName argument.\r\n */\r\nexport function localNameFromQName(arg: XPathResult): string | null {\r\n const qname = toString(arg);\r\n if (!qname) return null;\r\n\r\n // Handle Clark notation {uri}prefix:local or {uri}local\r\n let effectiveQName = qname;\r\n if (qname.startsWith('{')) {\r\n const closeBrace = qname.indexOf('}');\r\n if (closeBrace !== -1) {\r\n effectiveQName = qname.substring(closeBrace + 1);\r\n }\r\n }\r\n\r\n const colonIndex = effectiveQName.indexOf(':');\r\n if (colonIndex === -1) {\r\n return effectiveQName;\r\n }\r\n\r\n return effectiveQName.substring(colonIndex + 1);\r\n}\r\n\r\n/**\r\n * fn:namespace-uri-from-QName($arg as xs:QName?) as xs:anyURI?\r\n * Returns the namespace URI of the xs:QName argument.\r\n */\r\nexport function namespaceUriFromQName(arg: XPathResult): string | null {\r\n const qname = toString(arg);\r\n if (!qname) return null;\r\n\r\n // Handle Clark notation {uri}...\r\n if (qname.startsWith('{')) {\r\n const closeBrace = qname.indexOf('}');\r\n if (closeBrace !== -1) {\r\n return qname.substring(1, closeBrace);\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * fn:in-scope-prefixes($element as element()) as xs:string*\r\n * Returns the prefixes of the in-scope namespaces for an element.\r\n */\r\nexport function inScopePrefixes(element: XPathResult): string[] {\r\n const elem = getElement(element);\r\n if (!elem) {\r\n throw new Error('FORG0001: Argument to in-scope-prefixes must be an element');\r\n }\r\n\r\n const prefixes = new Set<string>();\r\n\r\n // Always include xml prefix\r\n prefixes.add('xml');\r\n\r\n // Walk up the tree collecting namespace declarations\r\n let current: XPathNode | null = elem;\r\n while (current) {\r\n // Check for xmlns attributes\r\n if ('attributes' in current && current.attributes) {\r\n const attrs = current.attributes as NamedNodeMap | { [key: string]: unknown };\r\n\r\n if (typeof (attrs as NamedNodeMap).getNamedItem === 'function') {\r\n // DOM NamedNodeMap\r\n for (let i = 0; i < (attrs as NamedNodeMap).length; i++) {\r\n const attr = (attrs as NamedNodeMap).item(i);\r\n if (attr) {\r\n const name = attr.name || attr.nodeName;\r\n if (name === 'xmlns') {\r\n prefixes.add(''); // Default namespace\r\n } else if (name.startsWith('xmlns:')) {\r\n prefixes.add(name.substring(6));\r\n }\r\n }\r\n }\r\n } else if (Array.isArray(attrs)) {\r\n // Array of attribute objects (custom format)\r\n for (const attr of attrs) {\r\n if (attr && typeof attr === 'object') {\r\n const name = (attr as any).name || (attr as any).nodeName;\r\n if (name === 'xmlns') {\r\n prefixes.add('');\r\n } else if (name && typeof name === 'string' && name.startsWith('xmlns:')) {\r\n prefixes.add(name.substring(6));\r\n }\r\n }\r\n }\r\n } else {\r\n // Object-style attributes (key-value pairs)\r\n for (const name of Object.keys(attrs)) {\r\n if (name === 'xmlns') {\r\n prefixes.add('');\r\n } else if (name.startsWith('xmlns:')) {\r\n prefixes.add(name.substring(6));\r\n }\r\n }\r\n }\r\n }\r\n\r\n current = current.parentNode as XPathNode | null;\r\n }\r\n\r\n return Array.from(prefixes);\r\n}\r\n\r\n/**\r\n * fn:namespace-uri-for-prefix($prefix as xs:string?, $element as element()) as xs:anyURI?\r\n * Returns the namespace URI associated with a prefix in the in-scope namespaces for an element.\r\n */\r\nexport function namespaceUriForPrefix(prefix: XPathResult, element: XPathResult): string | null {\r\n const prefixStr = toString(prefix);\r\n const elem = getElement(element);\r\n\r\n if (!elem) {\r\n throw new Error('FORG0001: Second argument to namespace-uri-for-prefix must be an element');\r\n }\r\n\r\n // Handle xml prefix\r\n if (prefixStr === 'xml') {\r\n return 'http://www.w3.org/XML/1998/namespace';\r\n }\r\n\r\n return getNamespaceForPrefix(elem, prefixStr);\r\n}\r\n\r\n// ============================================================================\r\n// Helper Functions\r\n// ============================================================================\r\n\r\nfunction toString(value: XPathResult): string {\r\n if (value === null || value === undefined) return '';\r\n if (Array.isArray(value)) {\r\n if (value.length === 0) return '';\r\n value = value[0];\r\n }\r\n if (typeof value === 'object' && value !== null && 'textContent' in value) {\r\n return (value as { textContent?: string }).textContent ?? '';\r\n }\r\n return String(value);\r\n}\r\n\r\nfunction getElement(value: XPathResult): XPathNode | null {\r\n if (value === null || value === undefined) return null;\r\n if (Array.isArray(value)) {\r\n if (value.length === 0) return null;\r\n value = value[0];\r\n }\r\n\r\n if (typeof value === 'object' && value !== null && 'nodeType' in value) {\r\n const node = value as unknown as XPathNode;\r\n if (node.nodeType === NodeType.ELEMENT_NODE) {\r\n return node;\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction isValidNCName(name: string): boolean {\r\n if (!name) return false;\r\n\r\n // NCName cannot start with a digit or hyphen\r\n const firstChar = name.charAt(0);\r\n if (/[0-9\\-.]/.test(firstChar)) return false;\r\n\r\n // NCName can only contain letters, digits, hyphens, underscores, and periods\r\n // Also cannot contain colons\r\n if (name.includes(':')) return false;\r\n\r\n // Simplified validation - allow letters, digits, hyphen, underscore, period\r\n return /^[a-zA-Z_][\\w.\\-]*$/.test(name);\r\n}\r\n\r\nfunction getNamespaceForPrefix(elem: XPathNode, prefix: string): string | null {\r\n let current: XPathNode | null = elem;\r\n\r\n while (current) {\r\n // Look for xmlns:prefix or xmlns (for default namespace)\r\n const attrName = prefix ? `xmlns:${prefix}` : 'xmlns';\r\n const ns = current.getAttribute?.(attrName);\r\n if (ns !== null && ns !== undefined) {\r\n return ns;\r\n }\r\n\r\n current = current.parentNode as XPathNode | null;\r\n }\r\n\r\n return null;\r\n}\r\n","/**\r\n * XPath 2.0 URI Functions\r\n *\r\n * Reference: https://www.w3.org/TR/xpath-functions/#uri-functions\r\n */\r\n\r\nimport { XPathContext, XPathResult } from '../context';\r\n\r\n/**\r\n * fn:resolve-uri($relative as xs:string?) as xs:anyURI?\r\n * fn:resolve-uri($relative as xs:string?, $base as xs:string) as xs:anyURI?\r\n */\r\nexport function resolveUri(\r\n relative: XPathResult,\r\n base?: XPathResult,\r\n context?: XPathContext\r\n): string | null {\r\n const rel = toString(relative);\r\n if (rel === '') return null;\r\n\r\n const baseUri = base !== undefined ? toString(base) : (context?.baseUri ?? '');\r\n\r\n try {\r\n if (baseUri) {\r\n return new URL(rel, baseUri).toString();\r\n }\r\n return new URL(rel).toString();\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * fn:encode-for-uri($uri-part as xs:string?) as xs:string\r\n */\r\nexport function encodeForUri(uriPart: XPathResult): string {\r\n const str = toString(uriPart);\r\n return encodeURIComponent(str).replace(\r\n /[!'()*]/g,\r\n (ch) => '%' + ch.charCodeAt(0).toString(16).toUpperCase()\r\n );\r\n}\r\n\r\n/**\r\n * fn:iri-to-uri($iri as xs:string?) as xs:string\r\n */\r\nexport function iriToUri(iri: XPathResult): string {\r\n const str = toString(iri);\r\n // encodeURI will leave valid URI chars untouched and percent-encode non-ASCII\r\n return encodeURI(str);\r\n}\r\n\r\n/**\r\n * fn:escape-html-uri($uri as xs:string?) as xs:string\r\n */\r\nexport function escapeHtmlUri(uri: XPathResult): string {\r\n const str = toString(uri);\r\n // Per spec, leave existing % escapes, encode spaces and quotes\r\n return encodeURI(str)\r\n .replace(/\\+/g, '%2B')\r\n .replace(/'/g, '%27')\r\n .replace(/\"/g, '%22')\r\n .replace(/</g, '%3C')\r\n .replace(/>/g, '%3E');\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Helpers\r\n// ---------------------------------------------------------------------------\r\nfunction toString(value: XPathResult): string {\r\n if (value === null || value === undefined) return '';\r\n if (Array.isArray(value)) {\r\n if (value.length === 0) return '';\r\n value = value[0];\r\n }\r\n return String(value);\r\n}\r\n","/**\r\n * XPath 2.0 Node Functions\r\n *\r\n * Reference: https://www.w3.org/TR/xpath-functions/#node-functions\r\n */\r\n\r\nimport { XPathContext, XPathResult } from '../context';\r\nimport { XPathNode } from '../node';\r\n\r\n/**\r\n * fn:node-name($arg as node()?) as xs:QName?\r\n * Returns the name of a node as an xs:QName.\r\n */\r\nexport function nodeName(arg: XPathResult, context: XPathContext): string | null {\r\n const node = getNode(arg, context);\r\n if (!node) return null;\r\n\r\n // Only elements, attributes, and processing instructions have names\r\n const nodeType = node.nodeType;\r\n if (\r\n nodeType !== 1 && // ELEMENT_NODE\r\n nodeType !== 2 && // ATTRIBUTE_NODE\r\n nodeType !== 7\r\n ) {\r\n // PROCESSING_INSTRUCTION_NODE\r\n return null;\r\n }\r\n\r\n return node.nodeName ?? null;\r\n}\r\n\r\n/**\r\n * fn:nilled($arg as node()?) as xs:boolean?\r\n * Returns true if the argument node is \"nilled\".\r\n * This is relevant for schema-validated documents where xsi:nil=\"true\".\r\n */\r\nexport function nilled(arg: XPathResult, context: XPathContext): boolean | null {\r\n const node = getNode(arg, context);\r\n if (!node) return null;\r\n\r\n // Only element nodes can be nilled\r\n if (node.nodeType !== 1) return null; // ELEMENT_NODE\r\n\r\n // Check for xsi:nil attribute\r\n const nilAttr = node.getAttribute?.('xsi:nil');\r\n\r\n return nilAttr === 'true' || nilAttr === '1';\r\n}\r\n\r\n/**\r\n * fn:data($arg as item()*) as xs:anyAtomicType*\r\n * Returns the result of atomizing a sequence.\r\n */\r\nexport function data(arg: XPathResult): XPathResult[] {\r\n if (arg === null || arg === undefined) return [];\r\n\r\n const items = Array.isArray(arg) ? arg : [arg];\r\n const result: XPathResult[] = [];\r\n\r\n for (const item of items) {\r\n result.push(atomize(item));\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * fn:base-uri() as xs:anyURI?\r\n * fn:base-uri($arg as node()?) as xs:anyURI?\r\n * Returns the base URI of a node.\r\n */\r\nexport function baseUri(arg: XPathResult, context: XPathContext): string | null {\r\n const node = getNode(arg, context);\r\n if (!node) return null;\r\n\r\n // Try to get baseURI from node\r\n if ('baseURI' in node && node.baseURI) {\r\n return node.baseURI as string;\r\n }\r\n\r\n // Check for xml:base attribute\r\n const xmlBase = node.getAttribute?.('xml:base');\r\n if (xmlBase) return xmlBase;\r\n\r\n // Try parent\r\n if (node.parentNode && isNode(node.parentNode)) {\r\n return baseUri([node.parentNode], context);\r\n }\r\n\r\n // Check context for base URI\r\n return context.baseUri ?? null;\r\n}\r\n\r\n/**\r\n * fn:document-uri($arg as node()?) as xs:anyURI?\r\n * Returns the document URI of a document node.\r\n */\r\nexport function documentUri(arg: XPathResult, context: XPathContext): string | null {\r\n const node = getNode(arg, context);\r\n if (!node) return null;\r\n\r\n // Only document nodes have document URIs\r\n if (node.nodeType !== 9) return null; // DOCUMENT_NODE\r\n\r\n // Check for documentURI property\r\n if ('documentURI' in node && node.documentURI) {\r\n return node.documentURI as string;\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * fn:root() as node()\r\n * fn:root($arg as node()?) as node()?\r\n * Returns the root of the tree to which the argument node belongs.\r\n */\r\nexport function root(arg: XPathResult, context: XPathContext): XPathNode | null {\r\n const node = getNode(arg, context);\r\n if (!node) return null;\r\n\r\n let current: XPathNode = node;\r\n let depth = 0;\r\n const visited = new Set<XPathNode>();\r\n\r\n while (current.parentNode && depth < 10000) {\r\n if (visited.has(current)) {\r\n // Circular reference - return current node\r\n return current;\r\n }\r\n visited.add(current);\r\n current = current.parentNode as XPathNode;\r\n depth++;\r\n }\r\n\r\n return current;\r\n}\r\n\r\n/**\r\n * fn:string($arg as item()?) as xs:string\r\n * Returns the string value of the argument.\r\n */\r\nexport function string(arg: XPathResult, context: XPathContext): string {\r\n if (arg === null || arg === undefined) {\r\n // With no argument, use context node\r\n if (!context.node) return '';\r\n return getStringValue(context.node);\r\n }\r\n\r\n if (Array.isArray(arg)) {\r\n if (arg.length === 0) return '';\r\n arg = arg[0];\r\n }\r\n\r\n if (isNode(arg)) {\r\n return getStringValue(arg as XPathNode);\r\n }\r\n\r\n return String(arg);\r\n}\r\n\r\n/**\r\n * fn:number($arg as xs:anyAtomicType?) as xs:double\r\n * Returns the numeric value of the argument.\r\n */\r\nexport function number(arg: XPathResult, context: XPathContext): number {\r\n if (arg === null || arg === undefined) {\r\n // With no argument, use context node string value\r\n if (!context.node) return NaN;\r\n return Number(getStringValue(context.node));\r\n }\r\n\r\n if (Array.isArray(arg)) {\r\n if (arg.length === 0) return NaN;\r\n arg = arg[0];\r\n }\r\n\r\n if (isNode(arg)) {\r\n return Number(getStringValue(arg as XPathNode));\r\n }\r\n\r\n return Number(arg);\r\n}\r\n\r\n/**\r\n * fn:lang($testlang as xs:string?) as xs:boolean\r\n * fn:lang($testlang as xs:string?, $node as node()) as xs:boolean\r\n * Returns true if the language of the node matches the specified language.\r\n */\r\nexport function lang(testlang: XPathResult, nodeArg: XPathResult, context: XPathContext): boolean {\r\n const targetLang = toString(testlang).toLowerCase();\r\n if (!targetLang) return false;\r\n\r\n const node = nodeArg !== undefined ? getNode(nodeArg, context) : context.node;\r\n if (!node) return false;\r\n\r\n let current: XPathNode | null = node;\r\n while (current) {\r\n const langAttr = current.getAttribute?.('xml:lang') || current.getAttribute?.('lang');\r\n if (langAttr) {\r\n const nodeLang = langAttr.toLowerCase();\r\n return nodeLang === targetLang || nodeLang.startsWith(targetLang + '-');\r\n }\r\n current = current.parentNode as XPathNode | null;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * fn:local-name() as xs:string\r\n * fn:local-name($arg as node()?) as xs:string\r\n * Returns the local name of a node.\r\n */\r\nexport function localName(arg: XPathResult, context: XPathContext): string {\r\n const node = getNode(arg, context);\r\n if (!node) return '';\r\n\r\n // Only elements, attributes, and PIs have local names\r\n const nodeType = node.nodeType;\r\n if (\r\n nodeType !== 1 && // ELEMENT_NODE\r\n nodeType !== 2 && // ATTRIBUTE_NODE\r\n nodeType !== 7\r\n ) {\r\n // PROCESSING_INSTRUCTION_NODE\r\n return '';\r\n }\r\n\r\n return node.localName ?? '';\r\n}\r\n\r\n/**\r\n * fn:namespace-uri() as xs:anyURI\r\n * fn:namespace-uri($arg as node()?) as xs:anyURI\r\n * Returns the namespace URI of a node.\r\n */\r\nexport function namespaceUri(arg: XPathResult, context: XPathContext): string {\r\n const node = getNode(arg, context);\r\n if (!node) return '';\r\n\r\n // Only elements and attributes have namespace URIs\r\n const nodeType = node.nodeType;\r\n if (\r\n nodeType !== 1 && // ELEMENT_NODE\r\n nodeType !== 2\r\n ) {\r\n // ATTRIBUTE_NODE\r\n return '';\r\n }\r\n\r\n return node.namespaceUri ?? '';\r\n}\r\n\r\n/**\r\n * fn:name() as xs:string\r\n * fn:name($arg as node()?) as xs:string\r\n * Returns the name of a node as a string.\r\n */\r\nexport function name(arg: XPathResult, context: XPathContext): string {\r\n const node = getNode(arg, context);\r\n if (!node) return '';\r\n\r\n // Only elements, attributes, and PIs have names\r\n const nodeType = node.nodeType;\r\n if (\r\n nodeType !== 1 && // ELEMENT_NODE\r\n nodeType !== 2 && // ATTRIBUTE_NODE\r\n nodeType !== 7\r\n ) {\r\n // PROCESSING_INSTRUCTION_NODE\r\n return '';\r\n }\r\n\r\n return node.nodeName ?? '';\r\n}\r\n\r\n/**\r\n * fn:generate-id() as xs:string\r\n * fn:generate-id($arg as node()?) as xs:string\r\n * Generates a unique ID for a node that is consistent across multiple invocations.\r\n */\r\nexport function generateId(arg: XPathResult, context: XPathContext): string {\r\n const node = getNode(arg, context);\r\n if (!node) return '';\r\n\r\n // Create a WeakMap to store IDs (or use a property on the node itself)\r\n // For simplicity, we'll use a symbol property if available\r\n const idSymbol = Symbol.for('__xpath_node_id__');\r\n\r\n if (!node[idSymbol as any]) {\r\n // Generate a unique ID starting with a letter\r\n const timestamp = Date.now().toString(36);\r\n const random = Math.random().toString(36).substring(2, 8);\r\n const counter = (Math.floor(Math.random() * 10000)).toString(36);\r\n node[idSymbol as any] = `n${timestamp}${random}${counter}`;\r\n }\r\n\r\n return node[idSymbol as any];\r\n}\r\n\r\n/**\r\n * fn:path() as xs:string?\r\n * fn:path($arg as node()?) as xs:string?\r\n * Returns the XPath expression that would select the given node.\r\n */\r\nexport function path(arg: XPathResult, context: XPathContext): string {\r\n const node = getNode(arg, context);\r\n if (!node) return '';\r\n\r\n const pathSegments: string[] = [];\r\n let current: XPathNode | null = node;\r\n let depth = 0;\r\n const visited = new Set<XPathNode>();\r\n\r\n while (current && depth < 10000) {\r\n if (visited.has(current)) {\r\n // Circular reference detected\r\n break;\r\n }\r\n visited.add(current);\r\n const segment = buildPathSegment(current);\r\n if (segment) {\r\n pathSegments.unshift(segment);\r\n }\r\n current = current.parentNode as XPathNode | null;\r\n depth++;\r\n }\r\n\r\n return '/' + pathSegments.join('/');\r\n}\r\n\r\n/**\r\n * fn:has-children() as xs:boolean\r\n * fn:has-children($arg as node()?) as xs:boolean\r\n * Returns true if the argument node has child nodes.\r\n */\r\nexport function hasChildren(arg: XPathResult, context: XPathContext): boolean {\r\n const node = getNode(arg, context);\r\n if (!node) return false;\r\n\r\n if ('childNodes' in node && Array.isArray(node.childNodes)) {\r\n return node.childNodes.length > 0;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n// Note: innermost() and outermost() are implemented in sequence-functions-30.ts\r\n// They are XPath 3.0 functions that operate on sequences, not node-specific functions.\r\n\r\n// ============================================================================\r\n// Helper Functions\r\n// ============================================================================\r\n\r\nfunction getNode(arg: XPathResult, context: XPathContext): XPathNode | null {\r\n if (arg === null || arg === undefined) {\r\n return context.node ?? null;\r\n }\r\n\r\n if (Array.isArray(arg)) {\r\n if (arg.length === 0) return null;\r\n arg = arg[0];\r\n }\r\n\r\n if (isNode(arg)) {\r\n return arg;\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction isNode(value: unknown): value is XPathNode {\r\n return typeof value === 'object' && value !== null && 'nodeType' in value;\r\n}\r\n\r\nfunction getStringValue(node: XPathNode): string {\r\n if (node.textContent !== undefined) {\r\n return node.textContent;\r\n }\r\n\r\n // For element nodes, concatenate all text descendants\r\n if (\r\n node.nodeType === 1 || // ELEMENT_NODE\r\n node.nodeType === 9\r\n ) {\r\n // DOCUMENT_NODE\r\n return getDescendantTextContent(node);\r\n }\r\n\r\n return String(node);\r\n}\r\n\r\nfunction getDescendantTextContent(node: XPathNode): string {\r\n const parts: string[] = [];\r\n\r\n if ('childNodes' in node && Array.isArray(node.childNodes)) {\r\n for (const child of node.childNodes) {\r\n if (child.nodeType === 3) {\r\n // TEXT_NODE\r\n parts.push(child.textContent ?? '');\r\n } else if (child.nodeType === 1) {\r\n // ELEMENT_NODE\r\n parts.push(getDescendantTextContent(child as XPathNode));\r\n }\r\n }\r\n }\r\n\r\n return parts.join('');\r\n}\r\n\r\nfunction atomize(value: XPathResult): XPathResult {\r\n if (value === null || value === undefined) return '';\r\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\r\n return value;\r\n }\r\n if (isNode(value)) {\r\n return getStringValue(value as XPathNode);\r\n }\r\n return String(value);\r\n}\r\n\r\nfunction toString(value: XPathResult): string {\r\n if (value === null || value === undefined) return '';\r\n if (Array.isArray(value)) {\r\n if (value.length === 0) return '';\r\n value = value[0];\r\n }\r\n if (isNode(value)) {\r\n return getStringValue(value as XPathNode);\r\n }\r\n return String(value);\r\n}\r\n\r\n// ============================================================================\r\n// Additional Helper Functions for Advanced Node Operations\r\n// ============================================================================\r\n\r\n// Maximum depth to prevent infinite loops in case of circular references\r\nconst MAX_DEPTH = 10000;\r\n\r\n/**\r\n * Calculate the depth of a node in the document tree.\r\n */\r\nfunction calculateDepth(node: XPathNode): number {\r\n let depth = 0;\r\n let current: XPathNode | null = node;\r\n const visited = new Set<XPathNode>();\r\n\r\n while (current.parentNode && depth < MAX_DEPTH) {\r\n if (visited.has(current)) {\r\n // Circular reference detected\r\n break;\r\n }\r\n visited.add(current);\r\n depth++;\r\n current = current.parentNode as XPathNode;\r\n }\r\n\r\n return depth;\r\n}\r\n\r\n/**\r\n * Check if a node is an ancestor of any node in an array.\r\n */\r\nfunction isAncestorOf(nodes: XPathNode[], node: XPathNode): boolean {\r\n for (const candidate of nodes) {\r\n let current: XPathNode | null = node.parentNode as XPathNode | null;\r\n let depth = 0;\r\n const visited = new Set<XPathNode>();\r\n\r\n while (current && depth < MAX_DEPTH) {\r\n if (visited.has(current)) {\r\n // Circular reference detected\r\n break;\r\n }\r\n if (current === candidate) {\r\n return true;\r\n }\r\n visited.add(current);\r\n current = current.parentNode as XPathNode | null;\r\n depth++;\r\n }\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Build a single segment of an XPath expression for a node.\r\n */\r\nfunction buildPathSegment(node: XPathNode): string {\r\n const nodeName = node.nodeName || 'node()';\r\n const nodeType = node.nodeType;\r\n\r\n switch (nodeType) {\r\n case 1: // ELEMENT_NODE\r\n // Check if we need a position index\r\n const parent = node.parentNode;\r\n if (parent && 'childNodes' in parent && Array.isArray(parent.childNodes)) {\r\n const siblings = parent.childNodes.filter(\r\n (n: any) => n.nodeType === 1 && n.nodeName === nodeName\r\n );\r\n if (siblings.length > 1) {\r\n const position = siblings.indexOf(node) + 1;\r\n return `${nodeName}[${position}]`;\r\n }\r\n }\r\n return nodeName;\r\n case 2: // ATTRIBUTE_NODE\r\n return `@${nodeName}`;\r\n case 3: // TEXT_NODE\r\n return 'text()';\r\n case 7: // PROCESSING_INSTRUCTION_NODE\r\n return `processing-instruction(${nodeName})`;\r\n case 8: // COMMENT_NODE\r\n return 'comment()';\r\n case 9: // DOCUMENT_NODE\r\n return '';\r\n default:\r\n return 'node()';\r\n }\r\n}\r\n\r\n/**\r\n * Normalize an argument to an array of nodes.\r\n */\r\nfunction normalizeToArray(arg: XPathResult): any[] {\r\n if (arg === null || arg === undefined) return [];\r\n if (Array.isArray(arg)) return arg;\r\n return [arg];\r\n}\r\n","import { XPathContext, XPathResult } from '../context';\r\nimport { XPathNode } from '../node';\r\nimport { XPathExpression } from './expression';\r\nimport { JsonToXmlConverter, JsonToXmlOptions } from './json-to-xml-converter';\r\nimport { AtomicType, castAs, getAtomicType } from '../types';\r\nimport {\r\n functionSignatureMismatch,\r\n unresolvedNameReference,\r\n typeMismatch,\r\n invalidCastArgument,\r\n} from '../errors';\r\nimport * as HOF from '../functions/higher-order-functions';\r\nimport * as MATH from '../functions/math-functions';\r\nimport * as SEQ30 from '../functions/sequence-functions-30';\r\nimport * as SEQ from '../functions/sequence-functions';\r\nimport * as ENV from '../functions/environment-functions';\r\nimport * as STR30 from '../functions/string-functions-30';\r\nimport * as ARRAY from '../functions/array-functions';\r\n\r\nimport * as MAP from '../functions/map-functions';\r\nimport * as JSONF from '../functions/json-functions';\r\nimport * as QNAME from '../functions/qname-functions';\r\nimport * as URI from '../functions/uri-functions';\r\nimport * as NODE from '../functions/node-functions';\r\n\r\n/**\r\n * Built-in function registry for XPath 3.0 function references.\r\n * Maps function names to their implementations.\r\n */\r\nconst toStringValue = (arg: any): string => {\r\n if (arg && typeof arg === 'object') {\r\n if (typeof (arg as any).stringValue === 'function') {\r\n return (arg as any).stringValue();\r\n }\r\n if (Array.isArray(arg)) {\r\n if (arg.length === 0) return '';\r\n const firstNode = arg[0];\r\n return firstNode?.textContent ?? String(firstNode);\r\n }\r\n if (typeof (arg as any).textContent === 'string') {\r\n return (arg as any).textContent;\r\n }\r\n if ((arg as any).nodeValue !== undefined && (arg as any).nodeValue !== null) {\r\n return String((arg as any).nodeValue);\r\n }\r\n }\r\n return String(arg ?? '');\r\n};\r\n\r\nconst BUILT_IN_FUNCTIONS: Record<string, (context: XPathContext, ...args: any[]) => any> = {\r\n // String functions\r\n 'upper-case': (_ctx, arg) => toStringValue(arg).toUpperCase(),\r\n 'lower-case': (_ctx, arg) => toStringValue(arg).toLowerCase(),\r\n concat: (_ctx, ...args) => args.map((a) => String(a)).join(''),\r\n 'string-join': (_ctx, seq, sep = '') => {\r\n if (Array.isArray(seq)) {\r\n return seq.map((s) => String(s)).join(String(sep));\r\n }\r\n return String(seq);\r\n },\r\n substring: (_ctx, str, start, len?) => {\r\n const s = String(str);\r\n const startIdx = Math.round(Number(start)) - 1;\r\n if (len === undefined) {\r\n return s.substring(Math.max(0, startIdx));\r\n }\r\n const length = Math.round(Number(len));\r\n const adjustedStart = Math.max(0, startIdx);\r\n return s.substring(adjustedStart, adjustedStart + length);\r\n },\r\n 'string-length': (_ctx, arg) => String(arg).length,\r\n 'normalize-space': (_ctx, arg) => String(arg).trim().replace(/\\s+/g, ' '),\r\n contains: (_ctx, str, sub) => String(str).includes(String(sub)),\r\n 'starts-with': (_ctx, str, sub) => String(str).startsWith(String(sub)),\r\n 'ends-with': (_ctx, str, sub) => String(str).endsWith(String(sub)),\r\n translate: (_ctx, str, from, to) => {\r\n const s = String(str);\r\n const f = String(from);\r\n const t = String(to);\r\n let result = '';\r\n for (const char of s) {\r\n const idx = f.indexOf(char);\r\n if (idx === -1) result += char;\r\n else if (idx < t.length) result += t[idx];\r\n }\r\n return result;\r\n },\r\n replace: (_ctx, input, pattern, replacement) => {\r\n const regex = new RegExp(String(pattern), 'g');\r\n return String(input).replace(regex, String(replacement));\r\n },\r\n matches: (_ctx, input, pattern) => {\r\n const regex = new RegExp(String(pattern));\r\n return regex.test(String(input));\r\n },\r\n tokenize: (_ctx, input, pattern = '\\\\s+') => {\r\n const regex = new RegExp(String(pattern));\r\n return String(input)\r\n .split(regex)\r\n .filter((s) => s.length > 0);\r\n },\r\n\r\n // Numeric functions\r\n abs: (_ctx, arg) => Math.abs(Number(arg)),\r\n ceiling: (_ctx, arg) => Math.ceil(Number(arg)),\r\n floor: (_ctx, arg) => Math.floor(Number(arg)),\r\n round: (_ctx, arg) => Math.round(Number(arg)),\r\n 'round-half-to-even': (_ctx, arg, precision = 0) => {\r\n const p = Math.pow(10, Number(precision));\r\n const n = Number(arg) * p;\r\n const floor = Math.floor(n);\r\n const decimal = n - floor;\r\n if (decimal === 0.5) {\r\n return (floor % 2 === 0 ? floor : floor + 1) / p;\r\n }\r\n return Math.round(n) / p;\r\n },\r\n number: (_ctx, arg) => Number(arg),\r\n\r\n // Boolean functions\r\n true: () => true,\r\n false: () => false,\r\n not: (_ctx, arg) => !arg,\r\n boolean: (_ctx, arg) => {\r\n if (typeof arg === 'boolean') return arg;\r\n if (typeof arg === 'number') return arg !== 0 && !isNaN(arg);\r\n if (typeof arg === 'string') return arg.length > 0;\r\n if (Array.isArray(arg)) return arg.length > 0;\r\n return !!arg;\r\n },\r\n\r\n // Sequence functions\r\n count: (_ctx, seq) =>\r\n Array.isArray(seq) ? seq.length : seq === null || seq === undefined ? 0 : 1,\r\n sum: (_ctx, seq) => {\r\n if (!Array.isArray(seq)) return Number(seq) || 0;\r\n return seq.reduce((acc, val) => acc + (Number(val) || 0), 0);\r\n },\r\n avg: (_ctx, seq) => {\r\n if (!Array.isArray(seq)) return Number(seq);\r\n if (seq.length === 0) return null;\r\n const sum = seq.reduce((acc, val) => acc + (Number(val) || 0), 0);\r\n return sum / seq.length;\r\n },\r\n min: (_ctx, seq) => {\r\n if (!Array.isArray(seq)) return Number(seq);\r\n if (seq.length === 0) return null;\r\n return Math.min(...seq.map((v) => Number(v)));\r\n },\r\n max: (_ctx, seq) => {\r\n if (!Array.isArray(seq)) return Number(seq);\r\n if (seq.length === 0) return null;\r\n return Math.max(...seq.map((v) => Number(v)));\r\n },\r\n empty: (_ctx, seq) => {\r\n if (seq === null || seq === undefined) return true;\r\n if (Array.isArray(seq)) return seq.length === 0;\r\n return false;\r\n },\r\n exists: (_ctx, seq) => {\r\n if (seq === null || seq === undefined) return false;\r\n if (Array.isArray(seq)) return seq.length > 0;\r\n return true;\r\n },\r\n reverse: (_ctx, seq) => {\r\n if (!Array.isArray(seq)) return [seq];\r\n return [...seq].reverse();\r\n },\r\n 'distinct-values': (_ctx, seq) => {\r\n if (!Array.isArray(seq)) return [seq];\r\n return Array.from(new Set(seq));\r\n },\r\n subsequence: (_ctx, seq, start, length?) => {\r\n if (!Array.isArray(seq)) seq = [seq];\r\n const startIdx = Math.round(Number(start)) - 1;\r\n if (length === undefined) {\r\n return seq.slice(Math.max(0, startIdx));\r\n }\r\n const len = Math.round(Number(length));\r\n return seq.slice(Math.max(0, startIdx), Math.max(0, startIdx) + len);\r\n },\r\n 'insert-before': (_ctx, seq, pos, inserts) => {\r\n if (!Array.isArray(seq)) seq = seq === null ? [] : [seq];\r\n if (!Array.isArray(inserts)) inserts = [inserts];\r\n const position = Math.max(0, Math.round(Number(pos)) - 1);\r\n return [...seq.slice(0, position), ...inserts, ...seq.slice(position)];\r\n },\r\n remove: (_ctx, seq, pos) => {\r\n if (!Array.isArray(seq)) seq = [seq];\r\n const position = Math.round(Number(pos)) - 1;\r\n if (position < 0 || position >= seq.length) return seq;\r\n return [...seq.slice(0, position), ...seq.slice(position + 1)];\r\n },\r\n\r\n // Node functions\r\n position: (ctx) => ctx.position ?? 0,\r\n last: (ctx) => ctx.size ?? 0,\r\n string: (ctx, arg?) => {\r\n if (arg === undefined) {\r\n return ctx.node?.textContent ?? '';\r\n }\r\n if (Array.isArray(arg) && arg.length > 0) {\r\n return arg[0]?.textContent ?? String(arg[0]);\r\n }\r\n return String(arg);\r\n },\r\n 'local-name': (ctx, arg?) => {\r\n const node = arg ? (Array.isArray(arg) ? arg[0] : arg) : ctx.node;\r\n return node?.localName ?? '';\r\n },\r\n 'namespace-uri': (ctx, arg?) => {\r\n const node = arg ? (Array.isArray(arg) ? arg[0] : arg) : ctx.node;\r\n return node?.namespaceUri ?? '';\r\n },\r\n name: (ctx, arg?) => {\r\n const node = arg ? (Array.isArray(arg) ? arg[0] : arg) : ctx.node;\r\n return node?.nodeName ?? '';\r\n },\r\n 'generate-id': (ctx, arg?) => NODE.generateId(arg, ctx),\r\n path: (ctx, arg?) => NODE.path(arg, ctx),\r\n 'has-children': (ctx, arg?) => NODE.hasChildren(arg, ctx),\r\n\r\n // Higher-order functions (XPath 3.0)\r\n 'for-each': HOF.forEach,\r\n filter: HOF.filter,\r\n 'fold-left': HOF.foldLeft,\r\n 'fold-right': HOF.foldRight,\r\n 'for-each-pair': HOF.forEachPair,\r\n sort: SEQ30.sort,\r\n apply: HOF.apply,\r\n 'function-name': HOF.functionName,\r\n 'function-arity': HOF.functionArity,\r\n\r\n // Math functions (XPath 3.0 math namespace)\r\n 'math:pi': MATH.pi,\r\n 'math:exp': MATH.exp,\r\n 'math:exp10': MATH.exp10,\r\n 'math:log': MATH.log,\r\n 'math:log10': MATH.log10,\r\n 'math:pow': MATH.pow,\r\n 'math:sqrt': MATH.sqrt,\r\n 'math:sin': MATH.sin,\r\n 'math:cos': MATH.cos,\r\n 'math:tan': MATH.tan,\r\n 'math:asin': MATH.asin,\r\n 'math:acos': MATH.acos,\r\n 'math:atan': MATH.atan,\r\n 'math:atan2': MATH.atan2,\r\n\r\n // Sequence functions (XPath 3.0)\r\n head: (_ctx, seq) => SEQ.head(seq),\r\n tail: (_ctx, seq) => SEQ.tail(seq),\r\n innermost: SEQ30.innermost,\r\n outermost: SEQ30.outermost,\r\n\r\n // Environment functions (XPath 3.0)\r\n 'environment-variable': ENV.environmentVariable,\r\n 'available-environment-variables': ENV.availableEnvironmentVariables,\r\n\r\n // Array functions (XPath 3.1)\r\n 'array:size': ARRAY.arraySize,\r\n 'array:get': ARRAY.arrayGet,\r\n 'array:put': ARRAY.arrayPut,\r\n 'array:append': ARRAY.arrayAppend,\r\n 'array:subarray': ARRAY.arraySubarray,\r\n 'array:remove': ARRAY.arrayRemove,\r\n 'array:insert-before': ARRAY.arrayInsertBefore,\r\n 'array:head': ARRAY.arrayHead,\r\n 'array:tail': ARRAY.arrayTail,\r\n 'array:reverse': ARRAY.arrayReverse,\r\n 'array:join': ARRAY.arrayJoin,\r\n 'array:flatten': ARRAY.arrayFlatten,\r\n 'array:for-each': ARRAY.arrayForEach,\r\n 'array:filter': ARRAY.arrayFilter,\r\n 'array:fold-left': ARRAY.arrayFoldLeft,\r\n 'array:fold-right': ARRAY.arrayFoldRight,\r\n 'array:sort': ARRAY.arraySort,\r\n\r\n // Map functions (XPath 3.1)\r\n 'map:size': MAP.mapSize,\r\n 'map:keys': MAP.mapKeys,\r\n 'map:contains': MAP.mapContains,\r\n 'map:get': MAP.mapGet,\r\n 'map:put': MAP.mapPut,\r\n 'map:entry': MAP.mapEntry,\r\n 'map:merge': MAP.mapMerge,\r\n 'map:for-each': MAP.mapForEach,\r\n 'map:remove': MAP.mapRemove,\r\n\r\n // JSON functions (XPath 3.1)\r\n // Note: xml-to-json is NOT registered here because XSLT provides its own version\r\n // with version checking (only allowed in XSLT 3.0). The XSLT version is registered\r\n // via context.functions in xpath.ts and takes precedence.\r\n 'parse-json': JSONF.parseJson,\r\n serialize: JSONF.serialize,\r\n 'json-to-xml': JSONF.jsonToXml,\r\n\r\n // String functions (XPath 3.0 additions)\r\n 'analyze-string': STR30.analyzeString,\r\n 'format-integer': STR30.formatInteger,\r\n 'format-number': STR30.formatNumber,\r\n\r\n // XPath 2.0 Type Constructor Functions (xs:* namespace)\r\n // These wrap the type system's castAs functionality for function references\r\n 'xs:string': (_ctx, arg) => castAs(arg, 'string'),\r\n 'xs:boolean': (_ctx, arg) => castAs(arg, 'boolean'),\r\n 'xs:decimal': (_ctx, arg) => castAs(arg, 'decimal'),\r\n 'xs:float': (_ctx, arg) => castAs(arg, 'float'),\r\n 'xs:double': (_ctx, arg) => castAs(arg, 'double'),\r\n 'xs:integer': (_ctx, arg) => castAs(arg, 'integer'),\r\n 'xs:duration': (_ctx, arg) => castAs(arg, 'duration'),\r\n 'xs:dateTime': (_ctx, arg) => castAs(arg, 'dateTime'),\r\n 'xs:date': (_ctx, arg) => castAs(arg, 'date'),\r\n 'xs:time': (_ctx, arg) => castAs(arg, 'time'),\r\n 'xs:anyURI': (_ctx, arg) => castAs(arg, 'anyURI'),\r\n 'xs:QName': (_ctx, arg) => castAs(arg, 'QName'),\r\n 'xs:untypedAtomic': (_ctx, arg) => castAs(arg, 'untypedAtomic'),\r\n // Gregorian types\r\n 'xs:gYearMonth': (_ctx, arg) => castAs(arg, 'gYearMonth'),\r\n 'xs:gYear': (_ctx, arg) => castAs(arg, 'gYear'),\r\n 'xs:gMonthDay': (_ctx, arg) => castAs(arg, 'gMonthDay'),\r\n 'xs:gDay': (_ctx, arg) => castAs(arg, 'gDay'),\r\n 'xs:gMonth': (_ctx, arg) => castAs(arg, 'gMonth'),\r\n // Binary types\r\n 'xs:hexBinary': (_ctx, arg) => castAs(arg, 'hexBinary'),\r\n 'xs:base64Binary': (_ctx, arg) => castAs(arg, 'base64Binary'),\r\n // Integer-derived types\r\n 'xs:long': (_ctx, arg) => castAs(arg, 'long'),\r\n 'xs:int': (_ctx, arg) => castAs(arg, 'int'),\r\n 'xs:short': (_ctx, arg) => castAs(arg, 'short'),\r\n 'xs:byte': (_ctx, arg) => castAs(arg, 'byte'),\r\n 'xs:nonPositiveInteger': (_ctx, arg) => castAs(arg, 'nonPositiveInteger'),\r\n 'xs:negativeInteger': (_ctx, arg) => castAs(arg, 'negativeInteger'),\r\n 'xs:nonNegativeInteger': (_ctx, arg) => castAs(arg, 'nonNegativeInteger'),\r\n 'xs:positiveInteger': (_ctx, arg) => castAs(arg, 'positiveInteger'),\r\n 'xs:unsignedLong': (_ctx, arg) => castAs(arg, 'unsignedLong'),\r\n 'xs:unsignedInt': (_ctx, arg) => castAs(arg, 'unsignedInt'),\r\n 'xs:unsignedShort': (_ctx, arg) => castAs(arg, 'unsignedShort'),\r\n 'xs:unsignedByte': (_ctx, arg) => castAs(arg, 'unsignedByte'),\r\n\r\n // XPath 2.0 QName Functions\r\n QName: (_ctx, uri, qname) => QNAME.QName(uri, qname),\r\n 'resolve-QName': (_ctx, qname, element) => QNAME.resolveQName(qname, element),\r\n 'prefix-from-QName': (_ctx, arg) => QNAME.prefixFromQName(arg),\r\n 'local-name-from-QName': (_ctx, arg) => QNAME.localNameFromQName(arg),\r\n 'namespace-uri-from-QName': (_ctx, arg) => QNAME.namespaceUriFromQName(arg),\r\n 'in-scope-prefixes': (_ctx, element) => QNAME.inScopePrefixes(element),\r\n 'namespace-uri-for-prefix': (_ctx, prefix, element) => QNAME.namespaceUriForPrefix(prefix, element),\r\n\r\n // XPath 2.0 URI Functions\r\n 'resolve-uri': (ctx, relative, base?) => URI.resolveUri(relative, base, ctx),\r\n 'encode-for-uri': (_ctx, uriPart) => URI.encodeForUri(uriPart),\r\n 'iri-to-uri': (_ctx, iri) => URI.iriToUri(iri),\r\n 'escape-html-uri': (_ctx, uri) => URI.escapeHtmlUri(uri),\r\n\r\n // XPath 2.0 Node Functions (enhanced)\r\n root: (ctx, arg?) => NODE.root(arg, ctx),\r\n 'base-uri': (ctx, arg?) => NODE.baseUri(arg, ctx),\r\n 'document-uri': (ctx, arg?) => NODE.documentUri(arg, ctx),\r\n nilled: (ctx, arg?) => NODE.nilled(arg, ctx),\r\n 'node-name': (ctx, arg?) => NODE.nodeName(arg, ctx),\r\n data: (_ctx, arg) => NODE.data(arg),\r\n lang: (ctx, testlang, node?) => NODE.lang(testlang, node, ctx),\r\n\r\n // XPath 2.0 Cardinality Functions\r\n 'zero-or-one': (_ctx, arg) => SEQ.zeroOrOne(arg),\r\n 'one-or-more': (_ctx, arg) => SEQ.oneOrMore(arg),\r\n 'exactly-one': (_ctx, arg) => SEQ.exactlyOne(arg),\r\n unordered: (_ctx, arg) => SEQ.unordered(arg),\r\n};\r\n\r\n/**\r\n * Function arity information for variadic functions.\r\n * Format: [minArgs, maxArgs]\r\n */\r\nconst FUNCTION_ARITY: Record<string, [number, number]> = {\r\n concat: [2, Infinity],\r\n substring: [2, 3],\r\n 'string-join': [1, 2],\r\n 'normalize-space': [0, 1],\r\n 'string-length': [0, 1],\r\n 'local-name': [0, 1],\r\n 'namespace-uri': [0, 1],\r\n name: [0, 1],\r\n 'generate-id': [0, 1],\r\n path: [0, 1],\r\n 'has-children': [0, 1],\r\n round: [1, 2],\r\n 'round-half-to-even': [1, 2],\r\n string: [0, 1],\r\n number: [0, 1],\r\n replace: [3, 4],\r\n matches: [2, 3],\r\n tokenize: [1, 3],\r\n // XSLT 2.0 regex functions\r\n 'regex-group': [1, 1],\r\n // XSLT 2.0 grouping functions\r\n 'current-group': [0, 0],\r\n 'current-grouping-key': [0, 0],\r\n subsequence: [2, 3],\r\n 'insert-before': [3, 3],\r\n remove: [2, 2],\r\n // Higher-order functions\r\n 'for-each': [2, 2],\r\n filter: [2, 2],\r\n 'fold-left': [3, 3],\r\n 'fold-right': [3, 3],\r\n 'for-each-pair': [3, 3],\r\n sort: [1, 3],\r\n apply: [2, 2],\r\n 'function-name': [1, 1],\r\n 'function-arity': [1, 1],\r\n // Math functions\r\n 'math:pi': [0, 0],\r\n 'math:exp': [1, 1],\r\n 'math:exp10': [1, 1],\r\n 'math:log': [1, 1],\r\n 'math:log10': [1, 1],\r\n 'math:pow': [2, 2],\r\n 'math:sqrt': [1, 1],\r\n 'math:sin': [1, 1],\r\n 'math:cos': [1, 1],\r\n 'math:tan': [1, 1],\r\n 'math:asin': [1, 1],\r\n 'math:acos': [1, 1],\r\n 'math:atan': [1, 1],\r\n 'math:atan2': [2, 2],\r\n // Sequence functions (XPath 3.0)\r\n head: [1, 1],\r\n tail: [1, 1],\r\n innermost: [1, 1],\r\n outermost: [1, 1],\r\n // Environment functions (XPath 3.0)\r\n 'environment-variable': [1, 1],\r\n 'available-environment-variables': [0, 0],\r\n // Array functions (XPath 3.1)\r\n 'array:size': [1, 1],\r\n 'array:get': [2, 2],\r\n 'array:put': [3, 3],\r\n 'array:append': [2, 2],\r\n 'array:subarray': [2, 3],\r\n 'array:remove': [2, 2],\r\n 'array:insert-before': [3, 3],\r\n 'array:head': [1, 1],\r\n 'array:tail': [1, 1],\r\n 'array:reverse': [1, 1],\r\n 'array:join': [1, 1],\r\n 'array:flatten': [1, 1],\r\n 'array:for-each': [2, 2],\r\n 'array:filter': [2, 2],\r\n 'array:fold-left': [3, 3],\r\n 'array:fold-right': [3, 3],\r\n 'array:sort': [1, 3],\r\n\r\n // Map functions (XPath 3.1)\r\n 'map:size': [1, 1],\r\n 'map:keys': [1, 1],\r\n 'map:contains': [2, 2],\r\n 'map:get': [2, 2],\r\n 'map:put': [3, 3],\r\n 'map:entry': [2, 2],\r\n 'map:merge': [1, 2],\r\n 'map:for-each': [2, 2],\r\n 'map:remove': [2, 2],\r\n\r\n // JSON functions (XPath 3.1)\r\n // Note: xml-to-json arity not registered here - handled by XSLT context.functions\r\n 'parse-json': [1, 2],\r\n serialize: [1, 2],\r\n 'json-to-xml': [1, 2],\r\n\r\n // String functions (XPath 3.0 additions)\r\n 'analyze-string': [2, 3],\r\n 'format-integer': [2, 3],\r\n 'format-number': [2, 3],\r\n\r\n // XPath 2.0 Type Constructor Functions (xs:* namespace)\r\n 'xs:string': [1, 1],\r\n 'xs:boolean': [1, 1],\r\n 'xs:decimal': [1, 1],\r\n 'xs:float': [1, 1],\r\n 'xs:double': [1, 1],\r\n 'xs:integer': [1, 1],\r\n 'xs:duration': [1, 1],\r\n 'xs:dateTime': [1, 1],\r\n 'xs:date': [1, 1],\r\n 'xs:time': [1, 1],\r\n 'xs:anyURI': [1, 1],\r\n 'xs:QName': [1, 1],\r\n 'xs:untypedAtomic': [1, 1],\r\n 'xs:gYearMonth': [1, 1],\r\n 'xs:gYear': [1, 1],\r\n 'xs:gMonthDay': [1, 1],\r\n 'xs:gDay': [1, 1],\r\n 'xs:gMonth': [1, 1],\r\n 'xs:hexBinary': [1, 1],\r\n 'xs:base64Binary': [1, 1],\r\n 'xs:long': [1, 1],\r\n 'xs:int': [1, 1],\r\n 'xs:short': [1, 1],\r\n 'xs:byte': [1, 1],\r\n 'xs:nonPositiveInteger': [1, 1],\r\n 'xs:negativeInteger': [1, 1],\r\n 'xs:nonNegativeInteger': [1, 1],\r\n 'xs:positiveInteger': [1, 1],\r\n 'xs:unsignedLong': [1, 1],\r\n 'xs:unsignedInt': [1, 1],\r\n 'xs:unsignedShort': [1, 1],\r\n 'xs:unsignedByte': [1, 1],\r\n\r\n // XPath 2.0 QName Functions\r\n QName: [2, 2],\r\n 'resolve-QName': [2, 2],\r\n 'prefix-from-QName': [1, 1],\r\n 'local-name-from-QName': [1, 1],\r\n 'namespace-uri-from-QName': [1, 1],\r\n 'in-scope-prefixes': [1, 1],\r\n 'namespace-uri-for-prefix': [2, 2],\r\n\r\n // XPath 2.0 URI Functions\r\n 'resolve-uri': [1, 2],\r\n 'encode-for-uri': [1, 1],\r\n 'iri-to-uri': [1, 1],\r\n 'escape-html-uri': [1, 1],\r\n\r\n // XPath 2.0 Node Functions (enhanced)\r\n root: [0, 1],\r\n 'base-uri': [0, 1],\r\n 'document-uri': [1, 1],\r\n nilled: [1, 1],\r\n 'node-name': [1, 1],\r\n data: [1, 1],\r\n lang: [1, 2],\r\n\r\n // XPath 2.0 Cardinality Functions\r\n 'zero-or-one': [1, 1],\r\n 'one-or-more': [1, 1],\r\n 'exactly-one': [1, 1],\r\n unordered: [1, 1],\r\n};\r\n\r\n/**\r\n * Get a built-in function implementation by name.\r\n */\r\nexport function getBuiltInFunction(\r\n name: string\r\n): ((context: XPathContext, ...args: any[]) => any) | undefined {\r\n return BUILT_IN_FUNCTIONS[name];\r\n}\r\n\r\n/**\r\n * Get the arity range for a built-in function.\r\n */\r\nexport function getBuiltInFunctionArity(name: string): [number, number] | undefined {\r\n return FUNCTION_ARITY[name];\r\n}\r\n\r\nexport class XPathFunctionCall extends XPathExpression {\r\n name: string;\r\n args: XPathExpression[];\r\n private jsonConverter: JsonToXmlConverter = new JsonToXmlConverter();\r\n\r\n constructor(name: string, args: XPathExpression[]) {\r\n super();\r\n this.name = name;\r\n this.args = args;\r\n }\r\n\r\n evaluate(context: XPathContext): XPathResult {\r\n const evaluatedArgs = this.args.map((arg) => arg.evaluate(context));\r\n\r\n // XPath 2.0 constructor functions: QName(...) delegates to atomic type cast\r\n const constructorType = this.getConstructorType();\r\n if (constructorType) {\r\n if (evaluatedArgs.length !== 1) {\r\n throw functionSignatureMismatch(this.name, '1', evaluatedArgs.length);\r\n }\r\n\r\n const raw = evaluatedArgs[0];\r\n if (Array.isArray(raw)) {\r\n if (raw.length === 0) {\r\n throw typeMismatch(\r\n 'single item',\r\n 'empty sequence',\r\n `constructor function ${this.name}`\r\n );\r\n }\r\n if (raw.length !== 1) {\r\n throw typeMismatch(\r\n 'single item',\r\n `sequence of ${raw.length} items`,\r\n `constructor function ${this.name}`\r\n );\r\n }\r\n return this.castConstructorValue(constructorType, raw[0]);\r\n }\r\n\r\n if (raw === undefined || raw === null) {\r\n throw typeMismatch(\r\n 'single item',\r\n 'empty sequence',\r\n `constructor function ${this.name}`\r\n );\r\n }\r\n\r\n return this.castConstructorValue(constructorType, raw);\r\n }\r\n\r\n // Built-in XPath 1.0 functions\r\n switch (this.name) {\r\n // Node set functions\r\n case 'last':\r\n return context.size ?? 0;\r\n case 'position':\r\n return context.position ?? 0;\r\n case 'count':\r\n return Array.isArray(evaluatedArgs[0]) ? evaluatedArgs[0].length : 0;\r\n case 'local-name':\r\n return this.localName(evaluatedArgs, context);\r\n case 'namespace-uri':\r\n return this.namespaceUri(evaluatedArgs, context);\r\n case 'name':\r\n return this.nodeName(evaluatedArgs, context);\r\n\r\n // String functions\r\n case 'string':\r\n return this.stringValue(evaluatedArgs, context);\r\n case 'concat':\r\n return evaluatedArgs.map((arg) => this.convertToString(arg)).join('');\r\n case 'starts-with':\r\n return String(evaluatedArgs[0]).startsWith(String(evaluatedArgs[1]));\r\n case 'contains':\r\n return String(evaluatedArgs[0]).includes(String(evaluatedArgs[1]));\r\n case 'substring-before':\r\n return this.substringBefore(evaluatedArgs);\r\n case 'substring-after':\r\n return this.substringAfter(evaluatedArgs);\r\n case 'substring':\r\n return this.substring(evaluatedArgs);\r\n case 'string-length':\r\n return this.stringLength(evaluatedArgs, context);\r\n case 'normalize-space':\r\n return this.normalizeSpace(evaluatedArgs, context);\r\n case 'translate':\r\n return this.translate(evaluatedArgs);\r\n\r\n // Boolean functions\r\n case 'boolean':\r\n return this.toBoolean(evaluatedArgs[0]);\r\n case 'not':\r\n return !this.toBoolean(evaluatedArgs[0]);\r\n case 'true':\r\n return true;\r\n case 'false':\r\n return false;\r\n case 'lang':\r\n return this.lang(evaluatedArgs, context);\r\n\r\n // Number functions\r\n case 'number':\r\n return this.toNumber(evaluatedArgs, context);\r\n case 'sum':\r\n return this.sum(evaluatedArgs);\r\n case 'floor':\r\n return Math.floor(Number(evaluatedArgs[0]));\r\n case 'ceiling':\r\n return Math.ceil(Number(evaluatedArgs[0]));\r\n case 'round':\r\n return Math.round(Number(evaluatedArgs[0]));\r\n\r\n // JSON functions (XPath 3.1)\r\n case 'json-to-xml':\r\n return this.jsonToXml(evaluatedArgs, context);\r\n\r\n // XSLT 2.0 regex-group function (used in xsl:analyze-string)\r\n case 'regex-group': {\r\n const groupIndex = Math.floor(Number(evaluatedArgs[0]));\r\n // Access regex groups from context.extensions (set during xsl:analyze-string)\r\n const regexGroups = context.extensions?.regexGroups as string[] | undefined;\r\n if (regexGroups && groupIndex >= 0 && groupIndex < regexGroups.length) {\r\n return regexGroups[groupIndex] ?? '';\r\n }\r\n // If context doesn't have regex groups or index out of range, return empty string\r\n return '';\r\n }\r\n\r\n // XSLT 2.0 current-group function (used in xsl:for-each-group)\r\n case 'current-group': {\r\n // Access current group from context.extensions (set during xsl:for-each-group)\r\n const currentGroup = context.extensions?.currentGroup;\r\n return currentGroup ?? [];\r\n }\r\n\r\n // XSLT 2.0 current-grouping-key function (used in xsl:for-each-group)\r\n case 'current-grouping-key': {\r\n // Access current grouping key from context.extensions (set during xsl:for-each-group)\r\n const currentGroupingKey = context.extensions?.currentGroupingKey;\r\n return currentGroupingKey ?? '';\r\n }\r\n\r\n default:\r\n // Check for custom functions in context FIRST (including XSLT extension functions)\r\n // This allows XSLT/custom functions to override built-in functions if needed\r\n if (context.functions && typeof context.functions[this.name] === 'function') {\r\n // Call custom function with context as first argument, followed by evaluated args\r\n // This allows XSLT functions to access context.node, context.variables, etc.\r\n return context.functions[this.name](context, ...evaluatedArgs);\r\n }\r\n\r\n // Check built-in XPath 2.0/3.0 functions from the BUILT_IN_FUNCTIONS map\r\n let builtInFunc = BUILT_IN_FUNCTIONS[this.name];\r\n\r\n // If not found and name has fn: prefix, try without it (fn: is the default function namespace)\r\n if (!builtInFunc && this.name.startsWith('fn:')) {\r\n const localName = this.name.substring(3); // Remove 'fn:' prefix\r\n builtInFunc = BUILT_IN_FUNCTIONS[localName];\r\n }\r\n\r\n // If not found and name is an EQName, try to resolve it\r\n if (!builtInFunc && this.name.startsWith('Q{')) {\r\n const { namespace, localName } = this.parseEQName(this.name);\r\n\r\n // Try local name first\r\n builtInFunc = BUILT_IN_FUNCTIONS[localName];\r\n\r\n // If still not found and namespace is math, try with math: prefix\r\n if (\r\n !builtInFunc &&\r\n namespace === 'http://www.w3.org/2005/xpath-functions/math'\r\n ) {\r\n builtInFunc = BUILT_IN_FUNCTIONS['math:' + localName];\r\n }\r\n\r\n // If still not found and namespace is array, try with array: prefix\r\n if (\r\n !builtInFunc &&\r\n namespace === 'http://www.w3.org/2005/xpath-functions/array'\r\n ) {\r\n builtInFunc = BUILT_IN_FUNCTIONS['array:' + localName];\r\n }\r\n }\r\n\r\n if (builtInFunc) {\r\n return builtInFunc(context, ...evaluatedArgs);\r\n }\r\n\r\n throw unresolvedNameReference(this.name, 'function');\r\n }\r\n }\r\n\r\n private parseEQName(name: string): { namespace: string; localName: string } {\r\n // Parse EQName format: Q{namespace}localName\r\n const match = name.match(/^Q\\{([^}]*)\\}(.+)$/);\r\n if (match) {\r\n return {\r\n namespace: match[1],\r\n localName: match[2],\r\n };\r\n }\r\n // Fallback if not a valid EQName\r\n return { namespace: '', localName: name };\r\n }\r\n\r\n private getConstructorType(): AtomicType | undefined {\r\n // Only treat xs: namespace function names as constructor functions\r\n // to avoid clobbering user-defined functions like my:double\r\n if (!this.name.includes(':')) {\r\n return undefined;\r\n }\r\n\r\n const [prefix, localName] = this.name.split(':');\r\n if (!localName) {\r\n return undefined;\r\n }\r\n\r\n // Only xs: namespace is for constructor functions\r\n if (prefix !== 'xs') {\r\n return undefined;\r\n }\r\n\r\n return getAtomicType(localName);\r\n }\r\n\r\n private castConstructorValue(constructorType: AtomicType, value: unknown): XPathResult {\r\n try {\r\n return constructorType.cast(value);\r\n } catch (err) {\r\n throw invalidCastArgument(value, this.name);\r\n }\r\n }\r\n\r\n private toBoolean(value: XPathResult): boolean {\r\n if (typeof value === 'boolean') return value;\r\n if (typeof value === 'number') return value !== 0 && !isNaN(value);\r\n if (typeof value === 'string') return value.length > 0;\r\n if (Array.isArray(value)) return value.length > 0;\r\n return !!value;\r\n }\r\n\r\n private toNumber(args: XPathResult[], context: XPathContext): number {\r\n const toNumberFromString = (text: string): number => {\r\n const trimmed = text.trim();\r\n if (trimmed.length === 0) {\r\n return NaN;\r\n }\r\n return Number(trimmed);\r\n };\r\n\r\n if (args.length === 0) {\r\n return toNumberFromString(this.stringValue([], context));\r\n }\r\n const value = args[0];\r\n\r\n // Handle NodeValue objects from XSLT context (NumberValue, StringValue, etc.)\r\n if (typeof value === 'object' && value !== null && 'numberValue' in value && typeof (value as any).numberValue === 'function') {\r\n return (value as any).numberValue();\r\n }\r\n\r\n // Handle node-set: get string value of first node then convert to number\r\n if (Array.isArray(value)) {\r\n if (value.length === 0) return NaN;\r\n const firstNode = value[0];\r\n // Get the string value of the node first\r\n const stringValue = this.getNodeStringValue(firstNode);\r\n return toNumberFromString(stringValue);\r\n }\r\n\r\n if (typeof value === 'string') {\r\n return toNumberFromString(value);\r\n }\r\n\r\n return Number(value);\r\n }\r\n\r\n private stringValue(args: XPathResult[], context: XPathContext): string {\r\n if (args.length === 0) {\r\n return context.node?.textContent ?? '';\r\n }\r\n const value = args[0];\r\n if (Array.isArray(value) && value.length > 0) {\r\n return value[0]?.textContent ?? String(value[0]);\r\n }\r\n return String(value);\r\n }\r\n\r\n /**\r\n * Converts an XPath result to a string according to XPath 1.0 specification.\r\n * - Node-set: Returns the string-value of the first node in document order\r\n * - Number: Converts to string representation\r\n * - Boolean: Converts to 'true' or 'false'\r\n * - String: Returns as-is\r\n */\r\n private convertToString(value: XPathResult): string {\r\n // If it's a node-set (array), get the string-value of the first node\r\n if (Array.isArray(value)) {\r\n if (value.length === 0) {\r\n return '';\r\n }\r\n const firstNode = value[0];\r\n // Return the text content of the first node\r\n return this.getNodeStringValue(firstNode);\r\n }\r\n\r\n // For primitive values, use JavaScript's String conversion\r\n return String(value);\r\n }\r\n\r\n /**\r\n * Gets the string-value of a node according to XPath 1.0 specification.\r\n * - Element nodes: Concatenation of all descendant text nodes\r\n * - Text nodes: The character data\r\n * - Attribute nodes: The attribute value\r\n * - Other nodes: Their text content\r\n */\r\n private getNodeStringValue(node: any): string {\r\n if (!node) {\r\n return '';\r\n }\r\n\r\n // If textContent is available, use it\r\n if (typeof node.textContent === 'string') {\r\n return node.textContent;\r\n }\r\n\r\n // For text nodes (nodeType 3) or attribute nodes (nodeType 2), use nodeValue\r\n if (node.nodeType === 3 || node.nodeType === 2) {\r\n return node.nodeValue ?? '';\r\n }\r\n\r\n // For element nodes (nodeType 1), document nodes (nodeType 9),\r\n // or document fragments (nodeType 11), recursively get text content\r\n if (node.nodeType === 1 || node.nodeType === 9 || node.nodeType === 11) {\r\n return this.getDescendantTextContent(node);\r\n }\r\n\r\n // Fallback for other node types\r\n if (node.nodeValue !== undefined && node.nodeValue !== null) {\r\n return String(node.nodeValue);\r\n }\r\n\r\n return '';\r\n }\r\n\r\n /**\r\n * Recursively gets the text content of all descendant text nodes.\r\n */\r\n private getDescendantTextContent(node: any): string {\r\n if (!node.childNodes || node.childNodes.length === 0) {\r\n return '';\r\n }\r\n\r\n let text = '';\r\n for (let i = 0; i < node.childNodes.length; i++) {\r\n const child = node.childNodes[i];\r\n if (child.nodeType === 3) { // Text node\r\n text += child.nodeValue ?? '';\r\n } else if (child.nodeType === 1) { // Element node\r\n text += this.getDescendantTextContent(child);\r\n }\r\n }\r\n return text;\r\n }\r\n\r\n private stringLength(args: XPathResult[], context: XPathContext): number {\r\n if (args.length === 0) {\r\n return this.stringValue([], context).length;\r\n }\r\n return String(args[0]).length;\r\n }\r\n\r\n private normalizeSpace(args: XPathResult[], context: XPathContext): string {\r\n const str = args.length === 0 ? this.stringValue([], context) : String(args[0]);\r\n return str.trim().replace(/\\s+/g, ' ');\r\n }\r\n\r\n private substringBefore(args: XPathResult[]): string {\r\n const str = String(args[0]);\r\n const search = String(args[1]);\r\n const index = str.indexOf(search);\r\n return index === -1 ? '' : str.substring(0, index);\r\n }\r\n\r\n private substringAfter(args: XPathResult[]): string {\r\n const str = String(args[0]);\r\n const search = String(args[1]);\r\n const index = str.indexOf(search);\r\n return index === -1 ? '' : str.substring(index + search.length);\r\n }\r\n\r\n private substring(args: XPathResult[]): string {\r\n const str = String(args[0]);\r\n // XPath uses 1-based indexing and rounds\r\n const start = Math.round(Number(args[1])) - 1;\r\n if (args.length === 2) {\r\n return str.substring(Math.max(0, start));\r\n }\r\n const length = Math.round(Number(args[2]));\r\n const adjustedStart = Math.max(0, start);\r\n const adjustedLength = Math.min(\r\n length - (adjustedStart - start),\r\n str.length - adjustedStart\r\n );\r\n return str.substring(adjustedStart, adjustedStart + adjustedLength);\r\n }\r\n\r\n private translate(args: XPathResult[]): string {\r\n const str = String(args[0]);\r\n const from = String(args[1]);\r\n const to = String(args[2]);\r\n let result = '';\r\n for (const char of str) {\r\n const index = from.indexOf(char);\r\n if (index === -1) {\r\n result += char;\r\n } else if (index < to.length) {\r\n result += to[index];\r\n }\r\n // If index >= to.length, character is removed\r\n }\r\n return result;\r\n }\r\n\r\n private localName(args: XPathResult[], context: XPathContext): string {\r\n const node = this.getNodeArg(args, context);\r\n return node?.localName ?? '';\r\n }\r\n\r\n private namespaceUri(args: XPathResult[], context: XPathContext): string {\r\n const node = this.getNodeArg(args, context);\r\n return node?.namespaceUri ?? '';\r\n }\r\n\r\n private nodeName(args: XPathResult[], context: XPathContext): string {\r\n const node = this.getNodeArg(args, context);\r\n return node?.nodeName ?? '';\r\n }\r\n\r\n private getNodeArg(args: XPathResult[], context: XPathContext): XPathNode | undefined {\r\n if (args.length > 0 && Array.isArray(args[0]) && args[0].length > 0) {\r\n return args[0][0];\r\n }\r\n return context.node;\r\n }\r\n\r\n private sum(args: XPathResult[]): number {\r\n const nodeSet = args[0];\r\n if (!Array.isArray(nodeSet)) return 0;\r\n return (nodeSet as any[]).reduce((acc: number, node: XPathNode) => {\r\n const value = Number(node?.textContent ?? node);\r\n return acc + (isNaN(value) ? 0 : value);\r\n }, 0);\r\n }\r\n\r\n private lang(args: XPathResult[], context: XPathContext): boolean {\r\n const targetLang = String(args[0]).toLowerCase();\r\n let node = context.node;\r\n while (node) {\r\n const lang = node.getAttribute?.('xml:lang') || node.getAttribute?.('lang');\r\n if (lang) {\r\n const nodeLang = lang.toLowerCase();\r\n return nodeLang === targetLang || nodeLang.startsWith(targetLang + '-');\r\n }\r\n node = node.parentNode as XPathNode | undefined;\r\n }\r\n return false;\r\n }\r\n\r\n private jsonToXml(args: XPathResult[], context: XPathContext): XPathResult {\r\n // Check XSLT version - json-to-xml is only supported in XSLT 3.0+\r\n // If xsltVersion is not set (in xpath lib tests), allow it for now\r\n if (context.xsltVersion && context.xsltVersion !== '3.0') {\r\n throw new Error(\r\n 'json-to-xml() is only supported in XSLT 3.0. Use version=\"3.0\" in your stylesheet.'\r\n );\r\n }\r\n\r\n // Get JSON text (first argument)\r\n const jsonText = args.length > 0 ? String(args[0]) : null;\r\n\r\n // Get options (second argument) if provided\r\n let options: JsonToXmlOptions | undefined;\r\n if (args.length > 1 && typeof args[1] === 'object' && args[1] !== null) {\r\n options = this.mapToOptions(args[1] as Record<string, any>);\r\n }\r\n\r\n const documentNode = this.jsonConverter.convert(jsonText, options);\r\n\r\n // Return as node set (array) with single document node, or empty array if null\r\n return documentNode ? [documentNode] : [];\r\n }\r\n\r\n private mapToOptions(optionsMap: Record<string, any>): JsonToXmlOptions {\r\n const options: JsonToXmlOptions = {};\r\n\r\n if (optionsMap['liberal'] !== undefined) {\r\n options.liberal = Boolean(optionsMap['liberal']);\r\n }\r\n\r\n if (optionsMap['duplicates'] !== undefined) {\r\n const dup = String(optionsMap['duplicates']).toLowerCase();\r\n if (dup === 'reject' || dup === 'use-first' || dup === 'retain') {\r\n options.duplicates = dup as 'reject' | 'use-first' | 'retain';\r\n }\r\n }\r\n\r\n if (optionsMap['validate'] !== undefined) {\r\n options.validate = Boolean(optionsMap['validate']);\r\n }\r\n\r\n if (optionsMap['escape'] !== undefined) {\r\n options.escape = Boolean(optionsMap['escape']);\r\n }\r\n\r\n if (optionsMap['fallback'] !== undefined && typeof optionsMap['fallback'] === 'function') {\r\n options.fallback = optionsMap['fallback'];\r\n }\r\n\r\n return options;\r\n }\r\n}\r\n","/**\r\n * XPath 3.0 Let Expression (Section 3.12)\r\n *\r\n * Syntax: let $x := expr1, $y := expr2 return expr3\r\n *\r\n * The let expression binds variables to values and makes them available\r\n * in the return expression. Unlike for expressions, let does not iterate -\r\n * it simply assigns values to variables.\r\n *\r\n * Reference: https://www.w3.org/TR/xpath-30/#id-let-expressions\r\n */\r\n\r\nimport { XPathContext, XPathResult } from '../context';\r\nimport { SequenceType } from '../types';\r\nimport { XPathExpression } from './expression';\r\n\r\n/**\r\n * Represents a single variable binding in a let expression.\r\n */\r\nexport interface XPathLetBinding {\r\n /** Variable name (without $) */\r\n variable: string;\r\n /** Expression whose value is bound to the variable */\r\n expression: XPathExpression;\r\n /** Optional type annotation */\r\n type?: SequenceType;\r\n}\r\n\r\n/**\r\n * XPath 3.0 Let Expression\r\n *\r\n * Examples:\r\n * let $x := 5 return $x * 2 → 10\r\n * let $x := 1, $y := 2 return $x + $y → 3\r\n * let $items := (1, 2, 3) return sum($items) → 6\r\n */\r\nexport class XPathLetExpression extends XPathExpression {\r\n bindings: XPathLetBinding[];\r\n returnExpr: XPathExpression;\r\n\r\n constructor(bindings: XPathLetBinding[], returnExpr: XPathExpression) {\r\n super();\r\n this.bindings = bindings;\r\n this.returnExpr = returnExpr;\r\n }\r\n\r\n evaluate(context: XPathContext): XPathResult {\r\n // Start with existing variables\r\n const variables = { ...(context.variables ?? {}) };\r\n\r\n // Evaluate each binding and add to variables\r\n let currentContext: XPathContext = { ...context, variables };\r\n\r\n for (const binding of this.bindings) {\r\n const value = binding.expression.evaluate(currentContext);\r\n variables[binding.variable] = value;\r\n currentContext = { ...currentContext, variables: { ...variables } };\r\n }\r\n\r\n // Evaluate return expression with all bindings in scope\r\n return this.returnExpr.evaluate(currentContext);\r\n }\r\n\r\n toString(): string {\r\n const bindingStrs = this.bindings.map((b) => `$${b.variable} := ${b.expression}`);\r\n return `let ${bindingStrs.join(', ')} return ${this.returnExpr}`;\r\n }\r\n}\r\n","/**\r\n * XPath 3.0 Simple Map Operator (!) (Section 3.3.2)\r\n *\r\n * Syntax: expr1 ! expr2\r\n *\r\n * The simple map operator evaluates expr1 to produce a sequence,\r\n * then for each item in the sequence, evaluates expr2 with that\r\n * item as the context item. The results are concatenated into\r\n * a single sequence.\r\n *\r\n * This is equivalent to: for $i in expr1 return $i/expr2\r\n * but more concise for simple cases.\r\n *\r\n * Reference: https://www.w3.org/TR/xpath-30/#id-map-operator\r\n */\r\n\r\nimport { XPathContext, XPathResult } from '../context';\r\nimport { XPathExpression } from './expression';\r\n\r\n/**\r\n * XPath 3.0 Simple Map Expression (!)\r\n *\r\n * Examples:\r\n * (1, 2, 3) ! (. * 2) → (2, 4, 6)\r\n * $items ! @id → sequence of @id values from each item\r\n * $items ! name() → sequence of element names\r\n * \"hello\" ! string-length(.) → 5\r\n * (1 to 5) ! (. * .) → (1, 4, 9, 16, 25)\r\n */\r\nexport class XPathSimpleMapExpression extends XPathExpression {\r\n left: XPathExpression;\r\n right: XPathExpression;\r\n\r\n constructor(left: XPathExpression, right: XPathExpression) {\r\n super();\r\n this.left = left;\r\n this.right = right;\r\n }\r\n\r\n evaluate(context: XPathContext): XPathResult {\r\n // Evaluate left expression to get the sequence\r\n const leftValue = this.left.evaluate(context);\r\n const sequence = this.normalizeToSequence(leftValue);\r\n\r\n if (sequence.length === 0) {\r\n return [];\r\n }\r\n\r\n const results: any[] = [];\r\n const size = sequence.length;\r\n\r\n // For each item in the sequence, evaluate right expression with that item as context\r\n for (let i = 0; i < size; i++) {\r\n const item = sequence[i];\r\n\r\n // Create context with item as context node/item\r\n const itemContext: XPathContext = {\r\n ...context,\r\n position: i + 1,\r\n size,\r\n };\r\n\r\n // If item is a node, set it as context node\r\n if (this.isNode(item)) {\r\n itemContext.node = item;\r\n }\r\n\r\n // For non-node items, we need to make the item available\r\n // In XPath 3.0, the context item can be an atomic value\r\n // We store it in a special way that expressions can access\r\n (itemContext as any).contextItem = item;\r\n\r\n const rightValue = this.right.evaluate(itemContext);\r\n this.appendResults(results, rightValue);\r\n }\r\n\r\n return results;\r\n }\r\n\r\n /**\r\n * Normalize a value to a sequence (array).\r\n */\r\n private normalizeToSequence(value: XPathResult): any[] {\r\n if (value === null || value === undefined) {\r\n return [];\r\n }\r\n if (Array.isArray(value)) {\r\n return value;\r\n }\r\n return [value];\r\n }\r\n\r\n /**\r\n * Check if a value is a DOM node.\r\n */\r\n private isNode(value: any): boolean {\r\n return value && typeof value === 'object' && 'nodeType' in value;\r\n }\r\n\r\n /**\r\n * Append results to the output array, flattening sequences.\r\n */\r\n private appendResults(results: any[], value: XPathResult): void {\r\n if (value === null || value === undefined) {\r\n return;\r\n }\r\n if (Array.isArray(value)) {\r\n results.push(...value);\r\n } else {\r\n results.push(value);\r\n }\r\n }\r\n\r\n toString(): string {\r\n return `${this.left} ! ${this.right}`;\r\n }\r\n}\r\n","/**\r\n * XPath 3.0 String Concatenation Operator (||) (Section 3.7.1)\r\n *\r\n * Syntax: expr1 || expr2\r\n *\r\n * The string concatenation operator atomizes both operands,\r\n * converts them to strings, and concatenates them.\r\n *\r\n * Reference: https://www.w3.org/TR/xpath-30/#id-concat\r\n */\r\n\r\nimport { XPathContext, XPathResult } from '../context';\r\nimport { XPathExpression } from './expression';\r\n\r\n/**\r\n * XPath 3.0 String Concatenation Expression (||)\r\n *\r\n * Examples:\r\n * \"Hello\" || \" \" || \"World\" → \"Hello World\"\r\n * \"Value: \" || 42 → \"Value: 42\"\r\n * \"Items: \" || count($items) → \"Items: 5\"\r\n * () || \"text\" → \"text\" (empty sequence converts to \"\")\r\n */\r\nexport class XPathStringConcatExpression extends XPathExpression {\r\n left: XPathExpression;\r\n right: XPathExpression;\r\n\r\n constructor(left: XPathExpression, right: XPathExpression) {\r\n super();\r\n this.left = left;\r\n this.right = right;\r\n }\r\n\r\n evaluate(context: XPathContext): string {\r\n // Evaluate both operands\r\n const leftValue = this.left.evaluate(context);\r\n const rightValue = this.right.evaluate(context);\r\n\r\n // Atomize and convert to strings\r\n const leftStr = this.atomizeToString(leftValue);\r\n const rightStr = this.atomizeToString(rightValue);\r\n\r\n // Concatenate\r\n return leftStr + rightStr;\r\n }\r\n\r\n /**\r\n * Atomize a value and convert to string.\r\n * Empty sequence becomes empty string.\r\n */\r\n private atomizeToString(value: XPathResult): string {\r\n // Empty sequence\r\n if (value === null || value === undefined) {\r\n return '';\r\n }\r\n\r\n // Handle NodeValue objects from XSLT context (StringValue, NumberValue, etc.)\r\n if (typeof value === 'object' && 'stringValue' in value && typeof (value as any).stringValue === 'function') {\r\n return (value as any).stringValue();\r\n }\r\n\r\n // Array (sequence)\r\n if (Array.isArray(value)) {\r\n if (value.length === 0) {\r\n return '';\r\n }\r\n // For sequences with multiple items, concatenate their string values with space\r\n // Actually in XPath 3.0, atomization of a sequence of >1 item is an error for ||\r\n // But for practical purposes, we'll take the first item\r\n return this.valueToString(value[0]);\r\n }\r\n\r\n return this.valueToString(value);\r\n }\r\n\r\n /**\r\n * Convert a single value to string.\r\n */\r\n private valueToString(value: any): string {\r\n if (value === null || value === undefined) {\r\n return '';\r\n }\r\n\r\n // Handle NodeValue objects from XSLT context (StringValue, NumberValue, etc.)\r\n if (typeof value === 'object' && 'stringValue' in value && typeof value.stringValue === 'function') {\r\n return value.stringValue();\r\n }\r\n\r\n if (typeof value === 'string') {\r\n return value;\r\n }\r\n\r\n if (typeof value === 'number') {\r\n // Handle special numeric values\r\n if (Number.isNaN(value)) return 'NaN';\r\n if (value === Infinity) return 'INF';\r\n if (value === -Infinity) return '-INF';\r\n // Remove trailing zeros after decimal point\r\n return String(value);\r\n }\r\n\r\n if (typeof value === 'boolean') {\r\n return value ? 'true' : 'false';\r\n }\r\n\r\n // Node - get string value\r\n if (this.isNode(value)) {\r\n return this.getNodeStringValue(value);\r\n }\r\n\r\n // Default: convert to string\r\n return String(value);\r\n }\r\n\r\n /**\r\n * Check if a value is a DOM node.\r\n */\r\n private isNode(value: any): boolean {\r\n return value && typeof value === 'object' && 'nodeType' in value;\r\n }\r\n\r\n /**\r\n * Get the string value of a node.\r\n */\r\n private getNodeStringValue(node: any): string {\r\n if (!node) return '';\r\n\r\n // Text or CDATA node\r\n if (node.nodeType === 3 || node.nodeType === 4) {\r\n return node.nodeValue || '';\r\n }\r\n\r\n // Attribute node\r\n if (node.nodeType === 2) {\r\n return node.value || node.nodeValue || '';\r\n }\r\n\r\n // Element or document node - concatenate all text content\r\n if (node.nodeType === 1 || node.nodeType === 9) {\r\n return node.textContent || '';\r\n }\r\n\r\n // Comment or processing instruction\r\n if (node.nodeType === 7 || node.nodeType === 8) {\r\n return node.nodeValue || '';\r\n }\r\n\r\n return '';\r\n }\r\n\r\n toString(): string {\r\n return `${this.left} || ${this.right}`;\r\n }\r\n}\r\n","/**\r\n * String Template Expression\r\n *\r\n * Implements XPath 3.0+ string templates with embedded expressions.\r\n * Syntax: `Hello {$name}, you are {$age} years old`\r\n *\r\n * Reference: XPath 3.0 Section 3.7 (String Constructors)\r\n */\r\n\r\nimport { XPathExpression } from './expression';\r\nimport { XPathContext, XPathResult } from '../context';\r\n\r\n/**\r\n * Represents a string template with embedded expressions.\r\n * Parts are alternating strings and expressions.\r\n */\r\nexport class StringTemplateExpression implements XPathExpression {\r\n /**\r\n * Array of parts: alternating strings and Expression objects\r\n * Strings are at even indices (0, 2, 4, ...)\r\n * Expressions are at odd indices (1, 3, 5, ...)\r\n */\r\n private parts: (string | XPathExpression)[];\r\n\r\n constructor(parts: (string | XPathExpression)[]) {\r\n this.parts = parts;\r\n }\r\n\r\n evaluate(context: XPathContext): XPathResult {\r\n const result: string[] = [];\r\n\r\n for (const part of this.parts) {\r\n if (typeof part === 'string') {\r\n // String part - add as-is\r\n result.push(part);\r\n } else {\r\n // Expression part - evaluate and convert to string\r\n const value = part.evaluate(context);\r\n result.push(this.valueToString(value));\r\n }\r\n }\r\n\r\n return result.join('');\r\n }\r\n\r\n /**\r\n * Convert a value to string for concatenation in template.\r\n */\r\n private valueToString(value: XPathResult): string {\r\n if (value === null || value === undefined) {\r\n return '';\r\n }\r\n\r\n if (typeof value === 'string') {\r\n return value;\r\n }\r\n\r\n if (typeof value === 'number') {\r\n // Handle special numbers per XPath spec\r\n if (Number.isNaN(value)) return 'NaN';\r\n if (value === Infinity) return 'INF';\r\n if (value === -Infinity) return '-INF';\r\n return String(value);\r\n }\r\n\r\n if (typeof value === 'boolean') {\r\n return value ? 'true' : 'false';\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n // Array: convert first item\r\n if (value.length === 0) return '';\r\n return this.valueToString(value[0]);\r\n }\r\n\r\n // Node or other object\r\n if (typeof value === 'object' && value !== null) {\r\n // If it's a node, use its string value\r\n if ('nodeType' in value && value.nodeType) {\r\n return this.getNodeStringValue(value);\r\n }\r\n\r\n // For other objects, use toString if available\r\n if (typeof value.toString === 'function') {\r\n const str = value.toString();\r\n if (str !== '[object Object]') {\r\n return str;\r\n }\r\n }\r\n }\r\n\r\n return String(value);\r\n }\r\n\r\n /**\r\n * Get string value of a node.\r\n */\r\n private getNodeStringValue(node: any): string {\r\n if (node.textContent !== undefined) {\r\n return String(node.textContent);\r\n }\r\n\r\n if (node.nodeType === 3) {\r\n // TEXT_NODE\r\n return node.data || node.textContent || '';\r\n }\r\n\r\n if (node.nodeType === 1 || node.nodeType === 9) {\r\n // ELEMENT_NODE or DOCUMENT_NODE - concatenate all text descendants\r\n return this.getDescendantTextContent(node);\r\n }\r\n\r\n return '';\r\n }\r\n\r\n /**\r\n * Get all text content from node and descendants.\r\n */\r\n private getDescendantTextContent(node: any): string {\r\n const parts: string[] = [];\r\n\r\n if ('childNodes' in node && Array.isArray(node.childNodes)) {\r\n for (const child of node.childNodes) {\r\n if (child.nodeType === 3) {\r\n // TEXT_NODE\r\n parts.push(child.textContent ?? child.data ?? '');\r\n } else if (child.nodeType === 1) {\r\n // ELEMENT_NODE\r\n parts.push(this.getDescendantTextContent(child));\r\n }\r\n }\r\n }\r\n\r\n return parts.join('');\r\n }\r\n}\r\n\r\n/**\r\n * Parse a string template and extract parts.\r\n * Returns array of alternating strings and parsed expression strings (not yet parsed).\r\n * The actual parsing is deferred to avoid circular dependencies.\r\n */\r\nexport function parseStringTemplate(template: string): (string | { expressionString: string })[] {\r\n const parts: (string | { expressionString: string })[] = [];\r\n let current = '';\r\n let i = 0;\r\n\r\n while (i < template.length) {\r\n const char = template[i];\r\n\r\n // Check for escape sequences\r\n if (char === '\\\\' && i + 1 < template.length) {\r\n const nextChar = template[i + 1];\r\n switch (nextChar) {\r\n case '`':\r\n current += '`';\r\n i += 2;\r\n break;\r\n case '{':\r\n current += '{';\r\n i += 2;\r\n break;\r\n case '}':\r\n current += '}';\r\n i += 2;\r\n break;\r\n case 'n':\r\n current += '\\n';\r\n i += 2;\r\n break;\r\n case 'r':\r\n current += '\\r';\r\n i += 2;\r\n break;\r\n case 't':\r\n current += '\\t';\r\n i += 2;\r\n break;\r\n case '\\\\':\r\n current += '\\\\';\r\n i += 2;\r\n break;\r\n default:\r\n // Unknown escape - keep as-is\r\n current += char;\r\n i++;\r\n }\r\n } else if (char === '{' && i + 1 < template.length && template[i + 1] !== '{') {\r\n // Start of embedded expression\r\n // Save current string part if not empty\r\n if (current.length > 0) {\r\n parts.push(current);\r\n current = '';\r\n }\r\n\r\n // Find matching closing brace\r\n let depth = 1;\r\n let j = i + 1;\r\n while (j < template.length && depth > 0) {\r\n if (template[j] === '{' && template[j - 1] !== '\\\\') {\r\n depth++;\r\n } else if (template[j] === '}' && template[j - 1] !== '\\\\') {\r\n depth--;\r\n }\r\n j++;\r\n }\r\n\r\n if (depth !== 0) {\r\n throw new Error('Unclosed expression in string template');\r\n }\r\n\r\n // Extract expression string (without parsing)\r\n const exprStr = template.substring(i + 1, j - 1);\r\n parts.push({ expressionString: exprStr });\r\n\r\n i = j;\r\n } else {\r\n current += char;\r\n i++;\r\n }\r\n }\r\n\r\n // Add final string part if not empty\r\n if (current.length > 0) {\r\n parts.push(current);\r\n }\r\n\r\n return parts;\r\n}\r\n","/**\r\n * XPath 3.0 Arrow Operator (=>) (Section 3.4)\r\n *\r\n * Syntax: expr => func(args)\r\n *\r\n * The arrow operator is syntactic sugar that allows function calls\r\n * to be chained in a more readable left-to-right style.\r\n * expr => f(arg2, arg3) is equivalent to f(expr, arg2, arg3)\r\n *\r\n * Reference: https://www.w3.org/TR/xpath-30/#id-arrow-operator\r\n */\r\n\r\nimport { XPathContext, XPathResult } from '../context';\r\nimport { XPathExpression } from './expression';\r\nimport { XPathFunctionCall } from './function-call-expression';\r\n\r\n/**\r\n * XPath 3.0 Arrow Expression (=>)\r\n *\r\n * The expression before => becomes the first argument to the function.\r\n *\r\n * Examples:\r\n * \"hello\" => upper-case() → \"HELLO\"\r\n * \"hello\" => substring(2, 3) → \"ell\"\r\n * $input => upper-case() => substring(1, 3) → \"HEL\"\r\n * (1, 2, 3) => sum() → 6\r\n */\r\nexport class XPathArrowExpression extends XPathExpression {\r\n /** The expression that becomes the first argument */\r\n input: XPathExpression;\r\n /** The function name (may include namespace prefix) */\r\n functionName: string;\r\n /** Additional arguments (after the implicit first argument) */\r\n args: XPathExpression[];\r\n\r\n constructor(input: XPathExpression, functionName: string, args: XPathExpression[]) {\r\n super();\r\n this.input = input;\r\n this.functionName = functionName;\r\n this.args = args;\r\n }\r\n\r\n evaluate(context: XPathContext): XPathResult {\r\n // The arrow operator transforms expr => f(args) into f(expr, args)\r\n // We create a function call with the input as the first argument\r\n const allArgs = [this.input, ...this.args];\r\n const funcCall = new XPathFunctionCall(this.functionName, allArgs);\r\n return funcCall.evaluate(context);\r\n }\r\n\r\n toString(): string {\r\n const argsStr = this.args.length > 0 ? this.args.map((a) => a.toString()).join(', ') : '';\r\n return `${this.input} => ${this.functionName}(${argsStr})`;\r\n }\r\n}\r\n","/**\r\n * XPath 3.0 Named Function Reference (Section 3.1.6)\r\n *\r\n * Syntax: fn:name#arity\r\n *\r\n * A named function reference returns a function item that refers to\r\n * a named function with the specified arity.\r\n *\r\n * Reference: https://www.w3.org/TR/xpath-30/#id-named-function-ref\r\n */\r\n\r\nimport { XPathContext, XPathResult, XPathFunctionItem } from '../context';\r\nimport { FN_NAMESPACE, MATH_NAMESPACE } from '../types/function-type';\r\nimport { XPathExpression } from './expression';\r\nimport { getBuiltInFunction, getBuiltInFunctionArity } from './function-call-expression';\r\n\r\n/**\r\n * XPath 3.0 Named Function Reference\r\n *\r\n * Examples:\r\n * fn:upper-case#1 → function item for upper-case with arity 1\r\n * fn:concat#2 → function item for concat with arity 2\r\n * fn:substring#2 → function item for substring(string, start)\r\n * fn:substring#3 → function item for substring(string, start, length)\r\n * math:sqrt#1 → function item for math:sqrt\r\n */\r\nexport class XPathNamedFunctionRef extends XPathExpression {\r\n /** Function name (may include namespace prefix) */\r\n name: string;\r\n /** Function arity (number of parameters) */\r\n arity: number;\r\n\r\n constructor(name: string, arity: number) {\r\n super();\r\n this.name = name;\r\n this.arity = arity;\r\n }\r\n\r\n evaluate(context: XPathContext): XPathFunctionItem {\r\n // Resolve the function by name and arity\r\n const funcItem = this.resolveFunction(context);\r\n if (!funcItem) {\r\n throw new Error(`Unknown function: ${this.name}#${this.arity}`);\r\n }\r\n return funcItem;\r\n }\r\n\r\n /**\r\n * Resolve the named function to a function item.\r\n */\r\n private resolveFunction(context: XPathContext): XPathFunctionItem | null {\r\n // Parse the name to get namespace and local name\r\n const { namespace: parsedNamespace, localName } = this.parseNameWithNamespace(\r\n this.name,\r\n context\r\n );\r\n\r\n // Use the parsed namespace\r\n const namespace = parsedNamespace;\r\n\r\n // Try to get built-in function - first try local name, then with namespace prefix\r\n let builtIn = getBuiltInFunction(localName);\r\n let lookupName = localName;\r\n\r\n // If not found and namespace is math, try with math: prefix\r\n if (!builtIn && namespace === MATH_NAMESPACE) {\r\n builtIn = getBuiltInFunction('math:' + localName);\r\n lookupName = 'math:' + localName;\r\n }\r\n\r\n if (builtIn) {\r\n // Verify arity matches\r\n const expectedArity = getBuiltInFunctionArity(lookupName);\r\n if (expectedArity !== undefined && !this.arityMatches(lookupName, this.arity)) {\r\n throw new Error(`Function ${this.name} does not accept ${this.arity} arguments`);\r\n }\r\n\r\n // Create a function item that wraps the built-in\r\n const implementation = (...args: any[]) => {\r\n // Build a minimal context for function evaluation\r\n return builtIn(context, ...args);\r\n };\r\n\r\n return {\r\n __isFunctionItem: true as const,\r\n implementation,\r\n arity: this.arity,\r\n name: localName,\r\n namespace,\r\n };\r\n }\r\n\r\n // Check context's function registry\r\n if (context.functionRegistry) {\r\n // Try looking up by local name or full name\r\n const registeredFunc =\r\n context.functionRegistry[localName] || context.functionRegistry[this.name];\r\n if (registeredFunc) {\r\n return {\r\n __isFunctionItem: true as const,\r\n implementation: registeredFunc,\r\n arity: this.arity,\r\n name: localName,\r\n namespace,\r\n };\r\n }\r\n }\r\n\r\n // Check custom functions\r\n if (context.functions) {\r\n const customFunc = context.functions[this.name] || context.functions[localName];\r\n if (customFunc) {\r\n return {\r\n __isFunctionItem: true as const,\r\n implementation: customFunc,\r\n arity: this.arity,\r\n name: localName,\r\n namespace,\r\n };\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * Check if the given arity is valid for the function.\r\n */\r\n private arityMatches(funcName: string, arity: number): boolean {\r\n // Some functions have variable arity\r\n const variableArityFuncs: Record<string, [number, number]> = {\r\n concat: [2, Infinity],\r\n substring: [2, 3],\r\n 'string-join': [1, 2],\r\n 'normalize-space': [0, 1],\r\n 'string-length': [0, 1],\r\n 'local-name': [0, 1],\r\n 'namespace-uri': [0, 1],\r\n name: [0, 1],\r\n round: [1, 2],\r\n 'format-number': [2, 3],\r\n };\r\n\r\n const range = variableArityFuncs[funcName];\r\n if (range) {\r\n return arity >= range[0] && arity <= range[1];\r\n }\r\n\r\n // For functions not in the variable arity list, accept any reasonable arity\r\n return arity >= 0 && arity <= 10;\r\n }\r\n\r\n /**\r\n * Parse a QName or EQName into namespace and local name.\r\n * Handles both prefix:local format and Q{uri}local format.\r\n */\r\n private parseNameWithNamespace(\r\n name: string,\r\n context: XPathContext\r\n ): { namespace?: string; localName: string } {\r\n // Check if it's an EQName (Q{uri}local)\r\n if (name.startsWith('Q{')) {\r\n const match = name.match(/^Q\\{([^}]*)\\}(.+)$/);\r\n if (match) {\r\n const [, uri, localName] = match;\r\n return {\r\n namespace: uri || undefined,\r\n localName,\r\n };\r\n }\r\n }\r\n\r\n // Parse as traditional QName (prefix:local)\r\n const colonIndex = name.indexOf(':');\r\n if (colonIndex > 0) {\r\n const prefix = name.substring(0, colonIndex);\r\n const localName = name.substring(colonIndex + 1);\r\n\r\n // Resolve prefix to namespace\r\n let namespace: string | undefined;\r\n if (prefix === 'fn') {\r\n namespace = FN_NAMESPACE;\r\n } else if (prefix === 'math') {\r\n namespace = MATH_NAMESPACE;\r\n } else if (context.namespaces && context.namespaces[prefix]) {\r\n namespace = context.namespaces[prefix];\r\n }\r\n\r\n return { namespace, localName };\r\n }\r\n\r\n // No prefix, use default function namespace\r\n return { namespace: FN_NAMESPACE, localName: name };\r\n }\r\n\r\n toString(): string {\r\n return `${this.name}#${this.arity}`;\r\n }\r\n}\r\n","/**\r\n * XPath 3.0 Inline Function Expression (Section 3.1.7)\r\n *\r\n * Syntax: function($param1 as Type1, $param2 as Type2) as ReturnType { body-expr }\r\n *\r\n * Inline functions create anonymous function items with access to\r\n * variables in the enclosing scope (closure).\r\n *\r\n * Reference: https://www.w3.org/TR/xpath-30/#id-inline-func\r\n */\r\n\r\nimport { XPathContext, XPathResult, XPathFunctionItem } from '../context';\r\nimport { SequenceType } from '../types';\r\nimport { XPathExpression } from './expression';\r\n\r\n/**\r\n * Represents a parameter in an inline function definition.\r\n */\r\nexport interface InlineFunctionParameter {\r\n /** Parameter name (without $) */\r\n name: string;\r\n /** Optional type annotation */\r\n type?: SequenceType;\r\n}\r\n\r\n/**\r\n * XPath 3.0 Inline Function Expression\r\n *\r\n * Creates an anonymous function item that can be:\r\n * - Stored in a variable\r\n * - Passed to higher-order functions\r\n * - Invoked dynamically\r\n *\r\n * Examples:\r\n * function($x) { $x + 1 }\r\n * function($x as xs:integer) as xs:integer { $x * 2 }\r\n * function($a, $b) { $a + $b }\r\n *\r\n * Inline functions capture their lexical environment (closure):\r\n * let $multiplier := 3\r\n * return function($x) { $x * $multiplier }\r\n */\r\nexport class XPathInlineFunctionExpression extends XPathExpression {\r\n /** Function parameters */\r\n params: InlineFunctionParameter[];\r\n /** Function body expression */\r\n body: XPathExpression;\r\n /** Optional return type annotation */\r\n returnType?: SequenceType;\r\n\r\n constructor(\r\n params: InlineFunctionParameter[],\r\n body: XPathExpression,\r\n returnType?: SequenceType\r\n ) {\r\n super();\r\n this.params = params;\r\n this.body = body;\r\n this.returnType = returnType;\r\n }\r\n\r\n evaluate(context: XPathContext): XPathFunctionItem {\r\n // Capture the current context's variables for closure\r\n const closureVariables = { ...(context.variables ?? {}) };\r\n\r\n // Create the function implementation\r\n const self = this;\r\n const implementation = function (...args: any[]): XPathResult {\r\n // Create a new context with closure variables and parameter bindings\r\n const variables: Record<string, any> = { ...closureVariables };\r\n\r\n // Bind arguments to parameters\r\n for (let i = 0; i < self.params.length; i++) {\r\n const param = self.params[i];\r\n const arg = i < args.length ? args[i] : null;\r\n variables[param.name] = arg;\r\n }\r\n\r\n // Evaluate body with the new context\r\n const evalContext: XPathContext = {\r\n ...context,\r\n variables,\r\n };\r\n\r\n return self.body.evaluate(evalContext);\r\n };\r\n\r\n // Create and return the function item\r\n return {\r\n __isFunctionItem: true as const,\r\n implementation,\r\n arity: this.params.length,\r\n name: undefined,\r\n namespace: undefined,\r\n };\r\n }\r\n\r\n toString(): string {\r\n const paramsStr = this.params\r\n .map((p) => {\r\n let s = `$${p.name}`;\r\n if (p.type) s += ` as ${p.type}`;\r\n return s;\r\n })\r\n .join(', ');\r\n\r\n let result = `function(${paramsStr})`;\r\n if (this.returnType) {\r\n result += ` as ${this.returnType}`;\r\n }\r\n result += ` { ${this.body} }`;\r\n return result;\r\n }\r\n}\r\n","/**\r\n * XPath 3.0 Dynamic Function Call (Section 3.2)\r\n *\r\n * Syntax: $func($arg1, $arg2, ...)\r\n *\r\n * A dynamic function call invokes a function item stored in a variable\r\n * or returned by an expression.\r\n *\r\n * Reference: https://www.w3.org/TR/xpath-30/#id-dynamic-function-call\r\n */\r\n\r\nimport { XPathContext, XPathResult, XPathFunctionItem } from '../context';\r\nimport { XPathExpression } from './expression';\r\nimport { isXPathMap } from './map-constructor-expression';\r\nimport { isXPathArray, getArrayMember } from './array-constructor-expression';\r\n\r\n/**\r\n * Check if a value is a function item.\r\n */\r\nfunction isFunctionItem(value: any): value is XPathFunctionItem {\r\n return value && typeof value === 'object' && value.__isFunctionItem === true;\r\n}\r\n\r\n/**\r\n * XPath 3.0 Dynamic Function Call\r\n *\r\n * Evaluates a function expression to get a function item,\r\n * then invokes it with the provided arguments.\r\n *\r\n * Examples:\r\n * let $f := fn:upper-case#1 return $f(\"hello\") → \"HELLO\"\r\n * let $add := function($a, $b) { $a + $b } return $add(2, 3) → 5\r\n * $callback($x, $y)\r\n *\r\n * Used when:\r\n * - Invoking a function stored in a variable\r\n * - Using arrow operator with variable function references\r\n * - Higher-order function callbacks\r\n */\r\nexport class XPathDynamicFunctionCall extends XPathExpression {\r\n /** Expression that evaluates to a function item */\r\n functionExpr: XPathExpression;\r\n /** Arguments to pass to the function */\r\n args: XPathExpression[];\r\n\r\n constructor(functionExpr: XPathExpression, args: XPathExpression[]) {\r\n super();\r\n this.functionExpr = functionExpr;\r\n this.args = args;\r\n }\r\n\r\n evaluate(context: XPathContext): XPathResult {\r\n // Evaluate the function expression to get a function item\r\n const funcValue = this.functionExpr.evaluate(context) as any;\r\n\r\n // XPath 3.1: Maps are single-argument functions (key lookup)\r\n if (isXPathMap(funcValue)) {\r\n if (this.args.length !== 1) {\r\n throw new Error(`Map lookup expects 1 argument but got ${this.args.length}`);\r\n }\r\n const key = String(this.args[0].evaluate(context));\r\n const value = funcValue[key];\r\n if (value === undefined) {\r\n throw new Error(`XPDY0002: Key \"${key}\" not found in map`);\r\n }\r\n return value;\r\n }\r\n\r\n // XPath 3.1: Arrays are single-argument functions (position lookup)\r\n if (isXPathArray(funcValue)) {\r\n if (this.args.length !== 1) {\r\n throw new Error(`Array lookup expects 1 argument but got ${this.args.length}`);\r\n }\r\n const position = Number(this.args[0].evaluate(context));\r\n return getArrayMember(funcValue, position);\r\n }\r\n\r\n // Check if it's a function item\r\n if (isFunctionItem(funcValue)) {\r\n const funcItem = funcValue as XPathFunctionItem;\r\n\r\n // Check arity\r\n if (funcItem.arity !== this.args.length) {\r\n throw new Error(\r\n `Function expects ${funcItem.arity} arguments but got ${this.args.length}`\r\n );\r\n }\r\n\r\n // Evaluate arguments\r\n const evaluatedArgs = this.args.map((arg) => arg.evaluate(context));\r\n\r\n // Invoke the function\r\n return funcItem.implementation(...evaluatedArgs);\r\n }\r\n\r\n // Also check if it's a native JavaScript function (for compatibility)\r\n if (typeof funcValue === 'function') {\r\n // Evaluate arguments\r\n const evaluatedArgs = this.args.map((arg) => arg.evaluate(context));\r\n return funcValue(...evaluatedArgs);\r\n }\r\n\r\n throw new Error('Dynamic function call: expression does not evaluate to a function item');\r\n }\r\n\r\n toString(): string {\r\n const argsStr = this.args.map((a) => a.toString()).join(', ');\r\n return `${this.functionExpr}(${argsStr})`;\r\n }\r\n}\r\n","/**\r\n * Try-Catch Expression - XSLT 3.0 Error Handling\r\n *\r\n * Implements the try-catch expression for handling errors in XPath/XSLT.\r\n * Syntax: try { expression } catch (err) { handler }\r\n *\r\n * The try-catch expression evaluates an expression and catches any dynamic errors,\r\n * allowing graceful error recovery or alternative processing.\r\n *\r\n * Note: Currently a simplified implementation that provides the expression structure.\r\n * Full async evaluation would require updating the XPathExpression base class.\r\n */\r\n\r\nimport { XPathExpression } from './expression';\r\nimport { XPathContext } from '../context';\r\n\r\n/**\r\n * Error information captured by catch block\r\n */\r\nexport interface CaughtError {\r\n /**\r\n * Error code as string (e.g., 'XPTY0004')\r\n */\r\n code: string;\r\n\r\n /**\r\n * Human-readable error description\r\n */\r\n description: string;\r\n\r\n /**\r\n * Error value (the original error object if available)\r\n */\r\n value?: any;\r\n\r\n /**\r\n * Stack trace if available\r\n */\r\n stack?: string;\r\n\r\n /**\r\n * Error type: 'static', 'dynamic', or 'type'\r\n */\r\n type: 'static' | 'dynamic' | 'type';\r\n}\r\n\r\n/**\r\n * Try-Catch Expression Implementation\r\n *\r\n * Evaluates a try expression and falls back to a catch expression on error.\r\n * The catch expression has access to the error information via error variables.\r\n */\r\nexport class TryExpression extends XPathExpression {\r\n /**\r\n * The expression to try\r\n */\r\n private tryExpr: XPathExpression;\r\n\r\n /**\r\n * Optional catch expression (evaluated if try fails)\r\n */\r\n private catchExpr: XPathExpression | null;\r\n\r\n /**\r\n * Optional error variable pattern to capture error info\r\n * Can match specific error codes or catch all\r\n */\r\n private errorPattern: string | null;\r\n\r\n /**\r\n * Variable name to bind error information\r\n */\r\n private errorVariableName: string | null;\r\n\r\n constructor(\r\n tryExpression: XPathExpression,\r\n catchExpression?: XPathExpression,\r\n errorPattern?: string,\r\n errorVariableName?: string\r\n ) {\r\n super();\r\n this.tryExpr = tryExpression;\r\n this.catchExpr = catchExpression || null;\r\n this.errorPattern = errorPattern || null;\r\n this.errorVariableName = errorVariableName || null;\r\n }\r\n\r\n /**\r\n * Evaluate the try-catch expression\r\n *\r\n * Note: This is a synchronous implementation for compatibility.\r\n * For full async support, the base XPathExpression class would need updating.\r\n */\r\n evaluate(context: XPathContext): any {\r\n try {\r\n // Attempt to evaluate the try expression\r\n const result = this.tryExpr.evaluate(context);\r\n\r\n // Handle promises if returned\r\n if (result && typeof result === 'object' && typeof (result as any).catch === 'function') {\r\n return (result as any).catch((error: any) => this.handleError(error, context));\r\n }\r\n\r\n return result;\r\n } catch (error) {\r\n // If catch expression not provided, suppress error and return empty sequence\r\n if (!this.catchExpr) {\r\n return undefined;\r\n }\r\n\r\n return this.handleError(error, context);\r\n }\r\n }\r\n\r\n /**\r\n * Handle caught error and evaluate catch expression\r\n */\r\n private handleError(error: any, context: XPathContext): any {\r\n // Create caught error information\r\n const caughtError = this.createCaughtError(error);\r\n\r\n // Check if error matches pattern\r\n if (this.errorPattern && !this.matchesErrorPattern(caughtError, this.errorPattern)) {\r\n // Error doesn't match pattern, re-throw\r\n throw error;\r\n }\r\n\r\n // Create new context with error information\r\n const catchContext: any = {\r\n node: (context as any).node,\r\n position: (context as any).position,\r\n size: (context as any).size,\r\n variables: (context as any).variables ? new Map((context as any).variables) : new Map(),\r\n functions: (context as any).functions || {},\r\n };\r\n\r\n // Bind error information to context if variable name specified\r\n if (this.errorVariableName) {\r\n catchContext.variables.set(this.errorVariableName, caughtError);\r\n }\r\n\r\n // Also provide error components as individual variables\r\n catchContext.variables.set('err:code', caughtError.code);\r\n catchContext.variables.set('err:description', caughtError.description);\r\n catchContext.variables.set('err:value', caughtError.value);\r\n\r\n // Evaluate catch expression\r\n return this.catchExpr!.evaluate(catchContext);\r\n }\r\n\r\n /**\r\n * Create caught error information from thrown error\r\n */\r\n private createCaughtError(error: any): CaughtError {\r\n let code = 'UNKNOWN';\r\n let description = 'Unknown error';\r\n let type: 'static' | 'dynamic' | 'type' = 'dynamic';\r\n\r\n if (typeof error === 'string') {\r\n description = error;\r\n } else if (error && typeof error === 'object') {\r\n if (error.message) {\r\n description = error.message;\r\n }\r\n if (error.code) {\r\n code = error.code;\r\n }\r\n if (error.type) {\r\n type = error.type;\r\n }\r\n }\r\n\r\n return {\r\n code,\r\n description,\r\n value: error,\r\n stack: error?.stack,\r\n type,\r\n };\r\n }\r\n\r\n /**\r\n * Check if caught error matches error pattern\r\n */\r\n private matchesErrorPattern(caughtError: CaughtError, pattern: string): boolean {\r\n // Pattern can be:\r\n // - \"*\" matches all errors\r\n // - \"XPTY0004\" matches specific error code\r\n // - \"err:*\" matches all err: namespace errors\r\n\r\n if (pattern === '*') {\r\n return true;\r\n }\r\n\r\n // Exact match\r\n return caughtError.code === pattern || caughtError.code.includes(pattern);\r\n }\r\n\r\n /**\r\n * Get string representation\r\n */\r\n override toString(): string {\r\n let result = `try { ${this.tryExpr.toString()} }`;\r\n if (this.catchExpr) {\r\n result += ` catch`;\r\n if (this.errorPattern) {\r\n result += ` (${this.errorPattern})`;\r\n }\r\n result += ` { ${this.catchExpr.toString()} }`;\r\n }\r\n return result;\r\n }\r\n}\r\n\r\n/**\r\n * Create a try-catch expression\r\n *\r\n * Usage:\r\n * createTryExpression(tryExpr, catchExpr, \"err:*\", \"error\")\r\n */\r\nexport function createTryExpression(\r\n tryExpression: XPathExpression,\r\n catchExpression?: XPathExpression,\r\n errorPattern?: string,\r\n errorVariableName?: string\r\n): TryExpression {\r\n return new TryExpression(tryExpression, catchExpression, errorPattern, errorVariableName);\r\n}\r\n\r\n/**\r\n * Helper to create simple try-catch (return empty on error)\r\n */\r\nexport function createTryOnly(tryExpression: XPathExpression): TryExpression {\r\n return new TryExpression(tryExpression, null);\r\n}\r\n\r\n/**\r\n * Helper to create try-catch with fallback value\r\n */\r\nexport function createTryWithFallback(\r\n tryExpression: XPathExpression,\r\n fallbackValue: any\r\n): TryExpression {\r\n // Create literal expression for fallback\r\n const fallbackExpr = new (class extends XPathExpression {\r\n evaluate(): any {\r\n return fallbackValue;\r\n }\r\n toString(): string {\r\n return JSON.stringify(fallbackValue);\r\n }\r\n })();\r\n\r\n return new TryExpression(tryExpression, fallbackExpr);\r\n}\r\n\r\n/**\r\n * Common XSLT 3.0 Error Codes\r\n */\r\nexport const XSLT3ErrorCodes = {\r\n /**\r\n * Type error\r\n */\r\n XPTY0004: 'XPTY0004',\r\n\r\n /**\r\n * Division by zero\r\n */\r\n FOAR0001: 'FOAR0001',\r\n\r\n /**\r\n * Invalid argument\r\n */\r\n FORG0001: 'FORG0001',\r\n\r\n /**\r\n * Invalid QName\r\n */\r\n FONS0004: 'FONS0004',\r\n\r\n /**\r\n * Sequence is empty\r\n */\r\n FORG0004: 'FORG0004',\r\n\r\n /**\r\n * Sequence has more than one item\r\n */\r\n FORG0005: 'FORG0005',\r\n\r\n /**\r\n * Variable not defined\r\n */\r\n XPST0008: 'XPST0008',\r\n\r\n /**\r\n * Context item is not a node\r\n */\r\n XPTY0019: 'XPTY0019',\r\n\r\n /**\r\n * Invalid format-string\r\n */\r\n FODF1310: 'FODF1310',\r\n\r\n /**\r\n * Schema not available\r\n */\r\n XPST0051: 'XPST0051',\r\n};\r\n\r\n/**\r\n * Helper to safely evaluate expression without error propagation\r\n *\r\n * Returns empty sequence if any error occurs\r\n */\r\nexport function safeEvaluate(expr: XPathExpression, context: XPathContext): any {\r\n const tryExpr = createTryOnly(expr);\r\n return tryExpr.evaluate(context);\r\n}\r\n","/**\r\n * Lookup Expression (? operator) - XPath 3.1\r\n *\r\n * Implements the lookup operator (?) for accessing map and array members:\r\n * - Unary lookup: ?key (when context item is map/array)\r\n * - Postfix lookup: $expr?key, $expr?1, $expr?(expr), $expr?*\r\n *\r\n * Key features:\r\n * - Maps: ?key accesses by string key\r\n * - Arrays: ?1, ?2, ... accesses by 1-based index\r\n * - Wildcard: ?* returns all members/keys\r\n * - Dynamic: ?(expr) evaluates expression for key\r\n * - Chaining: $map?data?items?* flattens nested structures\r\n *\r\n * Reference: https://www.w3.org/TR/xpath-31/#id-lookup\r\n */\r\n\r\nimport { XPathExpression } from './expression';\r\nimport { XPathContext } from '../context';\r\nimport { isXPathArray, XPathArray } from './array-constructor-expression';\r\nimport { isXPathMap, XPathMap } from './map-constructor-expression';\r\n\r\n/**\r\n * Key specifier types for lookup operations.\r\n */\r\nexport enum KeySpecifierType {\r\n NCNAME = 'NCNAME',\r\n INTEGER_LITERAL = 'INTEGER_LITERAL',\r\n PARENTHESIZED_EXPR = 'PARENTHESIZED_EXPR',\r\n WILDCARD = 'WILDCARD',\r\n}\r\n\r\n/**\r\n * Represents a key specifier in a lookup expression.\r\n */\r\nexport interface KeySpecifier {\r\n type: KeySpecifierType;\r\n value?: string | number | XPathExpression;\r\n}\r\n\r\n/**\r\n * Lookup expression: ?key, ?1, ?(expr), ?*\r\n */\r\nexport class XPathLookupExpression implements XPathExpression {\r\n constructor(\r\n private baseExpr: XPathExpression | null, // null for unary lookup\r\n private keySpecifier: KeySpecifier\r\n ) { }\r\n\r\n evaluate(context: XPathContext): any {\r\n // Determine the target (base expression result or context item)\r\n let target: any;\r\n if (this.baseExpr) {\r\n // Postfix lookup: evaluate base expression\r\n target = this.baseExpr.evaluate(context);\r\n } else {\r\n // Unary lookup: use context item\r\n target = (context as any).contextItem;\r\n if (target === undefined) {\r\n throw new Error('XPDY0002: Context item is undefined for unary lookup');\r\n }\r\n }\r\n\r\n // Apply lookup based on target type\r\n if (isXPathMap(target)) {\r\n return this.lookupInMap(target, this.keySpecifier, context);\r\n } else if (isXPathArray(target)) {\r\n return this.lookupInArray(target, this.keySpecifier, context);\r\n } else {\r\n throw new Error('XPTY0004: Lookup operator can only be applied to maps and arrays');\r\n }\r\n }\r\n\r\n private lookupInMap(map: XPathMap, keySpecifier: KeySpecifier, context: XPathContext): any {\r\n switch (keySpecifier.type) {\r\n case KeySpecifierType.NCNAME:\r\n const key = keySpecifier.value as string;\r\n return map[key];\r\n\r\n case KeySpecifierType.INTEGER_LITERAL:\r\n // For maps, integer keys are converted to strings\r\n const intKey = (keySpecifier.value as number).toString();\r\n return map[intKey];\r\n\r\n case KeySpecifierType.PARENTHESIZED_EXPR:\r\n // Evaluate the expression to get the key\r\n const expr = keySpecifier.value as XPathExpression;\r\n const dynamicKey = expr.evaluate(context);\r\n const stringKey = this.atomizeToString(dynamicKey);\r\n return map[stringKey];\r\n\r\n case KeySpecifierType.WILDCARD:\r\n // Return all values in the map, excluding internal properties\r\n return Object.keys(map)\r\n .filter((key) => !key.startsWith('__'))\r\n .map((key) => map[key]);\r\n\r\n default:\r\n throw new Error('FOAY0001: Invalid key specifier for map lookup');\r\n }\r\n }\r\n\r\n private lookupInArray(\r\n array: XPathArray,\r\n keySpecifier: KeySpecifier,\r\n context: XPathContext\r\n ): any {\r\n switch (keySpecifier.type) {\r\n case KeySpecifierType.INTEGER_LITERAL:\r\n const position = keySpecifier.value as number;\r\n if (position < 1) {\r\n throw new Error('FOAY0001: Array index must be positive');\r\n }\r\n if (position > array.members.length) {\r\n throw new Error('FOAY0001: Array index out of bounds');\r\n }\r\n return array.members[position - 1]; // 1-based indexing\r\n\r\n case KeySpecifierType.PARENTHESIZED_EXPR:\r\n // Evaluate expression to get position\r\n const expr = keySpecifier.value as XPathExpression;\r\n const dynamicPos = expr.evaluate(context);\r\n const positionNum = this.atomizeToNumber(dynamicPos);\r\n if (positionNum < 1) {\r\n throw new Error('FOAY0001: Array index must be positive');\r\n }\r\n if (positionNum > array.members.length) {\r\n throw new Error('FOAY0001: Array index out of bounds');\r\n }\r\n return array.members[positionNum - 1];\r\n\r\n case KeySpecifierType.WILDCARD:\r\n // Return all members (flattened if nested)\r\n return this.flattenArrayMembers(array.members);\r\n\r\n case KeySpecifierType.NCNAME:\r\n // NCName keys not valid for arrays\r\n throw new Error('XPTY0004: NCName key not valid for array lookup');\r\n\r\n default:\r\n throw new Error('FOAY0001: Invalid key specifier for array lookup');\r\n }\r\n }\r\n\r\n /**\r\n * Flatten array members, handling nested arrays.\r\n * For wildcard lookup, nested arrays are flattened.\r\n */\r\n private flattenArrayMembers(members: any[]): any[] {\r\n const result: any[] = [];\r\n for (const member of members) {\r\n if (isXPathArray(member)) {\r\n // Recursively flatten nested arrays\r\n result.push(...this.flattenArrayMembers(member.members));\r\n } else {\r\n result.push(member);\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Atomize a value to a string for use as a map key.\r\n * Per XPath 2.0 Section 2.4.2: Atomization\r\n * - Atomic values pass through unchanged\r\n * - Arrays/Maps: extract atomic values and convert to string\r\n * - Nodes: use string value\r\n * - Function items: should error (cannot atomize function items)\r\n */\r\n private atomizeToString(value: any): string {\r\n if (value === null || value === undefined) {\r\n return '';\r\n }\r\n\r\n if (typeof value === 'string') return value;\r\n if (typeof value === 'number') return value.toString();\r\n if (typeof value === 'boolean') return value.toString();\r\n\r\n // Handle XPath arrays (objects with $isXPathArray flag)\r\n if (Array.isArray(value)) {\r\n if (value.length === 0) return '';\r\n if (value.length === 1) return this.atomizeToString(value[0]);\r\n // Multiple values: use first\r\n return this.atomizeToString(value[0]);\r\n }\r\n\r\n // Handle XPath maps (objects with $isXPathMap flag)\r\n if (typeof value === 'object' && value.$isXPathMap) {\r\n // Maps cannot be directly atomized - should error\r\n throw new Error('XPTY0004: Cannot atomize a map to string');\r\n }\r\n\r\n // Handle node-like objects (have nodeType, nodeName, or textContent)\r\n if (typeof value === 'object' && (value.nodeType || value.nodeName || value.textContent)) {\r\n return (value.textContent || value.value || '').toString();\r\n }\r\n\r\n // Function items or other non-atomizable types\r\n if (typeof value === 'function') {\r\n throw new Error('XPTY0004: Cannot atomize a function item');\r\n }\r\n\r\n // Default: convert to string\r\n try {\r\n return String(value);\r\n } catch {\r\n throw new Error('XPTY0004: Cannot atomize value');\r\n }\r\n }\r\n\r\n /**\r\n * Atomize a value to a number for use as an array index.\r\n * Per XPath 2.0 Section 2.4.2: Atomization\r\n * - Numbers pass through unchanged\r\n * - Strings: convert to number\r\n * - Booleans: error\r\n * - Arrays/Maps/Function items: error\r\n */\r\n private atomizeToNumber(value: any): number {\r\n if (value === null || value === undefined) {\r\n throw new Error('XPTY0004: Cannot convert empty sequence to number');\r\n }\r\n\r\n if (typeof value === 'number') return value;\r\n\r\n if (typeof value === 'string') {\r\n const num = parseFloat(value);\r\n if (isNaN(num)) throw new Error('FORG0001: Invalid number');\r\n return num;\r\n }\r\n\r\n if (typeof value === 'boolean') {\r\n throw new Error('XPTY0004: Cannot convert boolean to number for array index');\r\n }\r\n\r\n // Handle XPath arrays\r\n if (Array.isArray(value)) {\r\n if (value.length === 0) {\r\n throw new Error('XPTY0004: Cannot convert empty sequence to number');\r\n }\r\n if (value.length === 1) {\r\n return this.atomizeToNumber(value[0]);\r\n }\r\n throw new Error('XPTY0004: Cannot convert sequence to single number');\r\n }\r\n\r\n // Handle XPath maps\r\n if (typeof value === 'object' && value.$isXPathMap) {\r\n throw new Error('XPTY0004: Cannot atomize a map to number');\r\n }\r\n\r\n // Handle node-like objects\r\n if (typeof value === 'object' && (value.nodeType || value.nodeName || value.textContent)) {\r\n const str = (value.textContent || value.value || '').toString();\r\n const num = parseFloat(str);\r\n if (isNaN(num)) throw new Error('FORG0001: Invalid number from node');\r\n return num;\r\n }\r\n\r\n // Function items\r\n if (typeof value === 'function') {\r\n throw new Error('XPTY0004: Cannot atomize a function item');\r\n }\r\n\r\n throw new Error('FORG0001: Cannot convert to number');\r\n }\r\n\r\n toString(): string {\r\n const base = this.baseExpr ? this.baseExpr.toString() : '';\r\n let keyStr: string;\r\n switch (this.keySpecifier.type) {\r\n case KeySpecifierType.NCNAME:\r\n keyStr = this.keySpecifier.value as string;\r\n break;\r\n case KeySpecifierType.INTEGER_LITERAL:\r\n keyStr = (this.keySpecifier.value as number).toString();\r\n break;\r\n case KeySpecifierType.PARENTHESIZED_EXPR:\r\n keyStr = `(${this.keySpecifier.value})`;\r\n break;\r\n case KeySpecifierType.WILDCARD:\r\n keyStr = '*';\r\n break;\r\n default:\r\n keyStr = '?';\r\n }\r\n return base + '?' + keyStr;\r\n }\r\n}\r\n","export * from './expression';\r\n\r\n// Literal expressions\r\nexport * from './literal-expression';\r\nexport * from './variable-reference-expression';\r\n\r\n// Path expressions\r\nexport * from './step-expression';\r\nexport * from './location-path-expression';\r\nexport * from './filter-expression';\r\n\r\n// Operator expressions\r\nexport * from './unary-expression';\r\nexport * from './binary-expression';\r\nexport * from './arithmetic-expression';\r\nexport * from './logical-expression';\r\nexport * from './conditional-expression';\r\nexport * from './for-expression';\r\nexport * from './quantified-expression';\r\nexport * from './instance-of-expression';\r\nexport * from './castable-expression';\r\nexport * from './treat-expression';\r\n\r\n// Sequence expressions\r\nexport * from './union-expression';\r\nexport * from './sequence-construction';\r\n\r\n// Predicates\r\nexport * from './predicate-expression';\r\n\r\n// Comparison expressions (Phase 2.3)\r\nexport * from './value-comparison';\r\nexport * from './general-comparison';\r\nexport * from './node-comparison';\r\n\r\n// Other expressions\r\nexport * from './function-call-expression';\r\n\r\n// JSON/XML conversion\r\nexport * from './json-to-xml-converter';\r\n\r\n// XPath 3.0 expressions\r\nexport * from './let-expression';\r\nexport * from './simple-map-expression';\r\nexport * from './string-concat-expression';\r\nexport * from './string-template-expression';\r\nexport * from './arrow-expression';\r\nexport * from './named-function-ref-expression';\r\nexport * from './inline-function-expression';\r\nexport * from './dynamic-function-call-expression';\r\n\r\n// XSLT 3.0 expressions\r\nexport * from './try-expression';\r\n\r\n// XPath 3.1 expressions\r\nexport * from './map-constructor-expression';\r\nexport * from './array-constructor-expression';\r\nexport * from './lookup-expression';\r\n","export { XPath, ExprContext } from './xpath';\r\nexport { Xslt, XsltOptions } from './xslt';\r\nexport { XmlParser, xmlEscapeText, XDocument, XNode, domDocumentToXDocument } from './dom';\r\n","import { TokenType as XPathTokenType } from './token-type';\r\n\r\nexport class XPathToken {\r\n type: XPathTokenType;\r\n lexeme: string;\r\n\r\n constructor(type: XPathTokenType, lexeme: string) {\r\n this.type = type;\r\n this.lexeme = lexeme;\r\n }\r\n}\r\n","import { XPathToken } from './token';\r\nimport { TokenType } from './token-type';\r\n\r\ntype XPathVersion = '1.0' | '2.0' | '3.0' | '3.1';\r\n\r\n/**\r\n * Configuration options for the XPath lexer.\r\n */\r\nexport interface XPathLexerOptions {\r\n /**\r\n * XPath specification version to use for tokenization.\r\n *\r\n * - '1.0': XPath 1.0 keywords only (and, or, div, mod, axes, node types, core functions)\r\n * - '2.0': Adds XPath 2.0 reserved words (if, then, else, for, return, some, every, etc.)\r\n * - '3.0'/'3.1': Same as 2.0 (reserved words are forward-compatible)\r\n *\r\n * Default: '1.0'\r\n *\r\n * @example\r\n * ```typescript\r\n * // XPath 1.0 lexer (treats 'if', 'then', 'else' as identifiers)\r\n * const lexer10 = new XPathLexer({ version: '1.0' });\r\n *\r\n * // XPath 2.0 lexer (treats 'if', 'then', 'else' as reserved words)\r\n * const lexer20 = new XPathLexer({ version: '2.0' });\r\n * ```\r\n */\r\n version?: XPathVersion;\r\n}\r\n\r\n/**\r\n * Default XPath version for the lexer.\r\n * Set to '1.0' for backward compatibility.\r\n */\r\nconst DEFAULT_LEXER_VERSION: XPathVersion = '1.0';\r\n\r\ntype ReservedWordMap = Record<string, { type: TokenType; value: string }>;\r\n\r\nconst COMMON_RESERVED_WORDS: ReservedWordMap = {\r\n // Location axes (XPath 1.0 complete list)\r\n ancestor: { type: 'LOCATION', value: 'ancestor' },\r\n 'ancestor-or-self': { type: 'LOCATION', value: 'ancestor-or-self' },\r\n attribute: { type: 'LOCATION', value: 'attribute' },\r\n child: { type: 'LOCATION', value: 'child' },\r\n descendant: { type: 'LOCATION', value: 'descendant' },\r\n 'descendant-or-self': { type: 'LOCATION', value: 'descendant-or-self' },\r\n following: { type: 'LOCATION', value: 'following' },\r\n 'following-sibling': { type: 'LOCATION', value: 'following-sibling' },\r\n namespace: { type: 'LOCATION', value: 'namespace' },\r\n parent: { type: 'LOCATION', value: 'parent' },\r\n preceding: { type: 'LOCATION', value: 'preceding' },\r\n 'preceding-sibling': { type: 'LOCATION', value: 'preceding-sibling' },\r\n self: { type: 'LOCATION', value: 'self' },\r\n\r\n // Node type tests\r\n node: { type: 'NODE_TYPE', value: 'node' },\r\n text: { type: 'NODE_TYPE', value: 'text' },\r\n comment: { type: 'NODE_TYPE', value: 'comment' },\r\n 'processing-instruction': { type: 'NODE_TYPE', value: 'processing-instruction' },\r\n\r\n // Operators\r\n and: { type: 'OPERATOR', value: 'and' },\r\n or: { type: 'OPERATOR', value: 'or' },\r\n div: { type: 'OPERATOR', value: 'div' },\r\n mod: { type: 'OPERATOR', value: 'mod' },\r\n\r\n // Node set functions (XPath 1.0, also valid in later versions)\r\n last: { type: 'FUNCTION', value: 'last' },\r\n position: { type: 'FUNCTION', value: 'position' },\r\n count: { type: 'FUNCTION', value: 'count' },\r\n id: { type: 'FUNCTION', value: 'id' },\r\n 'local-name': { type: 'FUNCTION', value: 'local-name' },\r\n 'namespace-uri': { type: 'FUNCTION', value: 'namespace-uri' },\r\n name: { type: 'FUNCTION', value: 'name' },\r\n\r\n // String functions\r\n string: { type: 'FUNCTION', value: 'string' },\r\n concat: { type: 'FUNCTION', value: 'concat' },\r\n 'starts-with': { type: 'FUNCTION', value: 'starts-with' },\r\n contains: { type: 'FUNCTION', value: 'contains' },\r\n 'substring-before': { type: 'FUNCTION', value: 'substring-before' },\r\n 'substring-after': { type: 'FUNCTION', value: 'substring-after' },\r\n substring: { type: 'FUNCTION', value: 'substring' },\r\n 'string-length': { type: 'FUNCTION', value: 'string-length' },\r\n 'normalize-space': { type: 'FUNCTION', value: 'normalize-space' },\r\n translate: { type: 'FUNCTION', value: 'translate' },\r\n\r\n // Boolean functions\r\n boolean: { type: 'FUNCTION', value: 'boolean' },\r\n not: { type: 'FUNCTION', value: 'not' },\r\n true: { type: 'FUNCTION', value: 'true' },\r\n false: { type: 'FUNCTION', value: 'false' },\r\n lang: { type: 'FUNCTION', value: 'lang' },\r\n\r\n // Number functions\r\n number: { type: 'FUNCTION', value: 'number' },\r\n sum: { type: 'FUNCTION', value: 'sum' },\r\n floor: { type: 'FUNCTION', value: 'floor' },\r\n ceiling: { type: 'FUNCTION', value: 'ceiling' },\r\n round: { type: 'FUNCTION', value: 'round' },\r\n};\r\n\r\nconst XPATH20_RESERVED_WORDS: ReservedWordMap = {\r\n // Conditional expression keywords (XPath 2.0)\r\n if: { type: 'RESERVED_WORD', value: 'if' },\r\n then: { type: 'RESERVED_WORD', value: 'then' },\r\n else: { type: 'RESERVED_WORD', value: 'else' },\r\n\r\n // FLWOR expressions (XPath 2.0)\r\n for: { type: 'RESERVED_WORD', value: 'for' },\r\n in: { type: 'RESERVED_WORD', value: 'in' },\r\n return: { type: 'RESERVED_WORD', value: 'return' },\r\n\r\n // Quantified expressions (XPath 2.0)\r\n some: { type: 'RESERVED_WORD', value: 'some' },\r\n every: { type: 'RESERVED_WORD', value: 'every' },\r\n satisfies: { type: 'RESERVED_WORD', value: 'satisfies' },\r\n\r\n // SequenceType operations (XPath 2.0)\r\n instance: { type: 'RESERVED_WORD', value: 'instance' },\r\n of: { type: 'RESERVED_WORD', value: 'of' },\r\n\r\n // Cast expressions (XPath 2.0)\r\n cast: { type: 'RESERVED_WORD', value: 'cast' },\r\n as: { type: 'RESERVED_WORD', value: 'as' },\r\n castable: { type: 'RESERVED_WORD', value: 'castable' },\r\n treat: { type: 'RESERVED_WORD', value: 'treat' },\r\n\r\n // Range expression (XPath 2.0)\r\n to: { type: 'RESERVED_WORD', value: 'to' },\r\n};\r\n\r\nconst XPATH30_RESERVED_WORDS: ReservedWordMap = {\r\n // Let expression (XPath 3.0)\r\n let: { type: 'RESERVED_WORD', value: 'let' },\r\n\r\n // Function keyword for inline functions (XPath 3.0)\r\n function: { type: 'RESERVED_WORD', value: 'function' },\r\n};\r\n\r\nconst XPATH31_RESERVED_WORDS: ReservedWordMap = {\r\n // Map constructor keyword (XPath 3.1)\r\n map: { type: 'RESERVED_WORD', value: 'map' },\r\n\r\n // Array constructor keyword (XPath 3.1)\r\n array: { type: 'RESERVED_WORD', value: 'array' },\r\n};\r\n\r\nfunction buildReservedWords(version: XPathVersion): ReservedWordMap {\r\n const merged: ReservedWordMap = { ...COMMON_RESERVED_WORDS };\r\n\r\n if (version !== '1.0') {\r\n Object.assign(merged, XPATH20_RESERVED_WORDS);\r\n }\r\n\r\n if (version === '3.0' || version === '3.1') {\r\n Object.assign(merged, XPATH30_RESERVED_WORDS);\r\n }\r\n\r\n if (version === '3.1') {\r\n Object.assign(merged, XPATH31_RESERVED_WORDS);\r\n }\r\n\r\n return merged;\r\n}\r\n\r\n/**\r\n * Lexer (tokenizer) for XPath expressions.\r\n *\r\n * Converts XPath expression strings into a sequence of tokens that can be\r\n * parsed by XPath10Parser or XPath20Parser.\r\n *\r\n * @example\r\n * ```typescript\r\n * // Create lexer with default options (XPath 1.0)\r\n * const lexer = new XPathLexer();\r\n *\r\n * // Create lexer with explicit version\r\n * const lexer10 = new XPathLexer('1.0');\r\n * const lexer20 = new XPathLexer('2.0');\r\n *\r\n * // Create lexer with options object\r\n * const lexer = new XPathLexer({ version: '2.0' });\r\n *\r\n * // Tokenize an expression\r\n * const tokens = lexer.scan('//book[@price > 10]');\r\n * ```\r\n */\r\nexport class XPathLexer {\r\n expression: string;\r\n current: number;\r\n tokens: XPathToken[];\r\n private additionalFunctions?: Set<string>;\r\n private readonly reservedWords: ReservedWordMap;\r\n private readonly version: XPathVersion;\r\n\r\n /**\r\n * Create a new XPath lexer.\r\n *\r\n * @param versionOrOptions - Either an XPath version string ('1.0', '2.0', '3.0', '3.1')\r\n * or an options object with a version property.\r\n * Defaults to '1.0' for backward compatibility.\r\n *\r\n * @example\r\n * ```typescript\r\n * // All of these create an XPath 1.0 lexer:\r\n * const lexer1 = new XPathLexer();\r\n * const lexer2 = new XPathLexer('1.0');\r\n * const lexer3 = new XPathLexer({ version: '1.0' });\r\n *\r\n * // Create an XPath 2.0 lexer:\r\n * const lexer4 = new XPathLexer('2.0');\r\n * const lexer5 = new XPathLexer({ version: '2.0' });\r\n * ```\r\n */\r\n constructor(versionOrOptions?: XPathVersion | XPathLexerOptions) {\r\n if (typeof versionOrOptions === 'object') {\r\n this.version = versionOrOptions.version ?? DEFAULT_LEXER_VERSION;\r\n } else {\r\n this.version = versionOrOptions ?? DEFAULT_LEXER_VERSION;\r\n }\r\n this.reservedWords = buildReservedWords(this.version);\r\n }\r\n\r\n /**\r\n * Get the XPath version this lexer is configured for.\r\n */\r\n getVersion(): XPathVersion {\r\n return this.version;\r\n }\r\n\r\n /**\r\n * Register additional function names to be recognized by the lexer.\r\n * Used for XSLT extension functions.\r\n */\r\n registerFunctions(functionNames: string[]): void {\r\n if (!this.additionalFunctions) {\r\n this.additionalFunctions = new Set();\r\n }\r\n for (const name of functionNames) {\r\n this.additionalFunctions.add(name);\r\n }\r\n }\r\n\r\n /**\r\n * Check if character is a valid start of an identifier.\r\n * Supports Unicode letters according to XML NCName specification.\r\n */\r\n isAlpha(char: string): boolean {\r\n // Allow ASCII letters, underscore, and Unicode letters\r\n // Using Unicode property escapes for broader Unicode support\r\n return /^[a-zA-Z_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD]$/.test(\r\n char\r\n );\r\n }\r\n\r\n /**\r\n * Check if character is valid in an identifier (after the first character).\r\n * Supports Unicode letters and digits according to XML NCName specification.\r\n * Note: Hyphen is handled separately in parseIdentifier for reserved words.\r\n */\r\n isAlphaNumeric(char: string): boolean {\r\n // Allow ASCII alphanumerics, underscore, and Unicode letters/digits/combining chars\r\n return /^[a-zA-Z0-9_\\u00B7\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0300-\\u036F\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u203F-\\u2040\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD]$/.test(\r\n char\r\n );\r\n }\r\n\r\n isNumber(char: string): boolean {\r\n return /^[0-9]$/.test(char);\r\n }\r\n\r\n isWhitespace(char: string): boolean {\r\n return /^[\\s\\t\\n\\r]$/.test(char);\r\n }\r\n\r\n peek(): string | undefined {\r\n return this.expression[this.current];\r\n }\r\n\r\n peekNext(): string | undefined {\r\n return this.expression[this.current + 1];\r\n }\r\n\r\n next(): string {\r\n return this.expression[this.current++];\r\n }\r\n\r\n match(expected: string): boolean {\r\n if (this.current >= this.expression.length) return false;\r\n if (this.expression[this.current] !== expected) return false;\r\n this.current++;\r\n return true;\r\n }\r\n\r\n parseIdentifier(firstCharacter: string): XPathToken {\r\n let characters = firstCharacter;\r\n\r\n // Parse alphanumeric characters, allowing hyphens for element names\r\n // XML NCName allows hyphens (but not at the start)\r\n while (this.current < this.expression.length) {\r\n const char = this.expression[this.current];\r\n\r\n if (this.isAlphaNumeric(char)) {\r\n characters += this.next();\r\n } else if (char === '-') {\r\n // Look ahead to check if this is a hyphenated identifier or subtraction\r\n const nextChar = this.expression[this.current + 1];\r\n\r\n // If hyphen is immediately followed by an alphanumeric character,\r\n // it's likely part of the identifier (e.g., \"my-element\", \"ancestor-or-self\")\r\n if (nextChar && this.isAlphaNumeric(nextChar)) {\r\n this.current++; // consume the hyphen\r\n characters += '-';\r\n // Continue parsing the rest of the identifier\r\n while (\r\n this.current < this.expression.length &&\r\n this.isAlphaNumeric(this.expression[this.current])\r\n ) {\r\n characters += this.next();\r\n }\r\n } else {\r\n // Hyphen followed by space or operator - it's subtraction\r\n break;\r\n }\r\n } else {\r\n break;\r\n }\r\n }\r\n\r\n const likelyReservedWord = this.reservedWords[characters.toLowerCase()];\r\n if (likelyReservedWord) {\r\n return new XPathToken(likelyReservedWord.type, characters);\r\n }\r\n\r\n // Check if this is an extension function\r\n if (this.additionalFunctions && this.additionalFunctions.has(characters)) {\r\n return new XPathToken('FUNCTION', characters);\r\n }\r\n\r\n if (characters.length > 0) {\r\n return new XPathToken('IDENTIFIER', characters);\r\n }\r\n\r\n throw new Error(`Invalid identifier: ${characters}`);\r\n }\r\n\r\n parseString(quoteChar: string): XPathToken {\r\n let value = '';\r\n\r\n while (\r\n this.current < this.expression.length &&\r\n this.expression[this.current] !== quoteChar\r\n ) {\r\n value += this.next();\r\n }\r\n\r\n if (this.current >= this.expression.length) {\r\n throw new Error(`Unterminated string literal`);\r\n }\r\n\r\n this.next(); // consume closing quote\r\n return new XPathToken('STRING', value);\r\n }\r\n\r\n /**\r\n * Parse string template: `Hello {$name}!`\r\n * Returns the entire template as-is for the parser to handle interpolation.\r\n */\r\n parseStringTemplate(): XPathToken {\r\n let value = '';\r\n let depth = 0;\r\n\r\n while (this.current < this.expression.length) {\r\n const char = this.expression[this.current];\r\n\r\n // Handle escape sequences\r\n if (char === '\\\\' && this.current + 1 < this.expression.length) {\r\n const nextChar = this.expression[this.current + 1];\r\n // Check for valid escapes: \\`, \\{, \\}, \\n, \\r, \\t, \\\\\r\n if (\r\n nextChar === '`' ||\r\n nextChar === '{' ||\r\n nextChar === '}' ||\r\n nextChar === 'n' ||\r\n nextChar === 'r' ||\r\n nextChar === 't' ||\r\n nextChar === '\\\\'\r\n ) {\r\n value += char;\r\n this.next();\r\n value += this.next();\r\n continue;\r\n }\r\n }\r\n\r\n // End of template\r\n if (char === '`' && depth === 0) {\r\n this.next(); // consume closing backtick\r\n return new XPathToken('STRING_TEMPLATE', value);\r\n }\r\n\r\n // Track nested braces\r\n if (char === '{') {\r\n depth++;\r\n } else if (char === '}') {\r\n depth--;\r\n }\r\n\r\n value += this.next();\r\n }\r\n\r\n throw new Error('Unterminated string template');\r\n }\r\n\r\n parseNumber(firstCharacter: string): XPathToken {\r\n let characters = firstCharacter;\r\n\r\n while (\r\n this.current < this.expression.length &&\r\n this.isNumber(this.expression[this.current]) &&\r\n this.expression[this.current] !== '.'\r\n ) {\r\n characters += this.next();\r\n }\r\n\r\n // Allow for a decimal point in the number\r\n if (this.current < this.expression.length && this.expression[this.current] === '.') {\r\n characters += this.next();\r\n while (\r\n this.current < this.expression.length &&\r\n this.isNumber(this.expression[this.current])\r\n ) {\r\n characters += this.next();\r\n }\r\n }\r\n\r\n if (characters.length > 0) {\r\n return new XPathToken('NUMBER', characters);\r\n }\r\n\r\n // If no valid number was found, return an error token\r\n throw new Error(`Invalid number: ${characters}`);\r\n }\r\n\r\n /**\r\n * Parse EQName (Expanded QName): Q{uri}local-name\r\n * XPath 3.0 syntax for directly specifying namespace URIs.\r\n * Example: Q{http://www.w3.org/2005/xpath-functions/math}pi\r\n */\r\n parseEQName(): XPathToken {\r\n // Q is already consumed, consume the opening brace\r\n this.next(); // consume '{'\r\n\r\n let uri = '';\r\n // Read until closing brace\r\n while (this.current < this.expression.length && this.expression[this.current] !== '}') {\r\n uri += this.next();\r\n }\r\n\r\n if (this.current >= this.expression.length) {\r\n throw new Error(`Unterminated EQName: missing '}' after URI`);\r\n }\r\n\r\n this.next(); // consume '}'\r\n\r\n // Now parse the local name\r\n let localName = '';\r\n if (this.current < this.expression.length && this.isAlpha(this.expression[this.current])) {\r\n while (this.current < this.expression.length) {\r\n const char = this.expression[this.current];\r\n if (this.isAlphaNumeric(char) || char === '-' || char === '_') {\r\n localName += this.next();\r\n } else {\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (localName.length === 0) {\r\n throw new Error(`EQName missing local name after '}': Q{${uri}}`);\r\n }\r\n\r\n // Store the full EQName as \"Q{uri}local\"\r\n const fullEQName = `Q{${uri}}${localName}`;\r\n return new XPathToken('EQNAME', fullEQName);\r\n }\r\n\r\n scanToken(): XPathToken | null {\r\n const char = this.next();\r\n\r\n // Skip whitespace\r\n if (this.isWhitespace(char)) {\r\n return null;\r\n }\r\n\r\n switch (char) {\r\n case '@':\r\n return new XPathToken('AT', char);\r\n case '$':\r\n return new XPathToken('DOLLAR', char);\r\n case '|':\r\n // XPath 3.0: || is string concatenation operator\r\n if (this.match('|')) {\r\n return new XPathToken('CONCAT', '||');\r\n }\r\n return new XPathToken('PIPE', char);\r\n\r\n case '#':\r\n // XPath 3.0: # is used for named function references (fn:name#arity)\r\n return new XPathToken('HASH', char);\r\n case '{':\r\n return new XPathToken('OPEN_CURLY_BRACKET', char);\r\n case '}':\r\n return new XPathToken('CLOSE_CURLY_BRACKET', char);\r\n case '[':\r\n return new XPathToken('OPEN_SQUARE_BRACKET', char);\r\n case ']':\r\n return new XPathToken('CLOSE_SQUARE_BRACKET', char);\r\n case '(':\r\n return new XPathToken('OPEN_PAREN', char);\r\n case ')':\r\n return new XPathToken('CLOSE_PAREN', char);\r\n case '+':\r\n return new XPathToken('PLUS', char);\r\n case '-':\r\n return new XPathToken('MINUS', char);\r\n case '*':\r\n return new XPathToken('ASTERISK', char);\r\n case ',':\r\n return new XPathToken('COMMA', char);\r\n case '?':\r\n return new XPathToken('QUESTION', char);\r\n\r\n case 'Q':\r\n // XPath 3.0: Q{uri}local is an EQName (expanded QName)\r\n if (this.peek() === '{') {\r\n return this.parseEQName();\r\n }\r\n // Otherwise treat as identifier\r\n return this.parseIdentifier(char);\r\n\r\n // Tokens that may be single or double character\r\n case '.':\r\n if (this.match('.')) {\r\n return new XPathToken('DOT_DOT', '..');\r\n }\r\n // Check if it's a number starting with decimal point\r\n if (this.peek() && this.isNumber(this.peek()!)) {\r\n return this.parseNumber(char);\r\n }\r\n return new XPathToken('DOT', char);\r\n\r\n case '/':\r\n if (this.match('/')) {\r\n return new XPathToken('DOUBLE_SLASH', '//');\r\n }\r\n return new XPathToken('SLASH', char);\r\n\r\n case ':':\r\n if (this.match(':')) {\r\n return new XPathToken('COLON_COLON', '::');\r\n }\r\n // XPath 3.0: := is variable assignment in let expressions\r\n if (this.match('=')) {\r\n return new XPathToken('ASSIGNMENT', ':=');\r\n }\r\n return new XPathToken('COLON', char);\r\n\r\n case '=':\r\n // XPath 3.0: => is the arrow operator\r\n if (this.match('>')) {\r\n return new XPathToken('FAT_ARROW', '=>');\r\n }\r\n return new XPathToken('EQUALS', char);\r\n\r\n case '!':\r\n if (this.match('=')) {\r\n return new XPathToken('NOT_EQUALS', '!=');\r\n }\r\n // XPath 3.0: ! is the simple map operator\r\n return new XPathToken('SIMPLE_MAP', char);\r\n\r\n case '<':\r\n if (this.match('=')) {\r\n return new XPathToken('LESS_THAN_OR_EQUAL', '<=');\r\n }\r\n return new XPathToken('LESS_THAN', char);\r\n\r\n case '>':\r\n if (this.match('=')) {\r\n return new XPathToken('GREATER_THAN_OR_EQUAL', '>=');\r\n }\r\n return new XPathToken('GREATER_THAN', char);\r\n\r\n // String literals\r\n case \"'\":\r\n return this.parseString(\"'\");\r\n\r\n case '\"':\r\n return this.parseString('\"');\r\n\r\n // String template (XPath 3.0+): `Hello {$name}!`\r\n case '`':\r\n return this.parseStringTemplate();\r\n\r\n default:\r\n if (this.isNumber(char)) {\r\n return this.parseNumber(char);\r\n }\r\n\r\n if (this.isAlpha(char)) {\r\n return this.parseIdentifier(char);\r\n }\r\n\r\n throw new Error(`Unexpected character: ${char}`);\r\n }\r\n }\r\n\r\n scan(expression: string): XPathToken[] {\r\n this.expression = expression;\r\n this.tokens = [];\r\n this.current = 0;\r\n\r\n while (this.current < this.expression.length) {\r\n const token = this.scanToken();\r\n if (token !== null) {\r\n this.tokens.push(token);\r\n }\r\n }\r\n\r\n return this.tokens;\r\n }\r\n}\r\n","import { XPathToken } from '../lexer/token';\r\nimport { TokenType } from '../lexer/token-type';\r\nimport {\r\n XPathExpression,\r\n XPathStringLiteral,\r\n XPathNumberLiteral,\r\n XPathVariableReference,\r\n XPathUnaryExpression,\r\n XPathArithmeticExpression,\r\n ArithmeticOperator,\r\n XPathBinaryExpression,\r\n XPathLogicalExpression,\r\n XPathFunctionCall,\r\n XPathStep,\r\n AxisType,\r\n NodeTest,\r\n XPathPredicate,\r\n XPathLocationPath,\r\n XPathFilterExpression,\r\n XPathUnionExpression,\r\n FilteredPathExpression,\r\n EmptySequenceExpression,\r\n} from '../expressions';\r\nimport { createStaticContext, XPathStaticContext } from '../static-context';\r\nimport { XSLTExtensions, XPathBaseParserOptions, validateExtensions } from '../xslt-extensions';\r\nimport { XPathVersion } from '../xpath-version';\r\nimport {\r\n grammarViolation,\r\n unsupportedAxis,\r\n unresolvedNameReference,\r\n functionSignatureMismatch,\r\n} from '../errors';\r\nimport { WarningCollector, createWarningCollector, createNoOpWarningCollector } from '../warnings';\r\n\r\n/**\r\n * Recursive descent parser shared by XPath 1.0+ implementations.\r\n *\r\n * Grammar (simplified):\r\n * Expr ::= OrExpr\r\n * OrExpr ::= AndExpr ('or' AndExpr)*\r\n * AndExpr ::= EqualityExpr ('and' EqualityExpr)*\r\n * EqualityExpr ::= RelationalExpr (('=' | '!=') RelationalExpr)*\r\n * RelationalExpr ::= AdditiveExpr (('<' | '>' | '<=' | '>=') AdditiveExpr)*\r\n * AdditiveExpr ::= MultiplicativeExpr (('+' | '-') MultiplicativeExpr)*\r\n * MultiplicativeExpr ::= UnaryExpr (('*' | 'div' | 'mod') UnaryExpr)*\r\n * UnaryExpr ::= '-'* UnionExpr\r\n * UnionExpr ::= PathExpr ('|' PathExpr)*\r\n * PathExpr ::= LocationPath | FilterExpr (('/' | '//') RelativeLocationPath)?\r\n * FilterExpr ::= PrimaryExpr Predicate*\r\n * PrimaryExpr ::= VariableReference | '(' Expr ')' | Literal | Number | FunctionCall\r\n * LocationPath ::= RelativeLocationPath | AbsoluteLocationPath\r\n * Step ::= AxisSpecifier NodeTest Predicate* | AbbreviatedStep\r\n * Predicate ::= '[' Expr ']'\r\n */\r\nexport abstract class XPathBaseParser {\r\n protected tokens: XPathToken[] = [];\r\n protected current: number = 0;\r\n protected extensions?: XSLTExtensions;\r\n protected options: XPathBaseParserOptions;\r\n protected staticContext: XPathStaticContext;\r\n protected warningCollector: WarningCollector;\r\n\r\n /**\r\n * Create a new XPath parser.\r\n *\r\n * @param options Optional parser configuration including XSLT extensions\r\n */\r\n protected constructor(options?: XPathBaseParserOptions) {\r\n this.options = {\r\n strict: options?.strict ?? true,\r\n version: options?.version,\r\n cache: options?.cache,\r\n extensions: options?.extensions,\r\n enableNamespaceAxis: options?.enableNamespaceAxis ?? false,\r\n staticContext: options?.staticContext ?? createStaticContext(),\r\n xpath10CompatibilityMode: options?.xpath10CompatibilityMode ?? false,\r\n warningConfig: options?.warningConfig,\r\n warningCollector: options?.warningCollector,\r\n };\r\n\r\n this.staticContext = this.options.staticContext!;\r\n\r\n // Initialize warning collector\r\n if (this.options.warningCollector) {\r\n this.warningCollector = this.options.warningCollector;\r\n } else if (this.options.warningConfig) {\r\n this.warningCollector = createWarningCollector(this.options.warningConfig);\r\n } else {\r\n // Default: create a warning collector that doesn't log to console\r\n this.warningCollector = createWarningCollector({ logToConsole: false });\r\n }\r\n\r\n if (this.options.extensions) {\r\n const errors = validateExtensions(this.options.extensions);\r\n if (errors.length > 0) {\r\n throw new Error(`Invalid XSLT extensions: ${errors.join(', ')}`);\r\n }\r\n this.extensions = this.options.extensions;\r\n }\r\n }\r\n\r\n /**\r\n * Get the warning collector for this parser.\r\n * Useful for retrieving warnings after parsing.\r\n */\r\n getWarningCollector(): WarningCollector {\r\n return this.warningCollector;\r\n }\r\n\r\n /**\r\n * Enforce the supported XPath versions for a concrete parser.\r\n */\r\n protected ensureVersionSupport(\r\n supportedVersions: XPathVersion[],\r\n defaultVersion: XPathVersion\r\n ): void {\r\n const resolvedVersion = this.options.version ?? defaultVersion;\r\n this.options.version = resolvedVersion;\r\n\r\n if (this.options.strict !== false && !supportedVersions.includes(resolvedVersion)) {\r\n throw new Error(\r\n `XPath version ${resolvedVersion} is not supported by ${this.constructor.name}. ` +\r\n `Supported versions: ${supportedVersions.join(', ')}`\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Get the parser options.\r\n */\r\n getOptions(): Readonly<XPathBaseParserOptions> {\r\n return this.options;\r\n }\r\n\r\n parse(tokens: XPathToken[]): XPathExpression {\r\n this.tokens = tokens;\r\n this.current = 0;\r\n\r\n // Emit compatibility mode warning if using XPath 2.0+ with compatibility mode\r\n if (\r\n this.options.xpath10CompatibilityMode &&\r\n this.options.version &&\r\n this.options.version !== '1.0'\r\n ) {\r\n this.warningCollector.emit(\r\n 'XPWC0001',\r\n `XPath ${this.options.version} with compatibility mode`,\r\n tokens.map((t) => t.lexeme).join('')\r\n );\r\n }\r\n\r\n if (tokens.length === 0) {\r\n throw grammarViolation('Empty expression');\r\n }\r\n\r\n const expr = this.parseExpr();\r\n\r\n if (!this.isAtEnd()) {\r\n throw grammarViolation(`Unexpected token: ${this.peek().lexeme}`);\r\n }\r\n\r\n return expr;\r\n }\r\n\r\n // ==================== Token Management ====================\r\n\r\n protected peek(): XPathToken {\r\n return this.tokens[this.current];\r\n }\r\n\r\n protected peekNext(): XPathToken | undefined {\r\n return this.tokens[this.current + 1];\r\n }\r\n\r\n protected previous(): XPathToken {\r\n return this.tokens[this.current - 1];\r\n }\r\n\r\n protected isAtEnd(): boolean {\r\n return this.current >= this.tokens.length;\r\n }\r\n\r\n protected advance(): XPathToken {\r\n if (!this.isAtEnd()) this.current++;\r\n return this.previous();\r\n }\r\n\r\n protected check(type: TokenType): boolean {\r\n if (this.isAtEnd()) return false;\r\n return this.peek().type === type;\r\n }\r\n\r\n protected checkLexeme(lexeme: string): boolean {\r\n if (this.isAtEnd()) return false;\r\n return this.peek().lexeme === lexeme;\r\n }\r\n\r\n protected match(...types: TokenType[]): boolean {\r\n for (const type of types) {\r\n if (this.check(type)) {\r\n this.advance();\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n protected consume(type: TokenType, message: string): XPathToken {\r\n if (this.check(type)) return this.advance();\r\n throw grammarViolation(`${message}. Got: ${this.peek()?.lexeme ?? 'EOF'}`);\r\n }\r\n\r\n // ==================== Expression Parsing ====================\r\n\r\n protected parseExpr(): XPathExpression {\r\n return this.parseOrExpr();\r\n }\r\n\r\n protected parseOrExpr(): XPathExpression {\r\n let left = this.parseAndExpr();\r\n\r\n while (this.check('OPERATOR') && this.peek().lexeme === 'or') {\r\n this.advance();\r\n const right = this.parseAndExpr();\r\n left = new XPathLogicalExpression(left, right, 'or');\r\n }\r\n\r\n return left;\r\n }\r\n\r\n protected parseAndExpr(): XPathExpression {\r\n let left = this.parseEqualityExpr();\r\n\r\n while (this.check('OPERATOR') && this.peek().lexeme === 'and') {\r\n this.advance();\r\n const right = this.parseEqualityExpr();\r\n left = new XPathLogicalExpression(left, right, 'and');\r\n }\r\n\r\n return left;\r\n }\r\n\r\n protected parseEqualityExpr(): XPathExpression {\r\n let left = this.parseRelationalExpr();\r\n\r\n while (this.match('EQUALS', 'NOT_EQUALS')) {\r\n const operator = this.previous().lexeme;\r\n const right = this.parseRelationalExpr();\r\n left = new XPathBinaryExpression(left, right, operator);\r\n }\r\n\r\n return left;\r\n }\r\n\r\n protected parseRelationalExpr(): XPathExpression {\r\n let left = this.parseAdditiveExpr();\r\n\r\n while (\r\n this.match('LESS_THAN', 'GREATER_THAN', 'LESS_THAN_OR_EQUAL', 'GREATER_THAN_OR_EQUAL')\r\n ) {\r\n const operator = this.previous().lexeme;\r\n const right = this.parseAdditiveExpr();\r\n left = new XPathBinaryExpression(left, right, operator);\r\n }\r\n\r\n return left;\r\n }\r\n\r\n protected parseAdditiveExpr(): XPathExpression {\r\n let left = this.parseMultiplicativeExpr();\r\n\r\n while (this.match('PLUS', 'MINUS')) {\r\n const operator = this.previous().lexeme as ArithmeticOperator;\r\n const right = this.parseMultiplicativeExpr();\r\n left = new XPathArithmeticExpression(left, right, operator);\r\n }\r\n\r\n return left;\r\n }\r\n\r\n protected parseMultiplicativeExpr(): XPathExpression {\r\n let left = this.parseUnaryExpr();\r\n\r\n while (true) {\r\n if (this.match('ASTERISK')) {\r\n const right = this.parseUnaryExpr();\r\n left = new XPathArithmeticExpression(left, right, '*');\r\n } else if (\r\n this.check('OPERATOR') &&\r\n (this.peek().lexeme === 'div' || this.peek().lexeme === 'mod')\r\n ) {\r\n const operator = this.advance().lexeme as ArithmeticOperator;\r\n const right = this.parseUnaryExpr();\r\n left = new XPathArithmeticExpression(left, right, operator);\r\n } else {\r\n break;\r\n }\r\n }\r\n\r\n return left;\r\n }\r\n\r\n protected parseUnaryExpr(): XPathExpression {\r\n if (this.match('MINUS')) {\r\n const operand = this.parseUnaryExpr();\r\n return new XPathUnaryExpression('-', operand);\r\n }\r\n\r\n return this.parseUnionExpr();\r\n }\r\n\r\n protected parseUnionExpr(): XPathExpression {\r\n let left = this.parsePathExpr();\r\n\r\n while (this.match('PIPE')) {\r\n const right = this.parsePathExpr();\r\n left = new XPathUnionExpression(left, right);\r\n }\r\n\r\n return left;\r\n }\r\n\r\n // ==================== Path Expression Parsing ====================\r\n\r\n protected parsePathExpr(): XPathExpression {\r\n // Check if this starts a location path\r\n if (this.check('SLASH') || this.check('DOUBLE_SLASH')) {\r\n return this.parseLocationPath();\r\n }\r\n\r\n // Check for axis or abbreviated step that starts a relative location path\r\n if (this.isStepStart()) {\r\n return this.parseLocationPath();\r\n }\r\n\r\n // Otherwise it's a filter expression (possibly followed by path)\r\n let expr = this.parseFilterExpr();\r\n\r\n // Check if followed by '/' or '//'\r\n if (this.match('SLASH', 'DOUBLE_SLASH')) {\r\n const isDescendant = this.previous().type === 'DOUBLE_SLASH';\r\n const steps = this.parseRelativeLocationPath();\r\n\r\n if (isDescendant) {\r\n // Insert descendant-or-self::node() step\r\n steps.unshift(\r\n new XPathStep('descendant-or-self', { type: 'node-type', nodeType: 'node' })\r\n );\r\n }\r\n\r\n // Create a composite expression: evaluate filter expr, then apply location path to each result\r\n const locationPath = new XPathLocationPath(steps, false);\r\n return new FilteredPathExpression(expr, locationPath);\r\n }\r\n\r\n return expr;\r\n }\r\n\r\n protected isStepStart(): boolean {\r\n if (this.isAtEnd()) return false;\r\n\r\n const token = this.peek();\r\n const next = this.peekNext();\r\n\r\n // Treat extended node test function-like syntax (element(), attribute(), etc.) as steps\r\n const nodeTestNames = [\r\n 'element',\r\n 'attribute',\r\n 'schema-element',\r\n 'schema-attribute',\r\n 'document-node',\r\n 'node',\r\n 'text',\r\n 'comment',\r\n 'processing-instruction',\r\n ];\r\n if (\r\n (token.type === 'IDENTIFIER' || token.type === 'NODE_TYPE') &&\r\n next?.type === 'OPEN_PAREN'\r\n ) {\r\n if (nodeTestNames.includes(token.lexeme.toLowerCase())) {\r\n return true;\r\n }\r\n }\r\n\r\n // Don't treat QName function calls as location steps\r\n if (this.isFunctionCallStart()) return false;\r\n\r\n // Abbreviated steps\r\n if (token.type === 'DOT' || token.type === 'DOT_DOT') return true;\r\n\r\n // Attribute axis abbreviation\r\n if (token.type === 'AT') return true;\r\n\r\n // Axis name followed by ::\r\n if (token.type === 'LOCATION') return true;\r\n\r\n // Node type test\r\n if (token.type === 'NODE_TYPE') return true;\r\n\r\n // Wildcard\r\n if (token.type === 'ASTERISK') return true;\r\n\r\n // Name test (identifier that's not a function call)\r\n // OPERATOR tokens (div, mod, and, or) can also be element names\r\n // FUNCTION tokens (id, count, etc.) can also be element/attribute names\r\n if (token.type === 'IDENTIFIER' || token.type === 'OPERATOR' || token.type === 'FUNCTION') {\r\n const next = this.peekNext();\r\n // It's a step if not followed by '(' (which would make it a function call)\r\n return !next || next.type !== 'OPEN_PAREN';\r\n }\r\n\r\n return false;\r\n }\r\n\r\n protected parseLocationPath(): XPathExpression {\r\n let absolute = false;\r\n const steps: XPathStep[] = [];\r\n\r\n if (this.match('SLASH')) {\r\n absolute = true;\r\n\r\n // Check if there's a relative path following\r\n if (!this.isAtEnd() && this.isStepStart()) {\r\n steps.push(...this.parseRelativeLocationPath());\r\n }\r\n } else if (this.match('DOUBLE_SLASH')) {\r\n absolute = true;\r\n\r\n // '//' is shorthand for '/descendant-or-self::node()/'\r\n steps.push(\r\n new XPathStep('descendant-or-self', { type: 'node-type', nodeType: 'node' })\r\n );\r\n steps.push(...this.parseRelativeLocationPath());\r\n } else {\r\n // Relative location path\r\n steps.push(...this.parseRelativeLocationPath());\r\n }\r\n\r\n return new XPathLocationPath(steps, absolute);\r\n }\r\n\r\n protected parseRelativeLocationPath(): XPathStep[] {\r\n const steps: XPathStep[] = [];\r\n\r\n steps.push(this.parseStep());\r\n\r\n while (this.match('SLASH', 'DOUBLE_SLASH')) {\r\n const isDescendant = this.previous().type === 'DOUBLE_SLASH';\r\n\r\n if (isDescendant) {\r\n // '//' is shorthand for '/descendant-or-self::node()/'\r\n steps.push(\r\n new XPathStep('descendant-or-self', { type: 'node-type', nodeType: 'node' })\r\n );\r\n }\r\n\r\n steps.push(this.parseStep());\r\n }\r\n\r\n return steps;\r\n }\r\n\r\n protected parseStep(): XPathStep {\r\n // Handle abbreviated steps\r\n if (this.match('DOT')) {\r\n return new XPathStep('self', { type: 'node-type', nodeType: 'node' });\r\n }\r\n\r\n if (this.match('DOT_DOT')) {\r\n return new XPathStep('parent', { type: 'node-type', nodeType: 'node' });\r\n }\r\n\r\n // Parse axis\r\n let axis: AxisType = 'child'; // default axis\r\n\r\n if (this.match('AT')) {\r\n axis = 'attribute';\r\n } else if (this.check('LOCATION')) {\r\n // Only treat as axis if followed by ::\r\n const next = this.peekNext();\r\n if (next && next.type === 'COLON_COLON') {\r\n axis = this.advance().lexeme as AxisType;\r\n this.advance(); // consume ::\r\n }\r\n // Otherwise, it's an element name that happens to match an axis name\r\n }\r\n\r\n if (axis === 'namespace') {\r\n if (!this.options.enableNamespaceAxis) {\r\n throw unsupportedAxis('namespace');\r\n }\r\n this.warnNamespaceAxis();\r\n }\r\n\r\n // Parse node test\r\n const nodeTest = this.parseNodeTest();\r\n\r\n // Parse predicates\r\n const predicates = this.parsePredicates();\r\n\r\n return new XPathStep(axis, nodeTest, predicates);\r\n }\r\n\r\n protected parseNodeTest(): NodeTest {\r\n // Wildcard\r\n if (this.match('ASTERISK')) {\r\n return { type: 'wildcard' };\r\n }\r\n\r\n // Check for element/attribute/document-node/schema-element/schema-attribute/processing-instruction followed by '('\r\n if (\r\n this.check('NODE_TYPE') ||\r\n this.check('IDENTIFIER') ||\r\n this.check('LOCATION') ||\r\n this.check('FUNCTION') ||\r\n this.check('OPERATOR')\r\n ) {\r\n const next = this.peekNext();\r\n if (next && next.type === 'OPEN_PAREN') {\r\n const testName = this.advance().lexeme.toLowerCase();\r\n this.advance(); // consume '('\r\n\r\n // Handle element() and element(name) and element(name, type) and element(*, type)\r\n if (testName === 'element') {\r\n return this.parseElementTest();\r\n }\r\n\r\n // Handle attribute() and attribute(name) and attribute(name, type) and attribute(*, type)\r\n if (testName === 'attribute') {\r\n return this.parseAttributeTest();\r\n }\r\n\r\n // Handle document-node() and document-node(element(...))\r\n if (testName === 'document-node') {\r\n return this.parseDocumentNodeTest();\r\n }\r\n\r\n // Handle schema-element(name)\r\n if (testName === 'schema-element') {\r\n const name = this.parseNameOrWildcard();\r\n this.consume('CLOSE_PAREN', \"Expected ')' after schema-element name\");\r\n return { type: 'schema-element', name };\r\n }\r\n\r\n // Handle schema-attribute(name)\r\n if (testName === 'schema-attribute') {\r\n const name = this.parseNameOrWildcard();\r\n this.consume('CLOSE_PAREN', \"Expected ')' after schema-attribute name\");\r\n return { type: 'schema-attribute', name };\r\n }\r\n\r\n // Handle node(), text(), comment(), processing-instruction()\r\n if (\r\n testName === 'node' ||\r\n testName === 'text' ||\r\n testName === 'comment' ||\r\n testName === 'processing-instruction'\r\n ) {\r\n // processing-instruction can have an optional literal argument\r\n if (testName === 'processing-instruction' && this.check('STRING')) {\r\n const target = this.advance().lexeme;\r\n this.consume(\r\n 'CLOSE_PAREN',\r\n \"Expected ')' after processing-instruction target\"\r\n );\r\n return { type: 'processing-instruction', target };\r\n }\r\n\r\n this.consume('CLOSE_PAREN', \"Expected ')' after node type\");\r\n return {\r\n type: 'node-type',\r\n nodeType: testName as\r\n | 'node'\r\n | 'text'\r\n | 'comment'\r\n | 'processing-instruction',\r\n };\r\n }\r\n }\r\n // Fall through to name test if not followed by '('\r\n }\r\n\r\n // Name test - can be IDENTIFIER, LOCATION (axis names), FUNCTION (function names), NODE_TYPE,\r\n // or OPERATOR (div, mod, and, or can be element names too)\r\n // All of these can be used as element names in XPath\r\n if (\r\n this.check('IDENTIFIER') ||\r\n this.check('LOCATION') ||\r\n this.check('FUNCTION') ||\r\n this.check('NODE_TYPE') ||\r\n this.check('OPERATOR')\r\n ) {\r\n const name = this.advance().lexeme;\r\n\r\n // Check for namespace prefix\r\n if (this.match('COLON')) {\r\n if (this.match('ASTERISK')) {\r\n // prefix:* - match any element in namespace\r\n return { type: 'wildcard', name: `${name}:*` };\r\n }\r\n // Local name can also be any of these token types\r\n if (\r\n this.check('IDENTIFIER') ||\r\n this.check('LOCATION') ||\r\n this.check('FUNCTION') ||\r\n this.check('NODE_TYPE') ||\r\n this.check('OPERATOR')\r\n ) {\r\n const localName = this.advance().lexeme;\r\n return { type: 'name', name: `${name}:${localName}` };\r\n }\r\n throw new Error('Expected local name after namespace prefix');\r\n }\r\n\r\n return { type: 'name', name };\r\n }\r\n\r\n throw grammarViolation(`Expected node test, got: ${this.peek()?.lexeme ?? 'EOF'}`);\r\n }\r\n\r\n protected parsePredicates(): XPathExpression[] {\r\n const predicates: XPathExpression[] = [];\r\n\r\n while (this.match('OPEN_SQUARE_BRACKET')) {\r\n const expr = this.parseExpr();\r\n this.consume('CLOSE_SQUARE_BRACKET', \"Expected ']' after predicate\");\r\n predicates.push(new XPathPredicate(expr));\r\n }\r\n\r\n return predicates;\r\n }\r\n\r\n // ==================== Filter Expression Parsing ====================\r\n\r\n protected parseFilterExpr(): XPathExpression {\r\n let expr = this.parsePrimaryExpr();\r\n\r\n // Collect all predicates\r\n const predicates: XPathExpression[] = [];\r\n while (this.check('OPEN_SQUARE_BRACKET')) {\r\n predicates.push(...this.parsePredicates());\r\n }\r\n\r\n // If there are predicates, wrap in filter expression\r\n if (predicates.length > 0) {\r\n return new XPathFilterExpression(expr, predicates);\r\n }\r\n\r\n return expr;\r\n }\r\n\r\n protected parsePrimaryExpr(): XPathExpression {\r\n // Variable reference: $name\r\n if (this.match('DOLLAR')) {\r\n const next = this.peek();\r\n if (!next || !this.isNcNameToken(next.type)) {\r\n throw grammarViolation(`Expected variable name after $. Got: ${next?.lexeme ?? 'EOF'}`);\r\n }\r\n const name = this.advance().lexeme;\r\n return new XPathVariableReference(name);\r\n }\r\n\r\n // Parenthesized expression\r\n if (this.match('OPEN_PAREN')) {\r\n // Allow empty parentheses to represent the empty sequence in XPath 2.0\r\n if (this.check('CLOSE_PAREN')) {\r\n this.advance();\r\n return new EmptySequenceExpression();\r\n }\r\n\r\n const expr = this.parseExpr();\r\n this.consume('CLOSE_PAREN', \"Expected ')' after expression\");\r\n return expr;\r\n }\r\n\r\n // String literal\r\n if (this.check('STRING')) {\r\n const value = this.advance().lexeme;\r\n return new XPathStringLiteral(value);\r\n }\r\n\r\n // Number literal\r\n if (this.check('NUMBER')) {\r\n const value = parseFloat(this.advance().lexeme);\r\n return new XPathNumberLiteral(value);\r\n }\r\n\r\n // Function call (supports QName prefixes)\r\n if (this.isFunctionCallStart()) {\r\n return this.parseFunctionCall();\r\n }\r\n\r\n throw grammarViolation(\r\n `Unexpected token in primary expression: ${this.peek()?.lexeme ?? 'EOF'}`\r\n );\r\n }\r\n\r\n protected parseFunctionCall(): XPathExpression {\r\n let name = this.advance().lexeme;\r\n\r\n // Handle EQName: Q{uri}local\r\n if (name.startsWith('Q{')) {\r\n // EQName is already fully qualified, use as-is\r\n this.consume('OPEN_PAREN', \"Expected '(' after function name\");\r\n } else if (this.match('COLON')) {\r\n const local = this.advance();\r\n if (!this.isNcNameToken(local.type)) {\r\n throw grammarViolation('Expected local name after namespace prefix');\r\n }\r\n name = `${name}:${local.lexeme}`;\r\n }\r\n\r\n if (!name.startsWith('Q{')) {\r\n this.consume('OPEN_PAREN', \"Expected '(' after function name\");\r\n }\r\n\r\n const args: XPathExpression[] = [];\r\n\r\n if (!this.check('CLOSE_PAREN')) {\r\n do {\r\n args.push(this.parseExpr());\r\n } while (this.match('COMMA'));\r\n }\r\n\r\n this.consume('CLOSE_PAREN', \"Expected ')' after function arguments\");\r\n\r\n return new XPathFunctionCall(name, args);\r\n }\r\n\r\n private isFunctionCallStart(): boolean {\r\n if (this.isAtEnd()) return false;\r\n\r\n const first = this.peek();\r\n const second = this.peekNext();\r\n\r\n const nodeTestNames = [\r\n 'element',\r\n 'attribute',\r\n 'schema-element',\r\n 'schema-attribute',\r\n 'document-node',\r\n 'node',\r\n 'text',\r\n 'comment',\r\n 'processing-instruction',\r\n ];\r\n const isNodeTestName = nodeTestNames.includes(first.lexeme?.toLowerCase?.() ?? '');\r\n\r\n // EQName followed by '(' is a function call\r\n if (first.type === 'EQNAME' && second?.type === 'OPEN_PAREN') {\r\n return true;\r\n }\r\n\r\n // Simple function name followed by '(' (exclude node-type tests)\r\n if (this.isFunctionNameToken(first.type) && second?.type === 'OPEN_PAREN') {\r\n if (isNodeTestName) return false;\r\n return true;\r\n }\r\n\r\n // QName: prefix:local followed by '(' (exclude node-type tokens)\r\n if (this.isFunctionNameToken(first.type) && second?.type === 'COLON') {\r\n const local = this.tokens[this.current + 2];\r\n const afterLocal = this.tokens[this.current + 3];\r\n if (\r\n local &&\r\n this.isFunctionNameToken(local.type) &&\r\n afterLocal?.type === 'OPEN_PAREN'\r\n ) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Emit deprecation warning for namespace axis usage.\r\n */\r\n private warnNamespaceAxis(): void {\r\n this.warningCollector.emit(\r\n 'XPWD0001',\r\n 'namespace:: axis',\r\n this.tokens.map((t) => t.lexeme).join('')\r\n );\r\n }\r\n\r\n private isFunctionNameToken(type: TokenType | undefined): boolean {\r\n // NODE_TYPE tokens (node, text, comment, processing-instruction) are reserved for node tests, not functions\r\n return (\r\n type === 'IDENTIFIER' ||\r\n type === 'FUNCTION' ||\r\n type === 'OPERATOR' ||\r\n type === 'LOCATION' ||\r\n type === 'EQNAME'\r\n );\r\n }\r\n\r\n private isNcNameToken(type: TokenType | undefined): boolean {\r\n // Allow any token kinds that can represent NCName parts (prefix/local), including node-type tokens for QNames\r\n return (\r\n type === 'IDENTIFIER' ||\r\n type === 'FUNCTION' ||\r\n type === 'OPERATOR' ||\r\n type === 'LOCATION' ||\r\n type === 'NODE_TYPE'\r\n );\r\n }\r\n\r\n private parseNameOrWildcard(): string {\r\n let name = '';\r\n if (this.match('ASTERISK')) {\r\n return '*';\r\n }\r\n if (this.check('EQNAME')) {\r\n return this.advance().lexeme;\r\n }\r\n if (\r\n this.check('IDENTIFIER') ||\r\n this.check('NODE_TYPE') ||\r\n this.check('FUNCTION') ||\r\n this.check('LOCATION') ||\r\n this.check('OPERATOR')\r\n ) {\r\n name = this.advance().lexeme;\r\n if (this.match('COLON')) {\r\n if (this.match('ASTERISK')) {\r\n return `${name}:*`;\r\n }\r\n if (\r\n this.check('IDENTIFIER') ||\r\n this.check('NODE_TYPE') ||\r\n this.check('FUNCTION') ||\r\n this.check('LOCATION') ||\r\n this.check('OPERATOR')\r\n ) {\r\n name += ':' + this.advance().lexeme;\r\n }\r\n }\r\n }\r\n return name;\r\n }\r\n\r\n private parseElementTest(): NodeTest {\r\n if (this.check('CLOSE_PAREN')) {\r\n this.advance();\r\n return { type: 'element' };\r\n }\r\n\r\n const name = this.parseNameOrWildcard();\r\n let elementType: string | undefined;\r\n\r\n if (this.match('COMMA')) {\r\n if (\r\n this.check('IDENTIFIER') ||\r\n this.check('NODE_TYPE') ||\r\n this.check('FUNCTION') ||\r\n this.check('LOCATION')\r\n ) {\r\n elementType = this.parseNameOrWildcard();\r\n }\r\n }\r\n\r\n this.consume('CLOSE_PAREN', \"Expected ')' after element test\");\r\n return {\r\n type: 'element',\r\n name: name === '*' ? undefined : name,\r\n elementType,\r\n isWildcardName: name === '*',\r\n };\r\n }\r\n\r\n private parseAttributeTest(): NodeTest {\r\n if (this.check('CLOSE_PAREN')) {\r\n this.advance();\r\n return { type: 'attribute' };\r\n }\r\n\r\n const name = this.parseNameOrWildcard();\r\n let elementType: string | undefined;\r\n\r\n if (this.match('COMMA')) {\r\n if (\r\n this.check('IDENTIFIER') ||\r\n this.check('NODE_TYPE') ||\r\n this.check('FUNCTION') ||\r\n this.check('LOCATION')\r\n ) {\r\n elementType = this.parseNameOrWildcard();\r\n }\r\n }\r\n\r\n this.consume('CLOSE_PAREN', \"Expected ')' after attribute test\");\r\n return {\r\n type: 'attribute',\r\n name: name === '*' ? undefined : name,\r\n elementType,\r\n isWildcardName: name === '*',\r\n };\r\n }\r\n\r\n private parseDocumentNodeTest(): NodeTest {\r\n if (this.check('CLOSE_PAREN')) {\r\n this.advance();\r\n return { type: 'document-node' };\r\n }\r\n\r\n // document-node(element(...)) or document-node(schema-element(...))\r\n const elementTest = this.parseNodeTest();\r\n this.consume('CLOSE_PAREN', \"Expected ')' after document-node test\");\r\n return {\r\n type: 'document-node',\r\n elementTest,\r\n };\r\n }\r\n}\r\n","/**\r\n * XPath 2.0 Static Context (Section 2.1.1)\r\n *\r\n * Captures compile-time information such as in-scope schema types, function\r\n * signatures, collations, and variable types. This is separate from the\r\n * dynamic XPathContext used during evaluation.\r\n */\r\n\r\nimport { SequenceType, OccurrenceIndicator } from './types/sequence-type';\r\nimport {\r\n DEFAULT_FUNCTION_NAMESPACE,\r\n DEFAULT_COLLATION,\r\n RESERVED_FUNCTION_NAMES,\r\n XS_NAMESPACE,\r\n} from './constants';\r\n\r\n// Re-export constants from unified constants.ts\r\nexport { DEFAULT_FUNCTION_NAMESPACE, DEFAULT_COLLATION, RESERVED_FUNCTION_NAMES };\r\n\r\nexport interface FunctionSignature {\r\n /** QName (prefix:local or local) of the function. */\r\n name: string;\r\n /** Namespace for the function; defaults to DEFAULT_FUNCTION_NAMESPACE. */\r\n namespace?: string;\r\n /** Optional argument types for static checking. */\r\n argumentTypes?: SequenceType[];\r\n /** Optional return type for static checking. */\r\n returnType?: SequenceType;\r\n /** Minimum required arguments. */\r\n minArgs: number;\r\n /** Maximum allowed arguments (undefined = unbounded). */\r\n maxArgs?: number;\r\n}\r\n\r\nexport interface SchemaTypeMap extends Record<string, string> { }\r\nexport interface SchemaElementMap extends Record<string, string> { }\r\nexport interface SchemaAttributeMap extends Record<string, string> { }\r\nexport interface FunctionSignatureMap extends Record<string, FunctionSignature> { }\r\nexport interface VariableTypeMap extends Record<string, SequenceType> { }\r\n\r\nexport interface XPathStaticContext {\r\n schemaTypes: SchemaTypeMap;\r\n elementDeclarations: SchemaElementMap;\r\n attributeDeclarations: SchemaAttributeMap;\r\n defaultElementNamespace: string;\r\n defaultTypeNamespace: string;\r\n functionSignatures: FunctionSignatureMap;\r\n defaultFunctionNamespace: string;\r\n reservedFunctionNames: Set<string>;\r\n collations: string[];\r\n defaultCollation: string;\r\n variableTypes: VariableTypeMap;\r\n contextItemType?: SequenceType;\r\n}\r\n\r\nconst toLocalName = (name: string): string => {\r\n const parts = name.split(':');\r\n return parts[parts.length - 1];\r\n};\r\n\r\nconst validateFunctionSignature = (signature: FunctionSignature): string[] => {\r\n const errors: string[] = [];\r\n if (signature.minArgs < 0) {\r\n errors.push(`Function ${signature.name}: minArgs cannot be negative`);\r\n }\r\n if (signature.maxArgs !== undefined && signature.maxArgs < signature.minArgs) {\r\n errors.push(`Function ${signature.name}: maxArgs cannot be less than minArgs`);\r\n }\r\n return errors;\r\n};\r\n\r\nconst ensureDefaultCollationPresent = (\r\n collations: string[],\r\n defaultCollation: string\r\n): string[] => {\r\n const set = new Set(collations);\r\n if (!set.has(defaultCollation)) {\r\n collations.push(defaultCollation);\r\n }\r\n return Array.from(new Set(collations));\r\n};\r\n\r\nexport function createStaticContext(overrides?: Partial<XPathStaticContext>): XPathStaticContext {\r\n const reserved = overrides?.reservedFunctionNames\r\n ? new Set(overrides.reservedFunctionNames)\r\n : new Set(RESERVED_FUNCTION_NAMES);\r\n\r\n const defaultCollation = overrides?.defaultCollation ?? DEFAULT_COLLATION;\r\n const collations = ensureDefaultCollationPresent(\r\n overrides?.collations ?? [DEFAULT_COLLATION],\r\n defaultCollation\r\n );\r\n\r\n return {\r\n schemaTypes: overrides?.schemaTypes ?? {},\r\n elementDeclarations: overrides?.elementDeclarations ?? {},\r\n attributeDeclarations: overrides?.attributeDeclarations ?? {},\r\n defaultElementNamespace: overrides?.defaultElementNamespace ?? '',\r\n defaultTypeNamespace: overrides?.defaultTypeNamespace ?? XS_NAMESPACE,\r\n functionSignatures: overrides?.functionSignatures ?? {},\r\n defaultFunctionNamespace: overrides?.defaultFunctionNamespace ?? DEFAULT_FUNCTION_NAMESPACE,\r\n reservedFunctionNames: reserved,\r\n collations,\r\n defaultCollation,\r\n variableTypes: overrides?.variableTypes ?? {},\r\n contextItemType: overrides?.contextItemType,\r\n };\r\n}\r\n\r\nexport function isReservedFunctionName(name: string, context?: XPathStaticContext): boolean {\r\n const local = toLocalName(name);\r\n const reserved = context?.reservedFunctionNames ?? new Set(RESERVED_FUNCTION_NAMES);\r\n return reserved.has(local);\r\n}\r\n\r\nexport function registerFunctionSignature(\r\n context: XPathStaticContext,\r\n signature: FunctionSignature,\r\n options?: { allowReserved?: boolean }\r\n): void {\r\n const errors = validateFunctionSignature(signature);\r\n const allowReserved = options?.allowReserved ?? false;\r\n if (!allowReserved && isReservedFunctionName(signature.name, context)) {\r\n errors.push(`Function ${signature.name} is reserved and cannot be overridden`);\r\n }\r\n if (errors.length > 0) {\r\n throw new Error(errors.join('; '));\r\n }\r\n\r\n context.functionSignatures[signature.name] = {\r\n ...signature,\r\n namespace: signature.namespace ?? context.defaultFunctionNamespace,\r\n };\r\n}\r\n\r\nexport function registerVariableType(\r\n context: XPathStaticContext,\r\n name: string,\r\n type: SequenceType\r\n): void {\r\n context.variableTypes[name] = type;\r\n}\r\n\r\nexport function validateStaticContext(context: XPathStaticContext): string[] {\r\n const errors: string[] = [];\r\n\r\n if (!context.collations.includes(context.defaultCollation)) {\r\n errors.push(\r\n `Default collation ${context.defaultCollation} is not in the in-scope collations`\r\n );\r\n }\r\n\r\n for (const signature of Object.values(context.functionSignatures)) {\r\n errors.push(...validateFunctionSignature(signature));\r\n if (isReservedFunctionName(signature.name, context)) {\r\n errors.push(`Function ${signature.name} is reserved and cannot be overridden`);\r\n }\r\n }\r\n\r\n return errors;\r\n}\r\n\r\n/**\r\n * Static Error Detection for XPath 3.1 (Phase 9.5)\r\n *\r\n * Provides compile-time type checking and error detection capabilities\r\n */\r\n\r\nexport enum StaticErrorSeverity {\r\n ERROR = 'error',\r\n WARNING = 'warning',\r\n INFO = 'info',\r\n}\r\n\r\nexport interface StaticError {\r\n severity: StaticErrorSeverity;\r\n code: string;\r\n message: string;\r\n location?: {\r\n line?: number;\r\n column?: number;\r\n offset?: number;\r\n };\r\n suggestion?: string;\r\n}\r\n\r\n/**\r\n * Check for type mismatches in function calls\r\n */\r\nexport function checkFunctionCall(\r\n context: XPathStaticContext,\r\n functionName: string,\r\n argTypes: SequenceType[]\r\n): StaticError[] {\r\n const errors: StaticError[] = [];\r\n const signature = context.functionSignatures[functionName];\r\n\r\n if (!signature) {\r\n errors.push({\r\n severity: StaticErrorSeverity.ERROR,\r\n code: 'XPST0017',\r\n message: `Unknown function: ${functionName}`,\r\n suggestion: `Check if the function name is spelled correctly and is in scope`,\r\n });\r\n return errors;\r\n }\r\n\r\n // Check argument count\r\n if (argTypes.length < signature.minArgs) {\r\n errors.push({\r\n severity: StaticErrorSeverity.ERROR,\r\n code: 'XPST0017',\r\n message: `Function ${functionName} requires at least ${signature.minArgs} arguments, got ${argTypes.length}`,\r\n });\r\n }\r\n\r\n if (signature.maxArgs !== undefined && argTypes.length > signature.maxArgs) {\r\n errors.push({\r\n severity: StaticErrorSeverity.ERROR,\r\n code: 'XPST0017',\r\n message: `Function ${functionName} accepts at most ${signature.maxArgs} arguments, got ${argTypes.length}`,\r\n });\r\n }\r\n\r\n // Check argument types if available\r\n if (signature.argumentTypes) {\r\n for (let i = 0; i < Math.min(argTypes.length, signature.argumentTypes.length); i++) {\r\n const expectedType = signature.argumentTypes[i];\r\n const actualType = argTypes[i];\r\n\r\n if (!typesCompatible(actualType, expectedType)) {\r\n errors.push({\r\n severity: StaticErrorSeverity.ERROR,\r\n code: 'XPTY0004',\r\n message: `Type mismatch in argument ${i + 1} of ${functionName}: expected ${formatSequenceType(expectedType)}, got ${formatSequenceType(actualType)}`,\r\n suggestion: `Consider casting the argument to the expected type`,\r\n });\r\n }\r\n }\r\n }\r\n\r\n return errors;\r\n}\r\n\r\n/**\r\n * Check for undefined variables\r\n */\r\nexport function checkVariableReference(\r\n context: XPathStaticContext,\r\n variableName: string\r\n): StaticError[] {\r\n const errors: StaticError[] = [];\r\n\r\n if (!context.variableTypes[variableName]) {\r\n errors.push({\r\n severity: StaticErrorSeverity.ERROR,\r\n code: 'XPST0008',\r\n message: `Undefined variable: $${variableName}`,\r\n suggestion: `Check if the variable is declared in the current scope`,\r\n });\r\n }\r\n\r\n return errors;\r\n}\r\n\r\n/**\r\n * Check for type compatibility in assignments or casts\r\n */\r\nexport function checkTypeCast(\r\n sourceType: SequenceType,\r\n targetType: SequenceType\r\n): StaticError[] {\r\n const errors: StaticError[] = [];\r\n\r\n if (!typesCompatible(sourceType, targetType)) {\r\n // Check if cast might fail at runtime\r\n errors.push({\r\n severity: StaticErrorSeverity.WARNING,\r\n code: 'XPTY0004',\r\n message: `Potentially unsafe cast from ${formatSequenceType(sourceType)} to ${formatSequenceType(targetType)}`,\r\n suggestion: `Verify that the cast is valid at runtime`,\r\n });\r\n }\r\n\r\n return errors;\r\n}\r\n\r\n/**\r\n * Detect potential division by zero\r\n */\r\nexport function checkDivision(\r\n dividendType: SequenceType,\r\n divisorType: SequenceType,\r\n divisorValue?: any\r\n): StaticError[] {\r\n const errors: StaticError[] = [];\r\n\r\n // If divisor is a literal zero, this is definitely an error\r\n if (divisorValue === 0) {\r\n errors.push({\r\n severity: StaticErrorSeverity.ERROR,\r\n code: 'FOAR0001',\r\n message: `Division by zero`,\r\n });\r\n } else if (divisorValue === undefined) {\r\n // Runtime check needed\r\n errors.push({\r\n severity: StaticErrorSeverity.WARNING,\r\n code: 'FOAR0001',\r\n message: `Potential division by zero - ensure divisor is non-zero at runtime`,\r\n });\r\n }\r\n\r\n return errors;\r\n}\r\n\r\n/**\r\n * Check sequence type compatibility\r\n */\r\nfunction typesCompatible(actual: SequenceType, expected: SequenceType): boolean {\r\n // Simplified compatibility check\r\n // In a full implementation, this would use the type hierarchy\r\n\r\n // Check cardinality compatibility\r\n if (!cardinalityCompatible(actual, expected)) {\r\n return false;\r\n }\r\n\r\n // Get item types using the getter method\r\n const expectedItem = expected.getItemType();\r\n const actualItem = actual.getItemType();\r\n\r\n // item() is compatible with everything\r\n if (expectedItem !== 'empty' && expectedItem.name === 'item') {\r\n return true;\r\n }\r\n\r\n // Check item type compatibility (simplified)\r\n if (actualItem !== 'empty' && expectedItem !== 'empty' && actualItem.name === expectedItem.name) {\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Check cardinality compatibility\r\n */\r\nfunction cardinalityCompatible(actual: SequenceType, expected: SequenceType): boolean {\r\n const actualOccurs = actual.getOccurrence();\r\n const expectedOccurs = expected.getOccurrence();\r\n\r\n // exactly-one matches all\r\n if (actualOccurs === OccurrenceIndicator.EXACTLY_ONE) {\r\n return true;\r\n }\r\n\r\n // zero-or-one matches zero-or-one and zero-or-more\r\n if (actualOccurs === OccurrenceIndicator.ZERO_OR_ONE) {\r\n return expectedOccurs === OccurrenceIndicator.ZERO_OR_ONE || expectedOccurs === OccurrenceIndicator.ZERO_OR_MORE;\r\n }\r\n\r\n // one-or-more matches one-or-more and zero-or-more\r\n if (actualOccurs === OccurrenceIndicator.ONE_OR_MORE) {\r\n return expectedOccurs === OccurrenceIndicator.ONE_OR_MORE || expectedOccurs === OccurrenceIndicator.ZERO_OR_MORE;\r\n }\r\n\r\n // zero-or-more only matches zero-or-more\r\n if (actualOccurs === OccurrenceIndicator.ZERO_OR_MORE) {\r\n return expectedOccurs === OccurrenceIndicator.ZERO_OR_MORE;\r\n }\r\n\r\n return actualOccurs === expectedOccurs;\r\n}\r\n\r\n/**\r\n * Format a SequenceType for display\r\n */\r\nfunction formatSequenceType(type: SequenceType): string {\r\n const itemType = type.getItemType();\r\n const itemName = itemType === 'empty' ? 'empty-sequence()' : itemType.name;\r\n const occurs = type.getOccurrence();\r\n\r\n const occursSymbol: Record<string, string> = {\r\n [OccurrenceIndicator.EXACTLY_ONE]: '',\r\n [OccurrenceIndicator.ZERO_OR_ONE]: '?',\r\n [OccurrenceIndicator.ONE_OR_MORE]: '+',\r\n [OccurrenceIndicator.ZERO_OR_MORE]: '*',\r\n };\r\n\r\n return `${itemName}${occursSymbol[occurs] || ''}`;\r\n}\r\n\r\n/**\r\n * Collect all static errors for an expression tree\r\n */\r\nexport function analyzeExpression(\r\n context: XPathStaticContext,\r\n expression: any\r\n): StaticError[] {\r\n const errors: StaticError[] = [];\r\n\r\n // Recursively analyze the expression tree\r\n // This is a placeholder for full static analysis\r\n if (!expression) {\r\n return errors;\r\n }\r\n\r\n if (typeof expression !== 'object') {\r\n return errors;\r\n }\r\n\r\n // Check function calls\r\n if (expression.type === 'function-call') {\r\n errors.push(...checkFunctionCall(context, expression.name, expression.args || []));\r\n }\r\n\r\n // Check variable references\r\n if (expression.type === 'variable') {\r\n errors.push(...checkVariableReference(context, expression.name));\r\n }\r\n\r\n // Recursively analyze child expressions\r\n if (Array.isArray(expression.children)) {\r\n for (const child of expression.children) {\r\n errors.push(...analyzeExpression(context, child));\r\n }\r\n }\r\n\r\n return errors;\r\n}\r\n\r\n/**\r\n * Format errors for display\r\n */\r\nexport function formatStaticErrors(errors: StaticError[]): string {\r\n if (errors.length === 0) {\r\n return 'No static errors found';\r\n }\r\n\r\n return errors\r\n .map((error) => {\r\n const location = error.location\r\n ? ` at line ${error.location.line}, column ${error.location.column}`\r\n : '';\r\n const suggestion = error.suggestion ? `\\n Suggestion: ${error.suggestion}` : '';\r\n return `[${error.severity.toUpperCase()}] ${error.code}: ${error.message}${location}${suggestion}`;\r\n })\r\n .join('\\n');\r\n}\r\n","/**\r\n * XSLT Extension Function specification for integration with xslt-processor.\r\n *\r\n * This file defines the interface and types for XSLT 1.0 extension functions.\r\n * The actual implementations live in the xslt-processor package.\r\n */\r\n\r\nimport { XPathContext } from './context';\r\nimport { XPathStaticContext } from './static-context';\r\nimport { XPathNode } from './node';\r\nimport { WarningConfiguration, WarningCollector } from './warnings';\r\n\r\n/**\r\n * Signature for an XSLT extension function.\r\n *\r\n * Extension functions receive arguments that have already been evaluated\r\n * by the XPath parser and must return a valid XPath result type.\r\n */\r\nexport type XSLTExtensionFunction = (context: XPathContext, ...args: any[]) => any;\r\n\r\n/**\r\n * Metadata for an XSLT extension function.\r\n */\r\nexport interface XSLTFunctionMetadata {\r\n /**\r\n * Function name as it appears in XPath expressions.\r\n * Examples: 'document', 'key', 'format-number'\r\n */\r\n name: string;\r\n\r\n /**\r\n * Minimum number of required arguments.\r\n */\r\n minArgs: number;\r\n\r\n /**\r\n * Maximum number of arguments (undefined for unlimited).\r\n */\r\n maxArgs?: number;\r\n\r\n /**\r\n * Function implementation.\r\n */\r\n implementation: XSLTExtensionFunction;\r\n\r\n /**\r\n * Brief description for documentation.\r\n */\r\n description?: string;\r\n}\r\n\r\n/**\r\n * XSLT Extensions bundle that can be passed to the XPath parser.\r\n *\r\n * This interface allows the xslt-processor package to provide XSLT-specific\r\n * functions while keeping the xpath library pure XPath 1.0.\r\n */\r\nexport interface XSLTExtensions {\r\n /**\r\n * List of XSLT extension functions to register.\r\n */\r\n functions: XSLTFunctionMetadata[];\r\n\r\n /**\r\n * XSLT version these extensions implement.\r\n */\r\n version: '1.0' | '2.0' | '3.0';\r\n\r\n /**\r\n * Optional: Additional context properties needed by XSLT functions.\r\n * For example, key definitions for key() function, or document cache for document().\r\n */\r\n contextExtensions?: {\r\n /**\r\n * Key definitions from <xsl:key> elements.\r\n * Format: { keyName: { match: string, use: string } }\r\n */\r\n keys?: Record<string, { match: string; use: string }>;\r\n\r\n /**\r\n * Document loader for document() function.\r\n */\r\n documentLoader?: (uri: string, baseUri?: string) => XPathNode | null;\r\n\r\n /**\r\n * Decimal format definitions from <xsl:decimal-format> elements.\r\n * Used by format-number() function.\r\n */\r\n decimalFormats?: Record<string, any>;\r\n\r\n /**\r\n * System properties for system-property() function.\r\n */\r\n systemProperties?: Record<string, string>;\r\n };\r\n}\r\n\r\n/**\r\n * Parser options that include XSLT extensions support.\r\n */\r\nexport interface XPathBaseParserOptions {\r\n /**\r\n * XPath specification version to use.\r\n *\r\n * - '1.0': XPath 1.0 (default, fully implemented)\r\n * - '2.0': XPath 2.0 (adds if-then-else, for, quantified expressions, type system)\r\n * - '3.0': XPath 3.0 (not yet implemented, falls back to 2.0 parser)\r\n * - '3.1': XPath 3.1 (not yet implemented, falls back to 2.0 parser)\r\n *\r\n * When using XPath10Parser, only '1.0' is valid.\r\n * When using XPath20Parser, only '2.0' is valid (in strict mode).\r\n * Use createXPathParser() factory for automatic version selection.\r\n *\r\n * Default: '1.0'\r\n */\r\n version?: '1.0' | '2.0' | '3.0' | '3.1';\r\n\r\n /**\r\n * Optional XSLT extensions to enable.\r\n * When provided, the parser will recognize and allow calling XSLT functions.\r\n */\r\n extensions?: XSLTExtensions;\r\n\r\n /**\r\n * Whether to cache parsed expressions for reuse.\r\n * Default: false\r\n */\r\n cache?: boolean;\r\n\r\n /**\r\n * Strict mode: throw errors for unsupported features.\r\n * When false, unsupported features may be silently ignored or cause warnings.\r\n * Default: true\r\n */\r\n strict?: boolean;\r\n\r\n /**\r\n * Enable support for the deprecated namespace axis (namespace::).\r\n * Default: false (raises XPST0010 when used).\r\n */\r\n enableNamespaceAxis?: boolean;\r\n\r\n /**\r\n * Static context configuration (in-scope types, functions, collations, variables).\r\n * Defaults to an empty static context with XPath-defined namespaces.\r\n */\r\n staticContext?: XPathStaticContext;\r\n\r\n /**\r\n * Enable XPath 1.0 backward compatibility mode.\r\n *\r\n * When true, XPath 2.0+ expressions follow XPath 1.0 type conversion rules.\r\n * This enables:\r\n * - XPath 1.0 boolean conversion semantics\r\n * - XPath 1.0 numeric conversion (with NaN for empty sequences)\r\n * - XPath 1.0 comparison rules (node-set to string conversion)\r\n * - XPath 1.0 logical operator behavior (short-circuit, error suppression)\r\n *\r\n * This option is only meaningful when version is '2.0' or higher.\r\n * When version is '1.0', this option is ignored (1.0 semantics are used).\r\n *\r\n * Default: false (XPath 2.0 semantics when using 2.0+ parser)\r\n */\r\n xpath10CompatibilityMode?: boolean;\r\n\r\n /**\r\n * Warning configuration for deprecated features and migration guidance (Phase 8.2).\r\n * Configure how warnings are collected, filtered, and reported.\r\n * Default: warnings enabled with 'info' minimum severity\r\n */\r\n warningConfig?: WarningConfiguration;\r\n\r\n /**\r\n * Warning collector instance for gathering warnings during parsing.\r\n * If not provided, a new collector will be created based on warningConfig.\r\n * Passing an existing collector allows aggregating warnings across multiple parses.\r\n */\r\n warningCollector?: WarningCollector;\r\n}\r\n\r\n/**\r\n * Helper to create an empty XSLT extensions bundle.\r\n * Useful for testing or as a starting point.\r\n */\r\nexport function createEmptyExtensions(version: '1.0' | '2.0' | '3.0' = '1.0'): XSLTExtensions {\r\n return {\r\n functions: [],\r\n version,\r\n };\r\n}\r\n\r\n/**\r\n * Helper to validate XSLT extensions bundle.\r\n * Checks for duplicate function names and invalid configurations.\r\n */\r\nexport function validateExtensions(extensions: XSLTExtensions): string[] {\r\n const errors: string[] = [];\r\n const functionNames = new Set<string>();\r\n\r\n for (const func of extensions.functions) {\r\n // Check for duplicate function names\r\n if (functionNames.has(func.name)) {\r\n errors.push(`Duplicate function name: ${func.name}`);\r\n }\r\n functionNames.add(func.name);\r\n\r\n // Validate argument counts\r\n if (func.minArgs < 0) {\r\n errors.push(`Function ${func.name}: minArgs cannot be negative`);\r\n }\r\n if (func.maxArgs !== undefined && func.maxArgs < func.minArgs) {\r\n errors.push(`Function ${func.name}: maxArgs cannot be less than minArgs`);\r\n }\r\n\r\n // Check implementation exists\r\n if (typeof func.implementation !== 'function') {\r\n errors.push(`Function ${func.name}: implementation must be a function`);\r\n }\r\n }\r\n\r\n return errors;\r\n}\r\n\r\n/**\r\n * Extract function names from XSLT extensions.\r\n * Useful for registering extension functions with the lexer.\r\n */\r\nexport function getExtensionFunctionNames(extensions: XSLTExtensions): string[] {\r\n return extensions.functions.map((f) => f.name);\r\n}\r\n","/**\r\n * XPath Warning System (Phase 8.2)\r\n *\r\n * Provides runtime warnings for deprecated features, potential incompatibilities,\r\n * and migration guidance when using XPath expressions.\r\n *\r\n * Reference: XPath 2.0 Specification, Appendix I (Incompatibilities)\r\n */\r\n\r\n/**\r\n * Warning severity levels\r\n */\r\nexport type WarningSeverity = 'info' | 'warning' | 'deprecation';\r\n\r\n/**\r\n * Warning categories for grouping and filtering\r\n */\r\nexport type WarningCategory =\r\n | 'deprecation'\r\n | 'compatibility'\r\n | 'performance'\r\n | 'type-coercion'\r\n | 'behavior-change';\r\n\r\n/**\r\n * Metadata for warning codes\r\n */\r\nexport interface WarningCodeMetadata {\r\n code: string;\r\n severity: WarningSeverity;\r\n category: WarningCategory;\r\n title: string;\r\n description: string;\r\n migration?: string;\r\n specReference?: string;\r\n}\r\n\r\n/**\r\n * Represents a single warning instance\r\n */\r\nexport interface XPathWarning {\r\n code: string;\r\n message: string;\r\n severity: WarningSeverity;\r\n category: WarningCategory;\r\n context?: string;\r\n expression?: string;\r\n line?: number;\r\n column?: number;\r\n}\r\n\r\n/**\r\n * All XPath warning codes with metadata\r\n */\r\nexport const WARNING_CODES: Record<string, WarningCodeMetadata> = {\r\n // ========================================================================\r\n // DEPRECATION WARNINGS\r\n // ========================================================================\r\n XPWD0001: {\r\n code: 'XPWD0001',\r\n severity: 'deprecation',\r\n category: 'deprecation',\r\n title: 'Namespace axis deprecated',\r\n description:\r\n 'The namespace axis (namespace::) is deprecated in XPath 2.0 and may not be ' +\r\n 'supported in all implementations. Consider using fn:namespace-uri-for-prefix() ' +\r\n 'or fn:in-scope-prefixes() instead.',\r\n migration:\r\n 'Replace namespace::* with fn:in-scope-prefixes(.) to get namespace prefixes, ' +\r\n 'or use fn:namespace-uri-for-prefix($prefix, .) to get namespace URIs.',\r\n specReference: 'XPath 2.0 Section 3.2.1.1',\r\n },\r\n\r\n XPWD0002: {\r\n code: 'XPWD0002',\r\n severity: 'deprecation',\r\n category: 'deprecation',\r\n title: 'Implicit string conversion',\r\n description:\r\n 'Implicit conversion of node-sets to strings using the first node is deprecated. ' +\r\n 'In XPath 2.0, this requires explicit conversion using fn:string() or data().',\r\n migration: 'Use fn:string($nodeset) or fn:data($nodeset) for explicit conversion.',\r\n specReference: 'XPath 2.0 Appendix I.2',\r\n },\r\n\r\n // ========================================================================\r\n // COMPATIBILITY WARNINGS\r\n // ========================================================================\r\n XPWC0001: {\r\n code: 'XPWC0001',\r\n severity: 'warning',\r\n category: 'compatibility',\r\n title: 'XPath 1.0 compatibility mode active',\r\n description:\r\n 'XPath 1.0 compatibility mode is enabled. Some XPath 2.0 type safety features ' +\r\n 'are relaxed to maintain backward compatibility.',\r\n migration: 'Consider migrating to XPath 2.0 semantics for improved type safety.',\r\n specReference: 'XPath 2.0 Section 3.6',\r\n },\r\n\r\n XPWC0002: {\r\n code: 'XPWC0002',\r\n severity: 'warning',\r\n category: 'compatibility',\r\n title: 'String comparison in XPath 2.0',\r\n description:\r\n 'String comparisons in XPath 2.0 are performed using Unicode codepoint collation ' +\r\n 'by default, which may produce different results than XPath 1.0.',\r\n migration: 'Use explicit collation specification if locale-specific comparison is needed.',\r\n specReference: 'XPath 2.0 Appendix I.4',\r\n },\r\n\r\n XPWC0003: {\r\n code: 'XPWC0003',\r\n severity: 'warning',\r\n category: 'compatibility',\r\n title: 'Empty sequence handling differs',\r\n description:\r\n 'In XPath 2.0, operations on empty sequences may return empty sequences instead ' +\r\n 'of NaN or false as in XPath 1.0.',\r\n migration: 'Use explicit empty sequence handling with fn:empty() or default values.',\r\n specReference: 'XPath 2.0 Appendix I.3',\r\n },\r\n\r\n // ========================================================================\r\n // TYPE COERCION WARNINGS\r\n // ========================================================================\r\n XPWT0001: {\r\n code: 'XPWT0001',\r\n severity: 'warning',\r\n category: 'type-coercion',\r\n title: 'Implicit numeric conversion',\r\n description:\r\n 'Value is being implicitly converted to a number. In XPath 2.0, this requires ' +\r\n 'explicit conversion in strict mode.',\r\n migration: 'Use xs:decimal(), xs:double(), or number() for explicit conversion.',\r\n specReference: 'XPath 2.0 Appendix I.2',\r\n },\r\n\r\n XPWT0002: {\r\n code: 'XPWT0002',\r\n severity: 'warning',\r\n category: 'type-coercion',\r\n title: 'Implicit boolean conversion',\r\n description:\r\n 'Value is being implicitly converted to boolean using XPath 1.0 rules. ' +\r\n 'In XPath 2.0, this is called Effective Boolean Value (EBV).',\r\n migration: 'Use fn:boolean() for explicit conversion.',\r\n specReference: 'XPath 2.0 Section 2.4.3',\r\n },\r\n\r\n XPWT0003: {\r\n code: 'XPWT0003',\r\n severity: 'info',\r\n category: 'type-coercion',\r\n title: 'Numeric type promotion',\r\n description:\r\n 'Numeric value is being promoted in the type hierarchy (integer → decimal → ' +\r\n 'float → double). This may result in precision loss.',\r\n migration: 'Consider using explicit casting if precision is important.',\r\n specReference: 'XPath 2.0 Appendix B.1',\r\n },\r\n\r\n // ========================================================================\r\n // BEHAVIOR CHANGE WARNINGS\r\n // ========================================================================\r\n XPWB0001: {\r\n code: 'XPWB0001',\r\n severity: 'warning',\r\n category: 'behavior-change',\r\n title: 'Arithmetic with empty sequence',\r\n description:\r\n 'In XPath 2.0, arithmetic operations with empty sequences return empty sequences, ' +\r\n 'not NaN as in XPath 1.0.',\r\n migration: 'Handle empty sequences explicitly before arithmetic operations.',\r\n specReference: 'XPath 2.0 Appendix I.3',\r\n },\r\n\r\n XPWB0002: {\r\n code: 'XPWB0002',\r\n severity: 'warning',\r\n category: 'behavior-change',\r\n title: 'Comparison with empty sequence',\r\n description:\r\n 'In XPath 2.0, value comparisons (eq, ne, etc.) with empty sequences return ' +\r\n 'empty sequences, not false.',\r\n migration: 'Use fn:empty() or fn:exists() to check for empty sequences before comparison.',\r\n specReference: 'XPath 2.0 Appendix I.3',\r\n },\r\n\r\n XPWB0003: {\r\n code: 'XPWB0003',\r\n severity: 'warning',\r\n category: 'behavior-change',\r\n title: 'Multiple values in singleton context',\r\n description:\r\n 'A sequence with multiple items is being used where a single item is expected. ' +\r\n 'In XPath 2.0, this may raise a type error.',\r\n migration: 'Use predicates or fn:head() to select a single item.',\r\n specReference: 'XPath 2.0 Section 2.4.4',\r\n },\r\n\r\n XPWB0004: {\r\n code: 'XPWB0004',\r\n severity: 'warning',\r\n category: 'behavior-change',\r\n title: 'String value of nodes',\r\n description:\r\n 'The string value of typed nodes in XPath 2.0 may differ from XPath 1.0 when ' +\r\n 'schema type information is present.',\r\n migration: 'Use fn:string() for consistent string conversion.',\r\n specReference: 'XPath 2.0 Appendix I.1',\r\n },\r\n\r\n // ========================================================================\r\n // PERFORMANCE WARNINGS\r\n // ========================================================================\r\n XPWP0001: {\r\n code: 'XPWP0001',\r\n severity: 'info',\r\n category: 'performance',\r\n title: 'Descendant axis on large document',\r\n description:\r\n 'Using descendant or descendant-or-self axis on large documents may impact ' +\r\n 'performance. Consider using more specific path expressions.',\r\n migration: 'Use more specific paths or indexes if available.',\r\n },\r\n\r\n XPWP0002: {\r\n code: 'XPWP0002',\r\n severity: 'info',\r\n category: 'performance',\r\n title: 'General comparison on sequences',\r\n description:\r\n 'General comparisons (=, !=, etc.) on sequences perform existential quantification, ' +\r\n 'which may be slower than value comparisons on single items.',\r\n migration: 'Use value comparisons (eq, ne, etc.) when comparing single values.',\r\n specReference: 'XPath 2.0 Section 3.5.2',\r\n },\r\n};\r\n\r\n/**\r\n * Warning handler function type\r\n */\r\nexport type WarningHandler = (warning: XPathWarning) => void;\r\n\r\n/**\r\n * Configuration for warning behavior\r\n */\r\nexport interface WarningConfiguration {\r\n /**\r\n * Whether warnings are enabled. Default: true\r\n */\r\n enabled?: boolean;\r\n\r\n /**\r\n * Minimum severity level to report. Default: 'info'\r\n */\r\n minSeverity?: WarningSeverity;\r\n\r\n /**\r\n * Categories to suppress (not report)\r\n */\r\n suppressCategories?: WarningCategory[];\r\n\r\n /**\r\n * Specific warning codes to suppress\r\n */\r\n suppressCodes?: string[];\r\n\r\n /**\r\n * Custom warning handler. If not provided, warnings are collected internally.\r\n */\r\n handler?: WarningHandler;\r\n\r\n /**\r\n * Whether to also log warnings to console. Default: false\r\n */\r\n logToConsole?: boolean;\r\n\r\n /**\r\n * Maximum number of warnings to collect before stopping. Default: 100\r\n */\r\n maxWarnings?: number;\r\n\r\n /**\r\n * Whether to emit each warning only once per expression. Default: true\r\n */\r\n emitOnce?: boolean;\r\n}\r\n\r\n/**\r\n * Default warning configuration\r\n */\r\nexport const DEFAULT_WARNING_CONFIG: Required<WarningConfiguration> = {\r\n enabled: true,\r\n minSeverity: 'info',\r\n suppressCategories: [],\r\n suppressCodes: [],\r\n handler: () => {},\r\n logToConsole: false,\r\n maxWarnings: 100,\r\n emitOnce: true,\r\n};\r\n\r\n/**\r\n * Severity level numeric values for comparison\r\n */\r\nconst SEVERITY_LEVELS: Record<WarningSeverity, number> = {\r\n info: 0,\r\n warning: 1,\r\n deprecation: 2,\r\n};\r\n\r\n/**\r\n * Warning collector class for managing warnings during expression evaluation\r\n */\r\nexport class WarningCollector {\r\n private warnings: XPathWarning[] = [];\r\n private config: Required<WarningConfiguration>;\r\n private emittedCodes: Set<string> = new Set();\r\n\r\n constructor(config?: WarningConfiguration) {\r\n this.config = { ...DEFAULT_WARNING_CONFIG, ...config };\r\n }\r\n\r\n /**\r\n * Emit a warning by code\r\n */\r\n emit(code: string, context?: string, expression?: string): void {\r\n if (!this.config.enabled) return;\r\n\r\n const metadata = WARNING_CODES[code];\r\n if (!metadata) {\r\n // Unknown warning code - still emit but with minimal info\r\n this.addWarning({\r\n code,\r\n message: `Unknown warning: ${code}`,\r\n severity: 'warning',\r\n category: 'compatibility',\r\n context,\r\n expression,\r\n });\r\n return;\r\n }\r\n\r\n // Check if this code should be suppressed\r\n if (this.config.suppressCodes.includes(code)) return;\r\n\r\n // Check if this category should be suppressed\r\n if (this.config.suppressCategories.includes(metadata.category)) return;\r\n\r\n // Check severity threshold\r\n if (SEVERITY_LEVELS[metadata.severity] < SEVERITY_LEVELS[this.config.minSeverity]) {\r\n return;\r\n }\r\n\r\n // Check emitOnce\r\n if (this.config.emitOnce && this.emittedCodes.has(code)) return;\r\n\r\n // Check max warnings\r\n if (this.warnings.length >= this.config.maxWarnings) return;\r\n\r\n const warning: XPathWarning = {\r\n code: metadata.code,\r\n message: metadata.description,\r\n severity: metadata.severity,\r\n category: metadata.category,\r\n context,\r\n expression,\r\n };\r\n\r\n this.addWarning(warning);\r\n this.emittedCodes.add(code);\r\n }\r\n\r\n /**\r\n * Emit a custom warning\r\n */\r\n emitCustom(warning: XPathWarning): void {\r\n if (!this.config.enabled) return;\r\n if (this.warnings.length >= this.config.maxWarnings) return;\r\n if (this.config.emitOnce && this.emittedCodes.has(warning.code)) return;\r\n\r\n this.addWarning(warning);\r\n this.emittedCodes.add(warning.code);\r\n }\r\n\r\n private addWarning(warning: XPathWarning): void {\r\n this.warnings.push(warning);\r\n\r\n // Call custom handler\r\n if (this.config.handler) {\r\n this.config.handler(warning);\r\n }\r\n\r\n // Log to console if enabled\r\n if (this.config.logToConsole) {\r\n const prefix =\r\n warning.severity === 'deprecation'\r\n ? '[DEPRECATED]'\r\n : warning.severity === 'warning'\r\n ? '[WARNING]'\r\n : '[INFO]';\r\n // eslint-disable-next-line no-console\r\n console.warn(`${prefix} ${warning.code}: ${warning.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * Get all collected warnings\r\n */\r\n getWarnings(): readonly XPathWarning[] {\r\n return this.warnings;\r\n }\r\n\r\n /**\r\n * Get warnings filtered by severity\r\n */\r\n getWarningsBySeverity(severity: WarningSeverity): XPathWarning[] {\r\n return this.warnings.filter((w) => w.severity === severity);\r\n }\r\n\r\n /**\r\n * Get warnings filtered by category\r\n */\r\n getWarningsByCategory(category: WarningCategory): XPathWarning[] {\r\n return this.warnings.filter((w) => w.category === category);\r\n }\r\n\r\n /**\r\n * Check if any warnings were collected\r\n */\r\n hasWarnings(): boolean {\r\n return this.warnings.length > 0;\r\n }\r\n\r\n /**\r\n * Get count of warnings\r\n */\r\n count(): number {\r\n return this.warnings.length;\r\n }\r\n\r\n /**\r\n * Clear all collected warnings\r\n */\r\n clear(): void {\r\n this.warnings = [];\r\n this.emittedCodes.clear();\r\n }\r\n\r\n /**\r\n * Format warnings as a report string\r\n */\r\n formatReport(): string {\r\n if (this.warnings.length === 0) {\r\n return 'No warnings.';\r\n }\r\n\r\n const lines: string[] = [];\r\n lines.push(\r\n `XPath Warnings Report (${this.warnings.length} warning${this.warnings.length === 1 ? '' : 's'}):`\r\n );\r\n lines.push('');\r\n\r\n // Group by category\r\n const byCategory: Record<string, XPathWarning[]> = {};\r\n for (const warning of this.warnings) {\r\n const category = warning.category;\r\n if (!byCategory[category]) {\r\n byCategory[category] = [];\r\n }\r\n byCategory[category].push(warning);\r\n }\r\n\r\n for (const category of Object.keys(byCategory)) {\r\n const warnings = byCategory[category];\r\n lines.push(`## ${formatCategoryName(category as WarningCategory)}`);\r\n for (const warning of warnings) {\r\n const metadata = WARNING_CODES[warning.code];\r\n lines.push(` ${warning.code}: ${metadata?.title || warning.message}`);\r\n if (warning.context) {\r\n lines.push(` Context: ${warning.context}`);\r\n }\r\n if (metadata?.migration) {\r\n lines.push(` Migration: ${metadata.migration}`);\r\n }\r\n }\r\n lines.push('');\r\n }\r\n\r\n return lines.join('\\n');\r\n }\r\n}\r\n\r\n/**\r\n * Format category name for display\r\n */\r\nfunction formatCategoryName(category: WarningCategory): string {\r\n switch (category) {\r\n case 'deprecation':\r\n return 'Deprecated Features';\r\n case 'compatibility':\r\n return 'Compatibility Issues';\r\n case 'performance':\r\n return 'Performance Considerations';\r\n case 'type-coercion':\r\n return 'Type Coercion';\r\n case 'behavior-change':\r\n return 'Behavior Changes';\r\n default:\r\n return category;\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// HELPER FUNCTIONS\r\n// ============================================================================\r\n\r\n/**\r\n * Get warning metadata by code\r\n */\r\nexport function getWarningMetadata(code: string): WarningCodeMetadata | undefined {\r\n return WARNING_CODES[code];\r\n}\r\n\r\n/**\r\n * Create a warning collector with default configuration\r\n */\r\nexport function createWarningCollector(config?: WarningConfiguration): WarningCollector {\r\n return new WarningCollector(config);\r\n}\r\n\r\n/**\r\n * Create a no-op warning collector (for when warnings are disabled)\r\n */\r\nexport function createNoOpWarningCollector(): WarningCollector {\r\n return new WarningCollector({ enabled: false });\r\n}\r\n\r\n/**\r\n * Check if a code is a valid warning code\r\n */\r\nexport function isValidWarningCode(code: string): boolean {\r\n return code in WARNING_CODES;\r\n}\r\n\r\n/**\r\n * Get all warning codes\r\n */\r\nexport function getAllWarningCodes(): string[] {\r\n return Object.keys(WARNING_CODES);\r\n}\r\n\r\n/**\r\n * Get warning codes by category\r\n */\r\nexport function getWarningCodesByCategory(category: WarningCategory): string[] {\r\n return Object.entries(WARNING_CODES)\r\n .filter(([, meta]) => meta.category === category)\r\n .map(([code]) => code);\r\n}\r\n\r\n/**\r\n * Get warning codes by severity\r\n */\r\nexport function getWarningCodesBySeverity(severity: WarningSeverity): string[] {\r\n return Object.entries(WARNING_CODES)\r\n .filter(([, meta]) => meta.severity === severity)\r\n .map(([code]) => code);\r\n}\r\n\r\n/**\r\n * Format a single warning for display\r\n */\r\nexport function formatWarning(warning: XPathWarning): string {\r\n const metadata = WARNING_CODES[warning.code];\r\n let result = `${warning.code}: ${metadata?.title || 'Unknown warning'}`;\r\n\r\n if (warning.context) {\r\n result += ` (${warning.context})`;\r\n }\r\n\r\n result += '\\n ' + warning.message;\r\n\r\n if (metadata?.migration) {\r\n result += '\\n Migration: ' + metadata.migration;\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Format warning code description\r\n */\r\nexport function formatWarningCodeDescription(code: string): string {\r\n const meta = getWarningMetadata(code);\r\n if (!meta) {\r\n return `Unknown warning: ${code}`;\r\n }\r\n return `${code}: ${meta.title} - ${meta.description}`;\r\n}\r\n","import { XPathBaseParserOptions } from '../xslt-extensions';\r\nimport { XPathBaseParser } from './base-parser';\r\n\r\nexport class XPath10Parser extends XPathBaseParser {\r\n constructor(options?: XPathBaseParserOptions) {\r\n super(options);\r\n this.ensureVersionSupport(['1.0'], '1.0');\r\n }\r\n}\r\n","import {\r\n XPathCastableExpression,\r\n XPathConditionalExpression,\r\n XPathExpression,\r\n XPathForExpression,\r\n XPathInstanceOfExpression,\r\n XPathQuantifiedExpression,\r\n XPathTreatExpression,\r\n XPathUnionExpression,\r\n XPathVariableReference,\r\n RangeExpression,\r\n} from '../expressions';\r\nimport { XPathToken } from '../lexer/token';\r\nimport {\r\n ITEM_TYPE,\r\n OccurrenceIndicator,\r\n SequenceType,\r\n createAtomicSequenceType,\r\n createEmptySequenceType,\r\n createItemSequenceType,\r\n getAtomicType,\r\n} from '../types';\r\nimport { XPathBaseParserOptions } from '../xslt-extensions';\r\nimport { XPathBaseParser } from './base-parser';\r\n\r\nexport class XPath20Parser extends XPathBaseParser {\r\n constructor(options?: XPathBaseParserOptions) {\r\n super(options);\r\n // Allow 3.0/3.1 to pass through for XPath30Parser subclass\r\n // XPath 2.0 features are a subset of 3.0/3.1\r\n this.ensureVersionSupport(['2.0', '3.0', '3.1'], '2.0');\r\n }\r\n\r\n protected parseExpr(): XPathExpression {\r\n if (this.checkReservedWord('for')) {\r\n return this.parseForExpr();\r\n }\r\n\r\n if (this.checkReservedWord('some') || this.checkReservedWord('every')) {\r\n return this.parseQuantifiedExpr();\r\n }\r\n\r\n return super.parseExpr();\r\n }\r\n\r\n protected parseUnionExpr(): XPathExpression {\r\n let left = this.parseInstanceOfExpr();\r\n\r\n while (this.match('PIPE')) {\r\n const right = this.parseInstanceOfExpr();\r\n left = new XPathUnionExpression(left, right);\r\n }\r\n\r\n return left;\r\n }\r\n\r\n protected parsePrimaryExpr(): XPathExpression {\r\n if (this.check('RESERVED_WORD') && this.peek().lexeme === 'if') {\r\n return this.parseIfExpr();\r\n }\r\n\r\n // Variable reference: $name\r\n // In XPath 2.0+, variable names can be any NCName, including reserved words like 'name'\r\n if (this.check('DOLLAR')) {\r\n this.advance(); // consume $\r\n if (!this.isNameToken()) {\r\n throw new Error(`Expected variable name after $. Got: ${this.peek()?.lexeme ?? 'EOF'}`);\r\n }\r\n const name = this.advance().lexeme;\r\n return new XPathVariableReference(name);\r\n }\r\n\r\n return super.parsePrimaryExpr();\r\n }\r\n\r\n private parseInstanceOfExpr(): XPathExpression {\r\n let expr = this.parseTreatExpr();\r\n\r\n if (this.checkReservedWord('instance')) {\r\n this.advance();\r\n this.consumeReservedWord('of', \"Expected 'of' after 'instance'\");\r\n const sequenceType = this.parseSequenceType();\r\n expr = new XPathInstanceOfExpression(expr, sequenceType);\r\n }\r\n\r\n return expr;\r\n }\r\n\r\n private parseTreatExpr(): XPathExpression {\r\n let expr = this.parseCastableExpr();\r\n\r\n if (this.checkReservedWord('treat')) {\r\n this.advance();\r\n this.consumeReservedWord('as', \"Expected 'as' after 'treat'\");\r\n const sequenceType = this.parseSequenceType();\r\n expr = new XPathTreatExpression(expr, sequenceType);\r\n }\r\n\r\n return expr;\r\n }\r\n\r\n private parseCastableExpr(): XPathExpression {\r\n let expr = this.parsePathExpr();\r\n\r\n if (this.checkReservedWord('castable')) {\r\n this.advance();\r\n this.consumeReservedWord('as', \"Expected 'as' after 'castable'\");\r\n const sequenceType = this.parseSequenceType();\r\n expr = new XPathCastableExpression(expr, sequenceType);\r\n }\r\n\r\n return expr;\r\n }\r\n\r\n private parseIfExpr(): XPathExpression {\r\n this.advance();\r\n this.consume('OPEN_PAREN', \"Expected '(' after 'if'\");\r\n const testExpr = this.parseExpr();\r\n this.consume('CLOSE_PAREN', \"Expected ')' after if test expression\");\r\n\r\n if (!(this.check('RESERVED_WORD') && this.peek().lexeme === 'then')) {\r\n throw new Error(\"Expected 'then' in conditional expression\");\r\n }\r\n this.advance();\r\n const thenExpr = this.parseExpr();\r\n\r\n if (!(this.check('RESERVED_WORD') && this.peek().lexeme === 'else')) {\r\n throw new Error(\"Expected 'else' in conditional expression\");\r\n }\r\n this.advance();\r\n const elseExpr = this.parseExpr();\r\n\r\n return new XPathConditionalExpression(testExpr, thenExpr, elseExpr);\r\n }\r\n\r\n private parseQuantifiedExpr(): XPathExpression {\r\n const quantifier = this.consumeReservedWordOneOf(\r\n ['some', 'every'],\r\n \"Expected 'some' or 'every' at start of quantified expression\"\r\n ) as 'some' | 'every';\r\n\r\n const bindings: { variable: string; expression: XPathExpression }[] = [];\r\n do {\r\n bindings.push(this.parseForBinding());\r\n } while (this.match('COMMA'));\r\n\r\n this.consumeReservedWord(\r\n 'satisfies',\r\n \"Expected 'satisfies' after quantified expression bindings\"\r\n );\r\n const satisfiesExpr = this.parseExpr();\r\n\r\n return new XPathQuantifiedExpression(quantifier, bindings, satisfiesExpr);\r\n }\r\n\r\n private parseForExpr(): XPathExpression {\r\n this.consumeReservedWord('for', \"Expected 'for' at start of for expression\");\r\n\r\n const bindings: { variable: string; expression: XPathExpression }[] = [];\r\n do {\r\n bindings.push(this.parseForBinding());\r\n } while (this.match('COMMA'));\r\n\r\n this.consumeReservedWord('return', \"Expected 'return' in for expression\");\r\n const returnExpr = this.parseExpr();\r\n\r\n return new XPathForExpression(bindings, returnExpr);\r\n }\r\n\r\n private parseForBinding(): { variable: string; expression: XPathExpression } {\r\n this.consume('DOLLAR', \"Expected '$' after 'for'\");\r\n const name = this.consume('IDENTIFIER', 'Expected variable name in for binding').lexeme;\r\n this.consumeReservedWord('in', \"Expected 'in' after variable name in for clause\");\r\n const expression = this.parseExpr();\r\n return { variable: name, expression };\r\n }\r\n\r\n protected parseSequenceType(): SequenceType {\r\n if (this.checkName('empty-sequence')) {\r\n this.advance();\r\n this.consume('OPEN_PAREN', \"Expected '(' after empty-sequence\");\r\n this.consume('CLOSE_PAREN', \"Expected ')' after empty-sequence\");\r\n return createEmptySequenceType();\r\n }\r\n\r\n if (this.checkName('item')) {\r\n this.advance();\r\n this.consume('OPEN_PAREN', \"Expected '(' after item\");\r\n this.consume('CLOSE_PAREN', \"Expected ')' after item()\");\r\n const occurrence = this.parseOccurrenceIndicator();\r\n return createItemSequenceType(ITEM_TYPE, occurrence);\r\n }\r\n\r\n // map(key-type, value-type) - XPath 3.1 support in 2.0 parser\r\n if (this.checkName('map')) {\r\n this.advance();\r\n this.consume('OPEN_PAREN', \"Expected '(' after map\");\r\n\r\n let keyType: SequenceType | null = null;\r\n let valueType: SequenceType | null = null;\r\n\r\n if (this.match('ASTERISK')) {\r\n // map(*)\r\n this.consume('CLOSE_PAREN', \"Expected ')' after map(*)\");\r\n } else {\r\n // map(key-type, value-type)\r\n keyType = this.parseSequenceType();\r\n this.consume('COMMA', \"Expected ',' after key type in map()\");\r\n valueType = this.parseSequenceType();\r\n this.consume('CLOSE_PAREN', \"Expected ')' after map type\");\r\n }\r\n\r\n const occurrence = this.parseOccurrenceIndicator();\r\n\r\n // Create typed map test\r\n const { createTypedMapTest } = require('../types/typed-collection-types');\r\n const mapItemType = createTypedMapTest(keyType, valueType);\r\n return createItemSequenceType(mapItemType, occurrence);\r\n }\r\n\r\n // array(member-type) - XPath 3.1 support in 2.0 parser\r\n if (this.checkName('array')) {\r\n this.advance();\r\n this.consume('OPEN_PAREN', \"Expected '(' after array\");\r\n\r\n let memberType: SequenceType | null = null;\r\n\r\n if (this.match('ASTERISK')) {\r\n // array(*)\r\n this.consume('CLOSE_PAREN', \"Expected ')' after array(*)\");\r\n } else {\r\n // array(member-type)\r\n memberType = this.parseSequenceType();\r\n this.consume('CLOSE_PAREN', \"Expected ')' after array type\");\r\n }\r\n\r\n const occurrence = this.parseOccurrenceIndicator();\r\n\r\n // Create typed array test\r\n const { createTypedArrayTest } = require('../types/typed-collection-types');\r\n const arrayItemType = createTypedArrayTest(memberType);\r\n return createItemSequenceType(arrayItemType, occurrence);\r\n }\r\n\r\n const qname = this.parseQName();\r\n const occurrence = this.parseOccurrenceIndicator();\r\n\r\n const localName = this.stripPrefix(qname);\r\n const atomicType = getAtomicType(localName);\r\n if (!atomicType) {\r\n throw new Error(`Unknown atomic type: ${qname}`);\r\n }\r\n\r\n return createAtomicSequenceType(atomicType, occurrence);\r\n }\r\n\r\n /**\r\n * Override parseAdditiveExpr to insert range expression (to) parsing.\r\n * Precedence: AdditiveExpr -> RangeExpr -> MultiplicativeExpr\r\n */\r\n protected parseAdditiveExpr(): XPathExpression {\r\n let left = this.parseRangeExpr();\r\n\r\n while (this.match('PLUS', 'MINUS')) {\r\n const operator = this.previous().lexeme as '+' | '-';\r\n const right = this.parseRangeExpr();\r\n left = new (require('../expressions').XPathArithmeticExpression)(left, right, operator);\r\n }\r\n\r\n return left;\r\n }\r\n\r\n /**\r\n * Parse range expression (to).\r\n * Syntax: expr to expr\r\n * Returns a sequence of consecutive integers from start to end.\r\n */\r\n protected parseRangeExpr(): XPathExpression {\r\n let left = this.parseMultiplicativeExpr();\r\n\r\n if (this.checkReservedWord('to')) {\r\n this.advance();\r\n const right = this.parseMultiplicativeExpr();\r\n left = new RangeExpression(left, right);\r\n }\r\n\r\n return left;\r\n }\r\n\r\n private parseOccurrenceIndicator(): OccurrenceIndicator {\r\n if (this.match('QUESTION')) return OccurrenceIndicator.ZERO_OR_ONE;\r\n if (this.match('ASTERISK')) return OccurrenceIndicator.ZERO_OR_MORE;\r\n if (this.match('PLUS')) return OccurrenceIndicator.ONE_OR_MORE;\r\n return OccurrenceIndicator.EXACTLY_ONE;\r\n }\r\n\r\n private parseQName(): string {\r\n const first = this.consumeNameToken('Expected type name in SequenceType');\r\n if (this.match('COLON')) {\r\n const local = this.consumeNameToken(\r\n 'Expected local name after : in SequenceType'\r\n ).lexeme;\r\n return `${first.lexeme}:${local}`;\r\n }\r\n return first.lexeme;\r\n }\r\n\r\n private stripPrefix(qname: string): string {\r\n const parts = qname.split(':');\r\n return parts.length === 2 ? parts[1] : parts[0];\r\n }\r\n\r\n private consumeNameToken(message: string): XPathToken {\r\n if (this.isNameToken()) {\r\n return this.advance();\r\n }\r\n throw new Error(`${message}. Got: ${this.peek()?.lexeme ?? 'EOF'}`);\r\n }\r\n\r\n private isNameToken(): boolean {\r\n if (this.isAtEnd()) return false;\r\n const type = this.peek().type;\r\n return (\r\n type === 'IDENTIFIER' ||\r\n type === 'FUNCTION' ||\r\n type === 'NODE_TYPE' ||\r\n type === 'OPERATOR' ||\r\n type === 'LOCATION' ||\r\n type === 'RESERVED_WORD'\r\n );\r\n }\r\n\r\n private checkName(name: string): boolean {\r\n return this.isNameToken() && this.peek().lexeme === name;\r\n }\r\n\r\n private checkReservedWord(word: string): boolean {\r\n return this.check('RESERVED_WORD') && this.peek().lexeme === word;\r\n }\r\n\r\n private consumeReservedWord(word: string, message: string): void {\r\n if (this.checkReservedWord(word)) {\r\n this.advance();\r\n return;\r\n }\r\n throw new Error(`${message}. Got: ${this.peek()?.lexeme ?? 'EOF'}`);\r\n }\r\n\r\n private consumeReservedWordOneOf(words: string[], message: string): string {\r\n for (const word of words) {\r\n if (this.checkReservedWord(word)) {\r\n this.advance();\r\n return word;\r\n }\r\n }\r\n throw new Error(`${message}. Got: ${this.peek()?.lexeme ?? 'EOF'}`);\r\n }\r\n}\r\n","/**\r\n * XPath 3.0 Parser\r\n *\r\n * Extends XPath20Parser to add support for XPath 3.0 features:\r\n * - Let expressions: let $x := expr, $y := expr return expr\r\n * - Simple map operator: expr ! expr\r\n * - String concatenation operator: expr || expr\r\n * - Arrow operator: expr => func(args)\r\n * - Named function references: fn:name#arity\r\n * - Inline functions: function($x) { $x + 1 }\r\n * - EQNames with URI literals: Q{uri}local\r\n *\r\n * Reference: https://www.w3.org/TR/xpath-30/\r\n */\r\n\r\nimport {\r\n XPathExpression,\r\n XPathFunctionCall,\r\n XPathNumberLiteral,\r\n XPathVariableReference,\r\n CommaExpression,\r\n} from '../expressions';\r\nimport { XPathLetExpression, XPathLetBinding } from '../expressions/let-expression';\r\nimport { XPathSimpleMapExpression } from '../expressions/simple-map-expression';\r\nimport { XPathStringConcatExpression } from '../expressions/string-concat-expression';\r\nimport { StringTemplateExpression, parseStringTemplate } from '../expressions/string-template-expression';\r\nimport { XPathLexer } from '../lexer/lexer';\r\nimport { XPathArrowExpression } from '../expressions/arrow-expression';\r\nimport { XPathNamedFunctionRef } from '../expressions/named-function-ref-expression';\r\nimport {\r\n XPathInlineFunctionExpression,\r\n InlineFunctionParameter,\r\n} from '../expressions/inline-function-expression';\r\nimport { XPathDynamicFunctionCall } from '../expressions/dynamic-function-call-expression';\r\nimport { XPathBaseParserOptions } from '../xslt-extensions';\r\nimport { XPath20Parser } from './parser-20';\r\nimport {\r\n SequenceType,\r\n OccurrenceIndicator,\r\n createAtomicSequenceType,\r\n createItemSequenceType,\r\n ITEM_TYPE,\r\n getAtomicType,\r\n createEmptySequenceType,\r\n} from '../types';\r\nimport { grammarViolation } from '../errors';\r\n\r\nexport class XPath30Parser extends XPath20Parser {\r\n constructor(options?: XPathBaseParserOptions) {\r\n // Default to XPath 3.0 if no version specified\r\n const opts = options ? { ...options } : {};\r\n if (!opts.version) {\r\n opts.version = '3.0';\r\n }\r\n super(opts);\r\n this.ensureVersionSupport(['3.0', '3.1'], '3.0');\r\n }\r\n\r\n /**\r\n * Override parseExpr to handle:\r\n * 1. Let expressions: let $x := expr return expr\r\n * 2. Sequence construction: expr, expr, expr (comma operator)\r\n */\r\n protected parseExpr(): XPathExpression {\r\n // Let expression: let $x := expr, $y := expr return expr\r\n if (this.checkReservedWordInternal('let')) {\r\n return this.parseLetExpr();\r\n }\r\n\r\n // Parse the first expression\r\n const first = this.parseExprSingle();\r\n\r\n // Check for comma (sequence construction)\r\n if (this.check('COMMA')) {\r\n const operands: XPathExpression[] = [first];\r\n while (this.match('COMMA')) {\r\n operands.push(this.parseExprSingle());\r\n }\r\n return new CommaExpression(operands);\r\n }\r\n\r\n return first;\r\n }\r\n\r\n /**\r\n * Parse a single expression (not comma-separated).\r\n */\r\n protected parseExprSingle(): XPathExpression {\r\n // ExprSingle allows FLWOR expressions like let/for without top-level comma sequences\r\n if (this.checkReservedWordInternal('let')) {\r\n return this.parseLetExpr();\r\n }\r\n\r\n return super.parseExpr();\r\n }\r\n\r\n /**\r\n * Override parseAdditiveExpr to insert string concatenation (||) parsing.\r\n * Precedence: || is between comparison and additive\r\n */\r\n protected parseAdditiveExpr(): XPathExpression {\r\n let left = this.parseStringConcatExpr();\r\n\r\n while (this.match('PLUS', 'MINUS')) {\r\n const operator = this.previous().lexeme as '+' | '-';\r\n const right = this.parseStringConcatExpr();\r\n left = new (require('../expressions').XPathArithmeticExpression)(left, right, operator);\r\n }\r\n\r\n return left;\r\n }\r\n\r\n /**\r\n * Parse string concatenation expression (||).\r\n * Syntax: expr || expr\r\n */\r\n private parseStringConcatExpr(): XPathExpression {\r\n let left = this.parseRangeExpr();\r\n\r\n while (this.match('CONCAT')) {\r\n const right = this.parseRangeExpr();\r\n left = new XPathStringConcatExpression(left, right);\r\n }\r\n\r\n return left;\r\n }\r\n\r\n /**\r\n * Override parseUnionExpr to insert simple map operator (!) parsing.\r\n * Precedence: ! is just above union (|)\r\n */\r\n protected parseUnionExpr(): XPathExpression {\r\n let left = this.parseSimpleMapExpr();\r\n\r\n while (this.match('PIPE')) {\r\n const right = this.parseSimpleMapExpr();\r\n left = new (require('../expressions').XPathUnionExpression)(left, right);\r\n }\r\n\r\n return left;\r\n }\r\n\r\n /**\r\n * Parse simple map expression (!).\r\n * Syntax: expr ! expr\r\n * Evaluates left expression, then for each item evaluates right with that item as context.\r\n */\r\n private parseSimpleMapExpr(): XPathExpression {\r\n // First parse what would normally be the instance-of level (from XPath 2.0)\r\n let left = this.parseInstanceOfExprInternal();\r\n\r\n while (this.match('SIMPLE_MAP')) {\r\n const right = this.parseInstanceOfExprInternal();\r\n left = new XPathSimpleMapExpression(left, right);\r\n }\r\n\r\n return left;\r\n }\r\n\r\n /**\r\n * Internal method to parse instance-of expression level.\r\n * This replaces the protected method from XPath20Parser for our precedence chain.\r\n */\r\n private parseInstanceOfExprInternal(): XPathExpression {\r\n let expr = this.parseTreatExprInternal();\r\n\r\n if (this.checkReservedWordInternal('instance')) {\r\n this.advance();\r\n this.consumeReservedWordInternal('of', \"Expected 'of' after 'instance'\");\r\n const sequenceType = this.parseSequenceTypeInternal();\r\n expr = new (require('../expressions').XPathInstanceOfExpression)(expr, sequenceType);\r\n }\r\n\r\n return expr;\r\n }\r\n\r\n /**\r\n * Internal method to parse treat expression level.\r\n */\r\n private parseTreatExprInternal(): XPathExpression {\r\n let expr = this.parseCastableExprInternal();\r\n\r\n if (this.checkReservedWordInternal('treat')) {\r\n this.advance();\r\n this.consumeReservedWordInternal('as', \"Expected 'as' after 'treat'\");\r\n const sequenceType = this.parseSequenceTypeInternal();\r\n expr = new (require('../expressions').XPathTreatExpression)(expr, sequenceType);\r\n }\r\n\r\n return expr;\r\n }\r\n\r\n /**\r\n * Internal method to parse castable expression level.\r\n */\r\n private parseCastableExprInternal(): XPathExpression {\r\n let expr = this.parseArrowExpr();\r\n\r\n if (this.checkReservedWordInternal('castable')) {\r\n this.advance();\r\n this.consumeReservedWordInternal('as', \"Expected 'as' after 'castable'\");\r\n const sequenceType = this.parseSequenceTypeInternal();\r\n expr = new (require('../expressions').XPathCastableExpression)(expr, sequenceType);\r\n }\r\n\r\n return expr;\r\n }\r\n\r\n /**\r\n * Parse arrow expression (=>).\r\n * Syntax: expr => func(args) => func2(args)\r\n * $x => f($y) is equivalent to f($x, $y)\r\n */\r\n private parseArrowExpr(): XPathExpression {\r\n let left = this.parsePathExpr();\r\n\r\n while (this.match('FAT_ARROW')) {\r\n // Parse function name or variable reference\r\n let funcExpr: XPathExpression;\r\n let args: XPathExpression[] = [];\r\n\r\n if (this.check('DOLLAR')) {\r\n // Variable reference to a function item: $f => ...\r\n this.advance();\r\n const varName = this.consume('IDENTIFIER', 'Expected variable name after $').lexeme;\r\n funcExpr = new XPathVariableReference(varName);\r\n\r\n // Arguments in parentheses (use parseExprSingle to avoid comma being treated as sequence)\r\n this.consume(\r\n 'OPEN_PAREN',\r\n \"Expected '(' after function variable in arrow expression\"\r\n );\r\n if (!this.check('CLOSE_PAREN')) {\r\n do {\r\n args.push(this.parseExprSingle());\r\n } while (this.match('COMMA'));\r\n }\r\n this.consume('CLOSE_PAREN', \"Expected ')' after arrow expression arguments\");\r\n\r\n // Dynamic function call with left as first argument\r\n left = new XPathDynamicFunctionCall(funcExpr, [left, ...args]);\r\n } else {\r\n // Named function call\r\n let name = this.advance().lexeme;\r\n\r\n // Check for QName (prefix:localname)\r\n if (this.match('COLON')) {\r\n const local = this.advance();\r\n name = `${name}:${local.lexeme}`;\r\n }\r\n\r\n // Arguments in parentheses (use parseExprSingle to avoid comma being treated as sequence)\r\n this.consume('OPEN_PAREN', \"Expected '(' after function name in arrow expression\");\r\n if (!this.check('CLOSE_PAREN')) {\r\n do {\r\n args.push(this.parseExprSingle());\r\n } while (this.match('COMMA'));\r\n }\r\n this.consume('CLOSE_PAREN', \"Expected ')' after arrow expression arguments\");\r\n\r\n // Create function call with left expression as first argument\r\n left = new XPathArrowExpression(left, name, args);\r\n }\r\n }\r\n\r\n return left;\r\n }\r\n\r\n /**\r\n * Override parseFunctionCall to use parseExprSingle for arguments.\r\n *\r\n * In XPath 3.0, function arguments are ExprSingle, not Expr.\r\n * This means commas in arguments don't create sequences at the function level.\r\n * For example: concat(\"Hello \", $name) should parse as two arguments,\r\n * not one argument that is a sequence of two items.\r\n */\r\n protected parseFunctionCall(): XPathExpression {\r\n let name = this.advance().lexeme;\r\n\r\n if (this.match('COLON')) {\r\n const local = this.advance();\r\n name = `${name}:${local.lexeme}`;\r\n }\r\n\r\n this.consume('OPEN_PAREN', \"Expected '(' after function name\");\r\n\r\n const args: XPathExpression[] = [];\r\n\r\n if (!this.check('CLOSE_PAREN')) {\r\n do {\r\n // Use parseExprSingle to avoid treating comma as sequence operator\r\n args.push(this.parseExprSingle());\r\n } while (this.match('COMMA'));\r\n }\r\n\r\n this.consume('CLOSE_PAREN', \"Expected ')' after function arguments\");\r\n\r\n return new XPathFunctionCall(name, args);\r\n }\r\n\r\n /**\r\n * Override parsePrimaryExpr to handle:\r\n * - Variable references with any name (including function names like 'name')\r\n * - Named function references (fn:name#arity)\r\n * - Inline functions (function($x) { expr })\r\n * - String templates (`Hello {$name}!`)\r\n */\r\n protected parsePrimaryExpr(): XPathExpression {\r\n // String template: `Hello {$name}!` (XPath 3.0+)\r\n if (this.check('STRING_TEMPLATE')) {\r\n const template = this.advance().lexeme;\r\n return this.parseStringTemplateFromLexeme(template);\r\n }\r\n\r\n // Variable reference: $name (allow any name token, not just IDENTIFIER)\r\n if (this.match('DOLLAR')) {\r\n const nameToken = this.consumeNameTokenInternal('Expected variable name after $');\r\n return new XPathVariableReference(nameToken.lexeme);\r\n }\r\n\r\n // Inline function: function($x, $y) { expr }\r\n if (this.checkReservedWordInternal('function')) {\r\n return this.parseInlineFunction();\r\n }\r\n\r\n // Check for named function reference (name#arity)\r\n if (this.isFunctionRefStart()) {\r\n return this.parseNamedFunctionRef();\r\n }\r\n\r\n return super.parsePrimaryExpr();\r\n }\r\n\r\n /**\r\n * Override isStepStart to exclude function references.\r\n * In XPath 3.0, name#arity is a function reference, not a location step.\r\n */\r\n protected isStepStart(): boolean {\r\n // If it looks like a function reference, it's not a step\r\n if (this.isFunctionRefStart()) {\r\n return false;\r\n }\r\n\r\n return super.isStepStart();\r\n }\r\n\r\n /**\r\n * Override parseFilterExpr to handle dynamic function calls.\r\n * In XPath 3.0, any primary expression followed by '(' is a dynamic function call.\r\n * Syntax: $func(args), (inline-function)(args), etc.\r\n */\r\n protected parseFilterExpr(): XPathExpression {\r\n let expr = this.parsePrimaryExpr();\r\n\r\n // Check for dynamic function call: expr(args)\r\n // This handles cases like $func(args) where $func is a function item\r\n // Note: parsePrimaryExpr already handles normal function calls (name(...))\r\n // so if we see '(' here, it must be a dynamic call\r\n if (this.check('OPEN_PAREN')) {\r\n // It's a dynamic function call\r\n this.advance(); // consume '('\r\n\r\n const args: XPathExpression[] = [];\r\n if (!this.check('CLOSE_PAREN')) {\r\n do {\r\n args.push(this.parseExprSingle());\r\n } while (this.match('COMMA'));\r\n }\r\n\r\n this.consume('CLOSE_PAREN', \"Expected ')' after function arguments\");\r\n expr = new XPathDynamicFunctionCall(expr, args);\r\n }\r\n\r\n // Collect all predicates\r\n const predicates: XPathExpression[] = [];\r\n while (this.check('OPEN_SQUARE_BRACKET')) {\r\n predicates.push(...this.parsePredicates());\r\n }\r\n\r\n // If there are predicates, wrap in filter expression\r\n if (predicates.length > 0) {\r\n const XPathFilterExpression = require('../expressions').XPathFilterExpression;\r\n return new XPathFilterExpression(expr, predicates);\r\n }\r\n\r\n return expr;\r\n }\r\n\r\n /**\r\n * Check if this looks like a function reference (name#arity).\r\n * Handles names with hyphens like upper-case#1 or prefix:upper-case#1\r\n * Also handles EQNames like Q{uri}name#1\r\n */\r\n private isFunctionRefStart(): boolean {\r\n if (this.isAtEnd()) return false;\r\n\r\n const token = this.peek();\r\n\r\n // EQName followed by # is a function reference\r\n if (token.type === 'EQNAME') {\r\n const next = this.peekNext();\r\n return next?.type === 'HASH';\r\n }\r\n\r\n // Check for identifier/function/operator/location that could start a QName\r\n if (\r\n token.type === 'IDENTIFIER' ||\r\n token.type === 'FUNCTION' ||\r\n token.type === 'OPERATOR' ||\r\n token.type === 'LOCATION'\r\n ) {\r\n // Scan ahead to find a HASH token, allowing for:\r\n // name#N\r\n // prefix:name#N\r\n // upper-case#N (hyphenated names)\r\n // prefix:upper-case#N (hyphenated local names)\r\n\r\n let lookAhead = 1;\r\n let foundHash = false;\r\n\r\n while (lookAhead < this.tokens.length - this.current) {\r\n const tok = this.tokens[this.current + lookAhead];\r\n\r\n if (!tok) break;\r\n\r\n // Stop if we hit HASH - that's what we're looking for\r\n if (tok.type === 'HASH') {\r\n foundHash = true;\r\n break;\r\n }\r\n\r\n // Allow: hyphens, colons, and name tokens (IDENTIFIER, FUNCTION, OPERATOR, LOCATION, NODE_TYPE)\r\n const isValidQNameChar =\r\n tok.type === 'MINUS' ||\r\n tok.type === 'COLON' ||\r\n tok.type === 'IDENTIFIER' ||\r\n tok.type === 'FUNCTION' ||\r\n tok.type === 'OPERATOR' ||\r\n tok.type === 'LOCATION' ||\r\n tok.type === 'NODE_TYPE';\r\n\r\n if (isValidQNameChar) {\r\n lookAhead++;\r\n } else {\r\n // Stop if we hit something else\r\n break;\r\n }\r\n }\r\n\r\n return foundHash;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Parse named function reference: fn:name#arity or upper-case#arity\r\n * Handles hyphenated names and QNames.\r\n */\r\n private parseNamedFunctionRef(): XPathExpression {\r\n let name = this.advance().lexeme;\r\n\r\n // Build the full QName, handling hyphens and colons\r\n while (!this.isAtEnd() && !this.check('HASH')) {\r\n if (this.match('MINUS') || this.match('COLON')) {\r\n // match() has already advanced past the operator\r\n const op = this.previous().lexeme;\r\n // Peek at the next identifier and include it\r\n const nextToken = this.peek();\r\n if (\r\n nextToken &&\r\n (nextToken.type === 'IDENTIFIER' ||\r\n nextToken.type === 'FUNCTION' ||\r\n nextToken.type === 'OPERATOR' ||\r\n nextToken.type === 'LOCATION' ||\r\n nextToken.type === 'NODE_TYPE')\r\n ) {\r\n this.advance();\r\n name = `${name}${op}${nextToken.lexeme}`;\r\n } else {\r\n throw grammarViolation(`Expected name after '${op}' in function reference`);\r\n }\r\n } else {\r\n break;\r\n }\r\n }\r\n\r\n // Consume #\r\n this.consume('HASH', \"Expected '#' in function reference\");\r\n\r\n // Parse arity (must be a number)\r\n const arityToken = this.consume('NUMBER', \"Expected arity number after '#'\");\r\n const arity = parseInt(arityToken.lexeme, 10);\r\n\r\n if (isNaN(arity) || arity < 0) {\r\n throw grammarViolation(`Invalid function arity: ${arityToken.lexeme}`);\r\n }\r\n\r\n return new XPathNamedFunctionRef(name, arity);\r\n }\r\n\r\n /**\r\n * Parse inline function: function($x as xs:integer, $y) as xs:integer { $x + $y }\r\n */\r\n private parseInlineFunction(): XPathExpression {\r\n this.advance(); // consume 'function'\r\n this.consume('OPEN_PAREN', \"Expected '(' after 'function'\");\r\n\r\n // Parse parameters\r\n const params: InlineFunctionParameter[] = [];\r\n if (!this.check('CLOSE_PAREN')) {\r\n do {\r\n this.consume('DOLLAR', \"Expected '$' before parameter name\");\r\n const paramName = this.consume('IDENTIFIER', 'Expected parameter name').lexeme;\r\n\r\n // Optional type annotation\r\n let paramType: SequenceType | undefined;\r\n if (this.checkReservedWordInternal('as')) {\r\n this.advance();\r\n paramType = this.parseSequenceTypeInternal();\r\n }\r\n\r\n params.push({ name: paramName, type: paramType });\r\n } while (this.match('COMMA'));\r\n }\r\n this.consume('CLOSE_PAREN', \"Expected ')' after function parameters\");\r\n\r\n // Optional return type\r\n let returnType: SequenceType | undefined;\r\n if (this.checkReservedWordInternal('as')) {\r\n this.advance();\r\n returnType = this.parseSequenceTypeInternal();\r\n }\r\n\r\n // Function body in curly braces\r\n this.consume('OPEN_CURLY_BRACKET', \"Expected '{' before function body\");\r\n const body = this.parseExpr();\r\n this.consume('CLOSE_CURLY_BRACKET', \"Expected '}' after function body\");\r\n\r\n return new XPathInlineFunctionExpression(params, body, returnType);\r\n }\r\n\r\n /**\r\n * Parse let expression: let $x := expr, $y := expr return expr\r\n */\r\n private parseLetExpr(): XPathExpression {\r\n this.consumeReservedWordInternal('let', \"Expected 'let'\");\r\n\r\n const bindings: XPathLetBinding[] = [];\r\n do {\r\n bindings.push(this.parseLetBinding());\r\n } while (this.match('COMMA'));\r\n\r\n this.consumeReservedWordInternal('return', \"Expected 'return' in let expression\");\r\n const returnExpr = this.parseExpr();\r\n\r\n return new XPathLetExpression(bindings, returnExpr);\r\n }\r\n\r\n /**\r\n * Parse a single let binding: $x := expr\r\n */\r\n private parseLetBinding(): XPathLetBinding {\r\n this.consume('DOLLAR', \"Expected '$' before variable name in let binding\");\r\n // Variable name can be any name token (including function names like 'name', 'string', etc.)\r\n const nameToken = this.consumeNameTokenInternal('Expected variable name in let binding');\r\n const name = nameToken.lexeme;\r\n\r\n // Optional type annotation\r\n let type: SequenceType | undefined;\r\n if (this.checkReservedWordInternal('as')) {\r\n this.advance();\r\n type = this.parseSequenceTypeInternal();\r\n }\r\n\r\n this.consume('ASSIGNMENT', \"Expected ':=' after variable name in let binding\");\r\n // Use parseExprSingle to avoid consuming commas that separate bindings\r\n const expression = this.parseExprSingle();\r\n\r\n return { variable: name, expression, type };\r\n }\r\n\r\n // Helper methods\r\n\r\n private checkReservedWordInternal(word: string): boolean {\r\n return this.check('RESERVED_WORD') && this.peek().lexeme === word;\r\n }\r\n\r\n private consumeReservedWordInternal(word: string, message: string): void {\r\n if (this.checkReservedWordInternal(word)) {\r\n this.advance();\r\n return;\r\n }\r\n throw grammarViolation(`${message}. Got: ${this.peek()?.lexeme ?? 'EOF'}`);\r\n }\r\n\r\n /**\r\n * Parse sequence type for type annotations.\r\n */\r\n protected parseSequenceTypeInternal(): SequenceType {\r\n // empty-sequence()\r\n if (this.checkNameInternal('empty-sequence')) {\r\n this.advance();\r\n this.consume('OPEN_PAREN', \"Expected '(' after empty-sequence\");\r\n this.consume('CLOSE_PAREN', \"Expected ')' after empty-sequence\");\r\n return createEmptySequenceType();\r\n }\r\n\r\n // item()\r\n if (this.checkNameInternal('item')) {\r\n this.advance();\r\n this.consume('OPEN_PAREN', \"Expected '(' after item\");\r\n this.consume('CLOSE_PAREN', \"Expected ')' after item()\");\r\n const occurrence = this.parseOccurrenceIndicatorInternal();\r\n return createItemSequenceType(ITEM_TYPE, occurrence);\r\n }\r\n\r\n // map(key-type, value-type) - XPath 3.1\r\n if (this.checkNameInternal('map')) {\r\n this.advance();\r\n this.consume('OPEN_PAREN', \"Expected '(' after map\");\r\n\r\n // Check for map(*) or map(key-type, value-type)\r\n let keyType: SequenceType | null = null;\r\n let valueType: SequenceType | null = null;\r\n\r\n if (this.match('ASTERISK')) {\r\n // map(*) - any map\r\n this.consume('CLOSE_PAREN', \"Expected ')' after map(*)\");\r\n } else {\r\n // map(key-type, value-type)\r\n keyType = this.parseSequenceTypeInternal();\r\n this.consume('COMMA', \"Expected ',' after key type in map()\");\r\n valueType = this.parseSequenceTypeInternal();\r\n this.consume('CLOSE_PAREN', \"Expected ')' after map type\");\r\n }\r\n\r\n const occurrence = this.parseOccurrenceIndicatorInternal();\r\n\r\n // Create typed map test\r\n const { createTypedMapTest } = require('../types/typed-collection-types');\r\n const mapItemType = createTypedMapTest(keyType, valueType);\r\n return createItemSequenceType(mapItemType, occurrence);\r\n }\r\n\r\n // array(member-type) - XPath 3.1\r\n if (this.checkNameInternal('array')) {\r\n this.advance();\r\n this.consume('OPEN_PAREN', \"Expected '(' after array\");\r\n\r\n let memberType: SequenceType | null = null;\r\n\r\n if (this.match('ASTERISK')) {\r\n // array(*) - any array\r\n this.consume('CLOSE_PAREN', \"Expected ')' after array(*)\");\r\n } else {\r\n // array(member-type)\r\n memberType = this.parseSequenceTypeInternal();\r\n this.consume('CLOSE_PAREN', \"Expected ')' after array type\");\r\n }\r\n\r\n const occurrence = this.parseOccurrenceIndicatorInternal();\r\n\r\n // Create typed array test\r\n const { createTypedArrayTest } = require('../types/typed-collection-types');\r\n const arrayItemType = createTypedArrayTest(memberType);\r\n return createItemSequenceType(arrayItemType, occurrence);\r\n }\r\n\r\n // function(...) type - simplified handling\r\n if (this.checkReservedWordInternal('function')) {\r\n this.advance();\r\n this.consume('OPEN_PAREN', \"Expected '(' after function\");\r\n\r\n let parameterTypes: SequenceType[] | null = null;\r\n\r\n if (this.match('ASTERISK')) {\r\n // function(*) wildcard\r\n this.consume('CLOSE_PAREN', \"Expected ')' after function(*)\");\r\n } else if (this.check('CLOSE_PAREN')) {\r\n // function() with no parameters\r\n parameterTypes = [];\r\n this.advance();\r\n } else {\r\n // Parse parameter type list: function(xs:string, xs:integer)\r\n parameterTypes = [];\r\n do {\r\n parameterTypes.push(this.parseSequenceTypeInternal());\r\n } while (this.match('COMMA'));\r\n this.consume('CLOSE_PAREN', \"Expected ')' after function parameter types\");\r\n }\r\n\r\n // Optional return type: function(...) as returnType\r\n let returnType: SequenceType | null = null;\r\n if (this.checkReservedWordInternal('as')) {\r\n this.advance();\r\n returnType = this.parseSequenceTypeInternal();\r\n }\r\n\r\n const occurrence = this.parseOccurrenceIndicatorInternal();\r\n\r\n const { createFunctionTest } = require('../types/function-type');\r\n const functionItemType = createFunctionTest(parameterTypes, returnType, {\r\n isWildcard: parameterTypes === null && returnType === null,\r\n });\r\n return createItemSequenceType(functionItemType, occurrence);\r\n }\r\n\r\n // Atomic type name\r\n const qname = this.parseQNameInternal();\r\n const occurrence = this.parseOccurrenceIndicatorInternal();\r\n\r\n const localName = this.stripPrefixInternal(qname);\r\n const atomicType = getAtomicType(localName);\r\n if (!atomicType) {\r\n throw grammarViolation(`Unknown atomic type: ${qname}`);\r\n }\r\n\r\n return createAtomicSequenceType(atomicType, occurrence);\r\n }\r\n\r\n private parseOccurrenceIndicatorInternal(): OccurrenceIndicator {\r\n if (this.match('QUESTION')) return OccurrenceIndicator.ZERO_OR_ONE;\r\n if (this.match('ASTERISK')) return OccurrenceIndicator.ZERO_OR_MORE;\r\n if (this.match('PLUS')) return OccurrenceIndicator.ONE_OR_MORE;\r\n return OccurrenceIndicator.EXACTLY_ONE;\r\n }\r\n\r\n private parseQNameInternal(): string {\r\n const first = this.consumeNameTokenInternal('Expected type name');\r\n if (this.match('COLON')) {\r\n const local = this.consumeNameTokenInternal('Expected local name after :').lexeme;\r\n return `${first.lexeme}:${local}`;\r\n }\r\n return first.lexeme;\r\n }\r\n\r\n private stripPrefixInternal(qname: string): string {\r\n const parts = qname.split(':');\r\n return parts.length === 2 ? parts[1] : parts[0];\r\n }\r\n\r\n private consumeNameTokenInternal(message: string) {\r\n if (this.isNameTokenInternal()) {\r\n return this.advance();\r\n }\r\n throw grammarViolation(`${message}. Got: ${this.peek()?.lexeme ?? 'EOF'}`);\r\n }\r\n\r\n private isNameTokenInternal(): boolean {\r\n if (this.isAtEnd()) return false;\r\n const type = this.peek().type;\r\n return (\r\n type === 'IDENTIFIER' ||\r\n type === 'FUNCTION' ||\r\n type === 'NODE_TYPE' ||\r\n type === 'OPERATOR' ||\r\n type === 'LOCATION' ||\r\n type === 'RESERVED_WORD'\r\n );\r\n }\r\n\r\n private checkNameInternal(name: string): boolean {\r\n return this.isNameTokenInternal() && this.peek().lexeme === name;\r\n }\r\n\r\n /**\r\n * Parse a string template from its lexeme and create a StringTemplateExpression.\r\n * The template string contains the raw content between backticks.\r\n */\r\n protected parseStringTemplateFromLexeme(template: string): XPathExpression {\r\n const rawParts = parseStringTemplate(template);\r\n const parts: (string | XPathExpression)[] = [];\r\n\r\n // Parse expression strings into actual expressions\r\n for (const part of rawParts) {\r\n if (typeof part === 'string') {\r\n parts.push(part);\r\n } else {\r\n // Handle empty or whitespace-only expressions\r\n const exprString = part.expressionString.trim();\r\n if (exprString.length === 0) {\r\n // Empty expression evaluates to empty string\r\n parts.push('');\r\n } else {\r\n // Parse the expression string using a fresh parser instance of the same type\r\n // Use XPath 3.1 version to support all features (array/map constructors, etc.)\r\n const lexer = new XPathLexer({ version: '3.1' });\r\n const tokens = lexer.scan(part.expressionString);\r\n // Create a parser of the same type as this instance\r\n const ParserClass = this.constructor as new () => XPath30Parser;\r\n const parser = new ParserClass();\r\n const expr = parser.parse(tokens);\r\n parts.push(expr);\r\n }\r\n }\r\n }\r\n\r\n return new StringTemplateExpression(parts);\r\n }\r\n}\r\n","/**\r\n * XPath 3.1 Parser\r\n *\r\n * Extends XPath30Parser to add support for XPath 3.1 features:\r\n * - Map constructors: map { key: value, ... }\r\n * - Array constructors: [item1, item2, ...] and array { expr }\r\n * - Lookup operator: ?key, ?*, ?(expr)\r\n * - Enhanced map and array functions\r\n * - JSON integration\r\n *\r\n * Reference: https://www.w3.org/TR/xpath-31/\r\n */\r\n\r\nimport { XPathExpression } from '../expressions';\r\nimport {\r\n XPathMapConstructorExpression,\r\n MapConstructorEntry,\r\n} from '../expressions/map-constructor-expression';\r\nimport {\r\n XPathSquareBracketArrayConstructor,\r\n XPathCurlyBraceArrayConstructor,\r\n} from '../expressions/array-constructor-expression';\r\nimport {\r\n XPathLookupExpression,\r\n KeySpecifier,\r\n KeySpecifierType,\r\n} from '../expressions/lookup-expression';\r\nimport { XPathVariableReference } from '../expressions';\r\nimport { XPathBaseParserOptions } from '../xslt-extensions';\r\nimport { XPath30Parser } from './parser-30';\r\n\r\nexport class XPath31Parser extends XPath30Parser {\r\n constructor(options?: XPathBaseParserOptions) {\r\n // Default to XPath 3.1 if no version specified\r\n const opts = options ? { ...options } : {};\r\n if (!opts.version) {\r\n opts.version = '3.1';\r\n }\r\n super(opts);\r\n this.ensureVersionSupport(['3.1'], '3.1');\r\n }\r\n\r\n /**\r\n * Override parsePrimaryExpr to handle:\r\n * - Map constructors (map { key: value, ... })\r\n * - Array constructors ([item, ...] and array { expr })\r\n * - All XPath 3.0 features from parent class\r\n */\r\n protected parsePrimaryExpr(): XPathExpression {\r\n // Map constructor: map { key: value, ... } (XPath 3.1)\r\n // Note: map:* function calls (e.g., map:size) are handled by parent class\r\n if (\r\n this.check('RESERVED_WORD') &&\r\n this.peek().lexeme === 'map' &&\r\n this.peekNext()?.type === 'OPEN_CURLY_BRACKET'\r\n ) {\r\n return this.parseMapConstructor();\r\n }\r\n\r\n // Array constructor: array { expr } (XPath 3.1)\r\n // Note: array:* function calls (e.g., array:size) are handled by parent class\r\n if (\r\n this.check('RESERVED_WORD') &&\r\n this.peek().lexeme === 'array' &&\r\n this.peekNext()?.type === 'OPEN_CURLY_BRACKET'\r\n ) {\r\n return this.parseCurlyArrayConstructor();\r\n }\r\n\r\n // Handle map:* and array:* function calls (e.g., map:size, array:size)\r\n // These look like reserved words followed by colon and function name\r\n if (\r\n this.check('RESERVED_WORD') &&\r\n (this.peek().lexeme === 'map' || this.peek().lexeme === 'array') &&\r\n this.peekNext()?.type === 'COLON'\r\n ) {\r\n return this.parseNamespacedFunctionCall();\r\n }\r\n\r\n // Square bracket array constructor: [item, item, ...] (XPath 3.1)\r\n if (this.check('OPEN_SQUARE_BRACKET')) {\r\n return this.parseSquareBracketArrayConstructor();\r\n }\r\n\r\n // Unary lookup operator: ?key (when context item is map/array) (XPath 3.1)\r\n if (this.check('QUESTION')) {\r\n return this.parseLookupExpr(null);\r\n }\r\n\r\n // Delegate to XPath 3.0 parser for other primary expressions\r\n return super.parsePrimaryExpr();\r\n }\r\n\r\n /**\r\n * Parse a namespaced function call like map:size or array:get.\r\n * These start with a reserved word (map/array) followed by colon.\r\n */\r\n private parseNamespacedFunctionCall(): XPathExpression {\r\n // Get the namespace prefix (map or array)\r\n const prefix = this.advance().lexeme;\r\n\r\n // Consume the colon\r\n this.consume('COLON', `Expected ':' after '${prefix}'`);\r\n\r\n // Get the function local name (can be IDENTIFIER or FUNCTION token)\r\n if (!this.check('IDENTIFIER') && !this.check('FUNCTION')) {\r\n throw new Error(`Expected function name after '${prefix}:'`);\r\n }\r\n const localName = this.advance().lexeme;\r\n\r\n // Build the full function name\r\n const fullName = `${prefix}:${localName}`;\r\n\r\n // Now we need to parse the function arguments\r\n // This is handled by the parent parser's function call logic\r\n // We need to create a function call expression\r\n\r\n // Consume the opening parenthesis\r\n this.consume('OPEN_PAREN', `Expected '(' after '${fullName}'`);\r\n\r\n // Parse arguments\r\n const args: XPathExpression[] = [];\r\n if (!this.check('CLOSE_PAREN')) {\r\n do {\r\n args.push(this.parseExprSingle());\r\n } while (this.match('COMMA'));\r\n }\r\n\r\n // Consume the closing parenthesis\r\n this.consume('CLOSE_PAREN', `Expected ')' after function arguments`);\r\n\r\n // Import and use the function call expression\r\n const { XPathFunctionCall } = require('../expressions/function-call-expression');\r\n return new XPathFunctionCall(fullName, args);\r\n }\r\n\r\n /**\r\n * Parse a map constructor expression (XPath 3.1).\r\n * Syntax: map { key1: value1, key2: value2, ... }\r\n * Syntax: map { } (empty map)\r\n *\r\n * Each entry is: ExprSingle : ExprSingle\r\n */\r\n private parseMapConstructor(): XPathExpression {\r\n // Consume 'map' keyword\r\n this.advance();\r\n\r\n // Consume '{'\r\n this.consume('OPEN_CURLY_BRACKET', \"Expected '{' after 'map'\");\r\n\r\n const entries: MapConstructorEntry[] = [];\r\n\r\n // Empty map: map { }\r\n if (this.check('CLOSE_CURLY_BRACKET')) {\r\n this.advance();\r\n return new XPathMapConstructorExpression(entries);\r\n }\r\n\r\n // Parse key-value pairs\r\n do {\r\n // Parse key as ExprSingle to avoid treating commas inside entries as sequence separators\r\n const key = this.parseExprSingle();\r\n\r\n // Consume ':'\r\n this.consume('COLON', \"Expected ':' after map key\");\r\n\r\n // Parse value expression as ExprSingle for the same reason\r\n const value = this.parseExprSingle();\r\n\r\n entries.push({ key, value });\r\n\r\n // Check for more entries\r\n } while (this.match('COMMA'));\r\n\r\n // Consume '}'\r\n this.consume('CLOSE_CURLY_BRACKET', \"Expected '}' after map entries\");\r\n\r\n return new XPathMapConstructorExpression(entries);\r\n }\r\n\r\n /**\r\n * Parse a square bracket array constructor (XPath 3.1).\r\n * Syntax: [item1, item2, ...]\r\n * Syntax: [] (empty array)\r\n *\r\n * Each comma-separated expression becomes a separate array member.\r\n */\r\n private parseSquareBracketArrayConstructor(): XPathExpression {\r\n // Consume '['\r\n this.advance();\r\n\r\n const items: XPathExpression[] = [];\r\n\r\n // Empty array: []\r\n if (this.check('CLOSE_SQUARE_BRACKET')) {\r\n this.advance();\r\n return new XPathSquareBracketArrayConstructor(items);\r\n }\r\n\r\n // Parse items\r\n do {\r\n // Parse each item as ExprSingle to avoid treating commas as sequence separators\r\n const item = this.parseExprSingle();\r\n items.push(item);\r\n } while (this.match('COMMA'));\r\n\r\n // Consume ']'\r\n this.consume('CLOSE_SQUARE_BRACKET', \"Expected ']' after array items\");\r\n\r\n return new XPathSquareBracketArrayConstructor(items);\r\n }\r\n\r\n /**\r\n * Parse a curly brace array constructor (XPath 3.1).\r\n * Syntax: array { expr }\r\n * Syntax: array { } (empty array)\r\n *\r\n * The expression result is evaluated and each item in the\r\n * resulting sequence becomes a separate array member.\r\n */\r\n private parseCurlyArrayConstructor(): XPathExpression {\r\n // Consume 'array' keyword\r\n this.advance();\r\n\r\n // Consume '{'\r\n this.consume('OPEN_CURLY_BRACKET', \"Expected '{' after 'array'\");\r\n\r\n // Empty array: array { }\r\n if (this.check('CLOSE_CURLY_BRACKET')) {\r\n this.advance();\r\n // Return an array with an empty sequence expression\r\n return new XPathCurlyBraceArrayConstructor({\r\n evaluate: () => [],\r\n toString: () => '()',\r\n } as XPathExpression);\r\n }\r\n\r\n // Parse the expression (can be any expression, including sequences)\r\n const expr = this.parseExpr();\r\n\r\n // Consume '}'\r\n this.consume('CLOSE_CURLY_BRACKET', \"Expected '}' after array expression\");\r\n\r\n return new XPathCurlyBraceArrayConstructor(expr);\r\n }\r\n\r\n /**\r\n * Override parseFilterExpr to handle lookup operators after predicates.\r\n * Lookup operators have lower precedence than predicates.\r\n */\r\n protected parseFilterExpr(): XPathExpression {\r\n // First parse the base expression (which may include dynamic function calls and predicates)\r\n let expr = super.parseFilterExpr();\r\n\r\n // Check for lookup operators: expr?key (can be chained)\r\n while (this.check('QUESTION')) {\r\n expr = this.parseLookupExpr(expr);\r\n }\r\n\r\n return expr;\r\n }\r\n\r\n /**\r\n * Parse a lookup expression: ?key, ?1, ?(expr), ?*\r\n */\r\n private parseLookupExpr(baseExpr: XPathExpression): XPathExpression {\r\n this.consume('QUESTION', 'Expected ? for lookup operator');\r\n\r\n let keySpecifier: KeySpecifier;\r\n\r\n if (this.match('ASTERISK')) {\r\n // Wildcard: ?*\r\n keySpecifier = { type: KeySpecifierType.WILDCARD };\r\n } else if (this.check('OPEN_PAREN')) {\r\n // Parenthesized expression: ?(expr)\r\n this.advance(); // consume '('\r\n const expr = this.parseExpr();\r\n this.consume('CLOSE_PAREN', \"Expected ')' after lookup expression\");\r\n keySpecifier = { type: KeySpecifierType.PARENTHESIZED_EXPR, value: expr };\r\n } else if (this.check('NUMBER')) {\r\n // Integer literal: ?1, ?2, etc.\r\n const numToken = this.advance();\r\n const position = parseInt(numToken.lexeme, 10);\r\n keySpecifier = { type: KeySpecifierType.INTEGER_LITERAL, value: position };\r\n } else if (\r\n this.peek()?.type === 'IDENTIFIER' ||\r\n this.peek()?.type === 'FUNCTION' ||\r\n this.peek()?.type === 'OPERATOR' ||\r\n this.peek()?.type === 'LOCATION' ||\r\n this.peek()?.type === 'NODE_TYPE'\r\n ) {\r\n // NCName: ?key\r\n const name = this.advance().lexeme;\r\n keySpecifier = { type: KeySpecifierType.NCNAME, value: name };\r\n } else {\r\n throw new Error('Expected key specifier after ?');\r\n }\r\n\r\n return new XPathLookupExpression(baseExpr, keySpecifier);\r\n }\r\n\r\n /**\r\n * Override parseSequenceType to support union types (XPath 3.1 Extension)\r\n * Syntax: type1 | type2 | ... | typeN\r\n *\r\n * Examples:\r\n * xs:string | xs:integer\r\n * (xs:integer | xs:decimal) | xs:double\r\n */\r\n protected parseSequenceType(): any {\r\n // Parse the first type\r\n let firstType = super.parseSequenceType();\r\n\r\n // Check for union operator |\r\n if (this.check('PIPE')) {\r\n const memberTypes: any[] = [firstType];\r\n\r\n // Parse additional types in the union\r\n while (this.match('PIPE')) {\r\n const nextType = super.parseSequenceType();\r\n memberTypes.push(nextType);\r\n }\r\n\r\n // Create union type from all member types\r\n const { createUnionType } = require('../types/union-type');\r\n const { createItemSequenceType } = require('../types/sequence-type');\r\n\r\n // Extract ItemTypes from SequenceTypes (they all should have same occurrence)\r\n const itemTypes = memberTypes.map((st) => {\r\n if (st.getItemType && typeof st.getItemType === 'function') {\r\n const itemType = st.getItemType();\r\n if (itemType === 'empty') {\r\n throw new Error('empty-sequence() cannot be used in union types');\r\n }\r\n return itemType;\r\n }\r\n return st;\r\n });\r\n\r\n // Get the occurrence indicator (use the first one, all should be compatible)\r\n const occurrence = firstType.getOccurrence ? firstType.getOccurrence() : 'ONE';\r\n\r\n // Create union ItemType\r\n const unionItemType = createUnionType(...itemTypes);\r\n\r\n // Wrap in SequenceType with the occurrence indicator\r\n return createItemSequenceType(unionItemType, occurrence);\r\n }\r\n\r\n return firstType;\r\n }\r\n\r\n /**\r\n * Override parseSequenceTypeInternal to support union types in type annotations\r\n * This is called from instance of, treat as, cast as, etc.\r\n */\r\n protected parseSequenceTypeInternal(): any {\r\n // Parse the first type using parent's internal method\r\n let firstType = super['parseSequenceTypeInternal']();\r\n\r\n // Check for union operator |\r\n if (this.check('PIPE')) {\r\n const memberTypes: any[] = [firstType];\r\n\r\n // Parse additional types in the union\r\n while (this.match('PIPE')) {\r\n const nextType = super['parseSequenceTypeInternal']();\r\n memberTypes.push(nextType);\r\n }\r\n\r\n // Create union type from all member types\r\n const { createUnionType } = require('../types/union-type');\r\n const { createItemSequenceType } = require('../types/sequence-type');\r\n\r\n // Extract ItemTypes from SequenceTypes\r\n const itemTypes = memberTypes.map((st) => {\r\n if (st.getItemType && typeof st.getItemType === 'function') {\r\n const itemType = st.getItemType();\r\n if (itemType === 'empty') {\r\n throw new Error('empty-sequence() cannot be used in union types');\r\n }\r\n return itemType;\r\n }\r\n return st;\r\n });\r\n\r\n // Get the occurrence indicator\r\n const occurrence = firstType.getOccurrence ? firstType.getOccurrence() : 'ONE';\r\n\r\n // Create union ItemType\r\n const unionItemType = createUnionType(...itemTypes);\r\n\r\n // Wrap in SequenceType\r\n return createItemSequenceType(unionItemType, occurrence);\r\n }\r\n\r\n return firstType;\r\n }\r\n}\r\n","export * from './base-parser';\r\nexport * from './parser-10';\r\nexport * from './parser-20';\r\nexport * from './parser-30';\r\nexport * from './parser-31';\r\n\r\nimport { XPath10Parser } from './parser-10';\r\nimport { XPath20Parser } from './parser-20';\r\nimport { XPath30Parser } from './parser-30';\r\nimport { XPath31Parser } from './parser-31';\r\nimport { XPathBaseParserOptions } from '../xslt-extensions';\r\nimport { XPathVersion, DEFAULT_XPATH_VERSION } from '../xpath-version';\r\n\r\n/**\r\n * Factory function to create an XPath parser for the specified version.\r\n *\r\n * @param version - The XPath version to use. Defaults to '1.0'.\r\n * @param options - Parser configuration options.\r\n * @returns An XPath parser instance appropriate for the version.\r\n *\r\n * @example\r\n * ```typescript\r\n * // Create XPath 1.0 parser (default)\r\n * const parser = createXPathParser();\r\n *\r\n * // Create XPath 1.0 parser explicitly\r\n * const parser10 = createXPathParser('1.0');\r\n *\r\n * // Create XPath 2.0 parser\r\n * const parser20 = createXPathParser('2.0');\r\n *\r\n * // Create parser with options\r\n * const parser = createXPathParser('1.0', { enableNamespaceAxis: true });\r\n * ```\r\n */\r\nexport function createXPathParser(\r\n version: XPathVersion = DEFAULT_XPATH_VERSION,\r\n options?: Omit<XPathBaseParserOptions, 'version'>\r\n): XPath10Parser | XPath20Parser | XPath30Parser | XPath31Parser {\r\n const fullOptions: XPathBaseParserOptions = { ...options, version };\r\n\r\n switch (version) {\r\n case '1.0':\r\n return new XPath10Parser(fullOptions);\r\n case '2.0':\r\n return new XPath20Parser(fullOptions);\r\n case '3.0':\r\n return new XPath30Parser(fullOptions);\r\n case '3.1':\r\n return new XPath31Parser(fullOptions);\r\n default:\r\n throw new Error(`Unsupported XPath version: ${version}`);\r\n }\r\n}\r\n\r\n/**\r\n * Alias for XPath10Parser for backward compatibility.\r\n *\r\n * @deprecated Use XPath10Parser, XPath20Parser, or createXPathParser() instead.\r\n * This alias defaults to XPath 1.0 behavior.\r\n *\r\n * @example\r\n * ```typescript\r\n * // Old usage (deprecated):\r\n * const parser = new XPathParser();\r\n *\r\n * // New recommended usage:\r\n * const parser = new XPath10Parser();\r\n * // or for XPath 2.0:\r\n * const parser = new XPath20Parser();\r\n * // or using the factory:\r\n * const parser = createXPathParser('1.0');\r\n * ```\r\n */\r\nexport const XPathParser = XPath10Parser;\r\n","// Copyright 2023-2026 Design Liquido\r\n// XPath adapter that uses the new lexer/parser implementation\r\n// while maintaining backward compatibility with the existing XSLT API.\r\n\r\nimport { XNode } from '../dom';\r\nimport { XPathLexer } from './lib/src/lexer';\r\nimport { createXPathParser } from './lib/src/parser';\r\nimport { XPathExpression, XPathLocationPath, XPathUnionExpression } from './lib/src/expressions';\r\nimport { ExprContext } from './expr-context';\r\nimport { NodeValue } from './values/node-value';\r\nimport { XPathVersion } from './lib/src/xpath-version';\r\nimport { NodeConverter } from './expressions/node-converter';\r\nimport { Expression } from './expressions/expression';\r\nimport { LocationExpr } from './expressions/location-expr';\r\nimport { UnionExpr } from './expressions/union-expr';\r\n\r\n/**\r\n * XPath class that uses the new lexer/parser implementation\r\n * while maintaining API compatibility with the old implementation.\r\n */\r\nexport class XPath {\r\n private lexers: Map<string, XPathLexer> = new Map();\r\n private parsers: Map<string, any> = new Map();\r\n private nodeConverter: NodeConverter;\r\n private parseCache: Map<string, Expression> = new Map();\r\n\r\n constructor() {\r\n this.nodeConverter = new NodeConverter();\r\n }\r\n\r\n private getLexer(version: XPathVersion): XPathLexer {\r\n const v = version || '1.0';\r\n if (!this.lexers.has(v)) {\r\n this.lexers.set(v, new XPathLexer({ version: v as any }));\r\n }\r\n return this.lexers.get(v)!;\r\n }\r\n\r\n private getParser(version: XPathVersion): any {\r\n const v = version || '1.0';\r\n if (!this.parsers.has(v)) {\r\n this.parsers.set(v, createXPathParser(v as any));\r\n }\r\n return this.parsers.get(v)!;\r\n }\r\n\r\n /**\r\n * Parse an XPath expression and return an Expression object.\r\n * @param expression The XPath expression string.\r\n * @param axis Optional axis override for relative paths.\r\n * @param version Optional XPath version (defaults to 1.0).\r\n */\r\n xPathParse(expression: string, axis?: string, version: XPathVersion = '1.0'): Expression {\r\n const cacheKey = `${expression}:${axis || ''}:${version}`;\r\n\r\n if (this.parseCache.has(cacheKey)) {\r\n return this.parseCache.get(cacheKey)!;\r\n }\r\n\r\n const lexer = this.getLexer(version);\r\n const parser = this.getParser(version);\r\n\r\n const tokens = lexer.scan(expression);\r\n const xpathExpr = parser.parse(tokens);\r\n\r\n const wrappedExpr = this.wrapExpression(xpathExpr, axis);\r\n this.parseCache.set(cacheKey, wrappedExpr);\r\n\r\n return wrappedExpr;\r\n }\r\n\r\n /**\r\n * Parse and evaluate an XPath expression.\r\n * @param select The XPath expression string.\r\n * @param context The expression context.\r\n */\r\n xPathEval(select: string, context: ExprContext): NodeValue {\r\n const version = (context.xsltVersion as XPathVersion) || '1.0';\r\n // For XSLT 3.0, use XPath 3.1 to get Maps and Arrays support which are often expected\r\n const effectiveVersion = version === '3.0' ? '3.1' : version;\r\n \r\n const expression = this.xPathParse(select, undefined, effectiveVersion);\r\n return expression.evaluate(context);\r\n }\r\n\r\n /**\r\n * Sort nodes in context according to sort specifications.\r\n * @param context The expression context with nodes to sort.\r\n * @param sort Array of sort specifications.\r\n */\r\n xPathSort(context: ExprContext, sort: any[]) {\r\n if (sort.length === 0) {\r\n return;\r\n }\r\n\r\n const sortList: { node: XNode; key: { value: any; order: string }[] }[] = [];\r\n\r\n for (let i = 0; i < context.contextSize(); ++i) {\r\n const node = context.nodeList[i];\r\n const sortItem = {\r\n node,\r\n key: [] as { value: any; order: string }[]\r\n };\r\n const clonedContext = context.clone([node], 0);\r\n\r\n for (const s of sort) {\r\n const value = s.expr.evaluate(clonedContext);\r\n\r\n let evalue: any;\r\n if (s.type === 'text') {\r\n evalue = value.stringValue();\r\n } else if (s.type === 'number') {\r\n evalue = value.numberValue();\r\n }\r\n sortItem.key.push({\r\n value: evalue,\r\n order: s.order\r\n });\r\n }\r\n\r\n // Make sort stable by adding index as lowest priority\r\n sortItem.key.push({\r\n value: i,\r\n order: 'ascending'\r\n });\r\n\r\n sortList.push(sortItem);\r\n }\r\n\r\n sortList.sort(this.xPathSortByKey);\r\n\r\n const nodes: XNode[] = [];\r\n for (let i = 0; i < sortList.length; ++i) {\r\n const node = sortList[i].node;\r\n node.siblingPosition = i;\r\n nodes.push(node);\r\n }\r\n\r\n context.nodeList = nodes;\r\n context.setNode(0);\r\n }\r\n\r\n /**\r\n * Comparison function for sorting.\r\n */\r\n private xPathSortByKey(v1: any, v2: any): number {\r\n for (let i = 0; i < v1.key.length; ++i) {\r\n const o = v1.key[i].order === 'descending' ? -1 : 1;\r\n if (v1.key[i].value > v2.key[i].value) {\r\n return +1 * o;\r\n }\r\n if (v1.key[i].value < v2.key[i].value) {\r\n return -1 * o;\r\n }\r\n }\r\n return 0;\r\n }\r\n\r\n /**\r\n * Wrap a new XPath expression in the backward-compatible Expression class.\r\n */\r\n private wrapExpression(xpathExpr: XPathExpression, axis?: string): Expression {\r\n if (xpathExpr instanceof XPathLocationPath) {\r\n // Apply axis override if specified\r\n if (axis && xpathExpr.steps.length > 0 && !xpathExpr.absolute) {\r\n xpathExpr.steps[0].axis = axis as any;\r\n }\r\n return new LocationExpr(xpathExpr, this.nodeConverter);\r\n }\r\n\r\n if (xpathExpr instanceof XPathUnionExpression) {\r\n const expr1 = this.wrapExpression(xpathExpr.left, axis);\r\n const expr2 = this.wrapExpression(xpathExpr.right, axis);\r\n return new UnionExpr(xpathExpr, this.nodeConverter, expr1, expr2);\r\n }\r\n\r\n return new Expression(xpathExpr, this.nodeConverter);\r\n }\r\n\r\n /**\r\n * Clear parse cache (useful for testing or memory management).\r\n */\r\n clearCache() {\r\n this.parseCache.clear();\r\n this.nodeConverter.clearCache();\r\n }\r\n}\r\n\r\n// Re-export expression classes for backward compatibility\r\nexport { Expression, LocationExpr, UnionExpr };\r\n","import { DOM_ATTRIBUTE_NODE, DOM_ELEMENT_NODE } from '../constants';\r\n\r\n// operate on native DOM nodes.\r\n/**\r\n * Our W3C DOM Node implementation. Note we call it XNode because we\r\n * can't define the identifier Node. We do this mostly for Opera,\r\n * where we can't reuse the HTML DOM for parsing our own XML, and for\r\n * Safari, where it is too expensive to have the template processor.\r\n */\r\nexport class XNode {\r\n id: number;\r\n childNodes: XNode[];\r\n nodeType: number;\r\n nodeName: string;\r\n nodeValue: any;\r\n firstChild: XNode;\r\n lastChild: XNode;\r\n nextSibling: XNode;\r\n previousSibling: XNode;\r\n siblingPosition: number;\r\n\r\n ownerDocument: any;\r\n namespaceUri: any;\r\n prefix: string;\r\n localName: string;\r\n\r\n parentNode: XNode;\r\n\r\n visited: boolean;\r\n escape: boolean;\r\n fromXslText: boolean;\r\n\r\n static _unusedXNodes: any[] = [];\r\n\r\n constructor(type: number, name: string, opt_value: any, opt_owner: any, opt_namespace?: any) {\r\n this.id = Math.random() * (Number.MAX_SAFE_INTEGER - 1) + 1;\r\n this.childNodes = [];\r\n this.visited = false;\r\n this.escape = true;\r\n this.fromXslText = false;\r\n this.siblingPosition = -1;\r\n\r\n this.init(type, name, opt_value, opt_owner, opt_namespace);\r\n }\r\n\r\n /**\r\n * Node initialization. Called by the constructor and `recycle` method.\r\n * @param type The node type.\r\n * @param name The node name.\r\n * @param value The node value.\r\n * @param owner The node owner.\r\n * @param namespaceUri The node namespace.\r\n */\r\n init(type: number, name: string, value: string, owner: any, namespaceUri: any) {\r\n this.nodeType = type - 0;\r\n this.nodeName = `${name}`;\r\n this.nodeValue = `${value}`;\r\n this.ownerDocument = owner;\r\n this.namespaceUri = namespaceUri || null;\r\n [this.prefix, this.localName] = this.qualifiedNameToParts(`${name}`);\r\n\r\n this.firstChild = null;\r\n this.lastChild = null;\r\n this.nextSibling = null;\r\n this.previousSibling = null;\r\n this.parentNode = null;\r\n }\r\n\r\n protected qualifiedNameToParts(name: string) {\r\n if (name.includes(':')) {\r\n return name.split(':');\r\n }\r\n\r\n return [null, name];\r\n }\r\n\r\n // Traverses the element nodes in the DOM section underneath the given\r\n // node and invokes the given callbacks as methods on every element\r\n // node encountered. Function opt_pre is invoked before a node's\r\n // children are traversed; opt_post is invoked after they are\r\n // traversed. Traversal will not be continued if a callback function\r\n // returns boolean false. NOTE(mesch): copied from\r\n // <//google3/maps/webmaps/javascript/dom.js>.\r\n protected domTraverseElements(node: XNode, opt_pre: Function, opt_post: any) {\r\n let ret;\r\n if (opt_pre) {\r\n ret = opt_pre.call(null, node);\r\n if (typeof ret == 'boolean' && !ret) {\r\n return false;\r\n }\r\n }\r\n\r\n for (let c = node.firstChild; c; c = c.nextSibling) {\r\n if (c.nodeType == DOM_ELEMENT_NODE) {\r\n ret = this.domTraverseElements.call(this, c, opt_pre, opt_post);\r\n if (typeof ret == 'boolean' && !ret) {\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n if (opt_post) {\r\n ret = opt_post.call(null, node);\r\n if (typeof ret == 'boolean' && !ret) {\r\n return false;\r\n }\r\n }\r\n }\r\n\r\n // TODO: Do we still need this?\r\n static recycle(node: any) {\r\n if (!node) {\r\n return;\r\n }\r\n\r\n if (node.constructor.name === 'XDocument') {\r\n this.recycle((node as any).documentElement);\r\n return;\r\n }\r\n\r\n if (node.constructor != this) {\r\n return;\r\n }\r\n\r\n this._unusedXNodes.push(node);\r\n /* for (let a = 0; a < node.attributes.length; ++a) {\r\n this.recycle(node.attributes[a]);\r\n } */\r\n\r\n for (let c = 0; c < node.childNodes.length; ++c) {\r\n this.recycle(node.childNodes[c]);\r\n }\r\n\r\n // node.attributes.length = 0;\r\n node.childNodes.length = 0;\r\n node.init.call(0, '', '', null);\r\n }\r\n\r\n static create(type: any, name: string, value: any, owner: any, namespace?: any): XNode {\r\n if (this._unusedXNodes.length > 0) {\r\n const node = this._unusedXNodes.pop();\r\n node.init(type, name, value, owner, namespace);\r\n return node;\r\n }\r\n\r\n return new XNode(type, name, value, owner, namespace);\r\n }\r\n\r\n static clone(node: XNode, newOwner: XNode): XNode {\r\n const newNode = new XNode(node.nodeType, node.nodeName, node.nodeValue, newOwner, node.namespaceUri);\r\n newNode.id = node.id;\r\n for (let child of node.childNodes) {\r\n newNode.appendChild(XNode.clone(child, newNode));\r\n }\r\n\r\n /* for (let attribute of node.attributes) {\r\n newNode.setAttribute(attribute.nodeName, attribute.nodeValue);\r\n } */\r\n\r\n return newNode;\r\n }\r\n\r\n appendChild(node: XNode) {\r\n // firstChild\r\n if (this.childNodes.length === 0) {\r\n this.firstChild = node;\r\n }\r\n\r\n // previousSibling\r\n node.previousSibling = this.lastChild;\r\n\r\n // nextSibling\r\n node.nextSibling = null;\r\n if (this.lastChild) {\r\n this.lastChild.nextSibling = node;\r\n }\r\n\r\n // parentNode\r\n node.parentNode = this;\r\n\r\n // lastChild\r\n this.lastChild = node;\r\n\r\n // childNodes\r\n this.childNodes.push(node);\r\n }\r\n\r\n replaceChild(newNode: any, oldNode: any) {\r\n if (oldNode == newNode) {\r\n return;\r\n }\r\n\r\n for (let i = 0; i < this.childNodes.length; ++i) {\r\n if (this.childNodes[i] == oldNode) {\r\n this.childNodes[i] = newNode;\r\n\r\n let p = oldNode.parentNode;\r\n oldNode.parentNode = null;\r\n newNode.parentNode = p;\r\n\r\n p = oldNode.previousSibling;\r\n oldNode.previousSibling = null;\r\n newNode.previousSibling = p;\r\n if (newNode.previousSibling) {\r\n newNode.previousSibling.nextSibling = newNode;\r\n }\r\n\r\n p = oldNode.nextSibling;\r\n oldNode.nextSibling = null;\r\n newNode.nextSibling = p;\r\n if (newNode.nextSibling) {\r\n newNode.nextSibling.previousSibling = newNode;\r\n }\r\n\r\n if (this.firstChild == oldNode) {\r\n this.firstChild = newNode;\r\n }\r\n\r\n if (this.lastChild == oldNode) {\r\n this.lastChild = newNode;\r\n }\r\n\r\n break;\r\n }\r\n }\r\n }\r\n\r\n insertBefore(newNode: any, oldNode: any) {\r\n if (oldNode == newNode) {\r\n return;\r\n }\r\n\r\n if (oldNode.parentNode != this) {\r\n return;\r\n }\r\n\r\n if (newNode.parentNode) {\r\n newNode.parentNode.removeChild(newNode);\r\n }\r\n\r\n const newChildren = [];\r\n\r\n for (const c of this.childNodes) {\r\n if (c == oldNode) {\r\n newChildren.push(newNode);\r\n\r\n newNode.parentNode = this;\r\n\r\n newNode.previousSibling = oldNode.previousSibling;\r\n oldNode.previousSibling = newNode;\r\n if (newNode.previousSibling) {\r\n newNode.previousSibling.nextSibling = newNode;\r\n }\r\n\r\n newNode.nextSibling = oldNode;\r\n\r\n if (this.firstChild == oldNode) {\r\n this.firstChild = newNode;\r\n }\r\n }\r\n newChildren.push(c);\r\n }\r\n\r\n this.childNodes = newChildren;\r\n }\r\n\r\n removeChild(node: XNode) {\r\n const newChildren = [];\r\n\r\n for (const c of this.childNodes) {\r\n if (c != node) {\r\n newChildren.push(c);\r\n } else {\r\n if (c.previousSibling) {\r\n c.previousSibling.nextSibling = c.nextSibling;\r\n }\r\n if (c.nextSibling) {\r\n c.nextSibling.previousSibling = c.previousSibling;\r\n }\r\n if (this.firstChild == c) {\r\n this.firstChild = c.nextSibling;\r\n }\r\n if (this.lastChild == c) {\r\n this.lastChild = c.previousSibling;\r\n }\r\n }\r\n }\r\n\r\n this.childNodes = newChildren;\r\n }\r\n\r\n hasAttributes() {\r\n const attributes = this.childNodes.filter(n => n.nodeType === DOM_ATTRIBUTE_NODE);\r\n return attributes.length > 0;\r\n }\r\n\r\n setAttribute(name: string, value: any) {\r\n const attributes = this.childNodes.filter(n => n.nodeType === DOM_ATTRIBUTE_NODE);\r\n for (let i = 0; i < attributes.length; ++i) {\r\n if (attributes[i].nodeName == name) {\r\n attributes[i].nodeValue = `${value}`;\r\n return;\r\n }\r\n }\r\n\r\n const newAttribute = XNode.create(DOM_ATTRIBUTE_NODE, name, value, this);\r\n newAttribute.parentNode = this;\r\n this.appendChild(newAttribute);\r\n }\r\n\r\n setAttributeNS(namespace: any, name: any, value: any) {\r\n const attributes = this.childNodes.filter(n => n.nodeType === DOM_ATTRIBUTE_NODE);\r\n for (let i = 0; i < attributes.length; ++i) {\r\n const attribute = attributes[i];\r\n if (\r\n attribute.namespaceUri == namespace &&\r\n attribute.localName == this.qualifiedNameToParts(`${name}`)[1]\r\n ) {\r\n attribute.nodeValue = `${value}`;\r\n attribute.nodeName = `${name}`;\r\n attribute.prefix = this.qualifiedNameToParts(`${name}`)[0];\r\n return;\r\n }\r\n }\r\n\r\n const newAttribute = XNode.create(DOM_ATTRIBUTE_NODE, name, value, this, namespace);\r\n newAttribute.parentNode = this;\r\n this.appendChild(newAttribute);\r\n }\r\n\r\n getAttributeValue(name: string): any {\r\n const attributes = this.childNodes.filter(n => n.nodeType === DOM_ATTRIBUTE_NODE);\r\n for (let i = 0; i < attributes.length; ++i) {\r\n if (attributes[i].nodeName === name) {\r\n return attributes[i].nodeValue;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n getAttributeNS(namespace: any, localName: any) {\r\n const attributes = this.childNodes.filter(n => n.nodeType === DOM_ATTRIBUTE_NODE);\r\n for (let i = 0; i < attributes.length; ++i) {\r\n const attribute = attributes[i];\r\n if (attribute.namespaceUri === namespace && attribute.localName === localName) {\r\n return attribute.nodeValue;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n hasAttribute(name: string) {\r\n const attributes = this.childNodes.filter(n => n.nodeType === DOM_ATTRIBUTE_NODE);\r\n for (let i = 0; i < attributes.length; ++i) {\r\n if (attributes[i].nodeName === name) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n hasAttributeNS(namespace: string, localName: string) {\r\n const attributes = this.childNodes.filter(n => n.nodeType === DOM_ATTRIBUTE_NODE);\r\n for (let i = 0; i < attributes.length; ++i) {\r\n const attribute = attributes[i];\r\n if (attribute.namespaceUri === namespace && attribute.localName === localName) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n removeAttribute(name: string) {\r\n const newChildNodes: XNode[] = [];\r\n for (let i = 0; i < this.childNodes.length; ++i) {\r\n const childNode = this.childNodes[i];\r\n if (childNode.nodeType !== DOM_ATTRIBUTE_NODE) {\r\n newChildNodes.push(childNode);\r\n continue;\r\n }\r\n\r\n if (childNode.nodeName !== name) {\r\n newChildNodes.push(childNode);\r\n }\r\n }\r\n\r\n this.childNodes = newChildNodes;\r\n }\r\n\r\n removeAttributeNS(namespace: string, localName: string) {\r\n const newChildNodes: XNode[] = [];\r\n for (let i = 0; i < this.childNodes.length; ++i) {\r\n const childNode = this.childNodes[i];\r\n if (childNode.nodeType !== DOM_ATTRIBUTE_NODE) {\r\n newChildNodes.push(childNode);\r\n continue;\r\n }\r\n\r\n if (childNode.localName !== localName || childNode.namespaceUri !== namespace) {\r\n newChildNodes.push(childNode);\r\n }\r\n }\r\n\r\n this.childNodes = newChildNodes;\r\n }\r\n\r\n getElementsByTagName(name: string) {\r\n const ret = [];\r\n const self = this;\r\n if ('*' == name) {\r\n this.domTraverseElements(\r\n this,\r\n (node: XNode) => {\r\n if (self == node) return;\r\n ret.push(node);\r\n },\r\n null\r\n );\r\n } else {\r\n this.domTraverseElements(\r\n this,\r\n (node: XNode) => {\r\n if (self == node) return;\r\n if (node.nodeName == name) {\r\n ret.push(node);\r\n }\r\n },\r\n null\r\n );\r\n }\r\n return ret;\r\n }\r\n\r\n getElementsByTagNameNS(namespace: string, localName: string) {\r\n const ret = [];\r\n const self = this;\r\n if ('*' == namespace && '*' == localName) {\r\n this.domTraverseElements(\r\n this,\r\n (node: any) => {\r\n if (self == node) return;\r\n ret.push(node);\r\n },\r\n null\r\n );\r\n } else if ('*' == namespace) {\r\n this.domTraverseElements(\r\n this,\r\n (node: any) => {\r\n if (self == node) return;\r\n if (node.localName == localName) ret.push(node);\r\n },\r\n null\r\n );\r\n } else if ('*' == localName) {\r\n this.domTraverseElements(\r\n this,\r\n (node: any) => {\r\n if (self == node) return;\r\n if (node.namespaceUri == namespace) ret.push(node);\r\n },\r\n null\r\n );\r\n } else {\r\n this.domTraverseElements(\r\n this,\r\n (node: any) => {\r\n if (self == node) return;\r\n if (node.localName == localName && node.namespaceUri == namespace) {\r\n ret.push(node);\r\n }\r\n },\r\n null\r\n );\r\n }\r\n return ret;\r\n }\r\n\r\n getElementById(id: any): any {\r\n let ret = null;\r\n this.domTraverseElements(\r\n this,\r\n (node: any) => {\r\n if (node.getAttributeValue('id') == id) {\r\n ret = node;\r\n return false;\r\n }\r\n },\r\n null\r\n );\r\n return ret;\r\n }\r\n\r\n getAncestorByLocalName(localName: string): XNode | undefined {\r\n if (this.parentNode === null || this.parentNode === undefined) {\r\n return undefined;\r\n }\r\n\r\n if (this.parentNode.localName === localName) {\r\n return this.parentNode;\r\n }\r\n\r\n return this.parentNode.getAncestorByLocalName(localName);\r\n }\r\n\r\n getAncestorById(id: number): XNode | undefined {\r\n if (this.parentNode === null || this.parentNode === undefined) {\r\n return undefined;\r\n }\r\n\r\n if (this.parentNode.id === id) {\r\n return this.parentNode;\r\n }\r\n\r\n return this.parentNode.getAncestorById(id);\r\n }\r\n\r\n toString(): string {\r\n return `${this.nodeType}, ${this.nodeName}, ${this.nodeValue}`;\r\n }\r\n}\r\n","import {\r\n DOM_ATTRIBUTE_NODE,\r\n DOM_CDATA_SECTION_NODE,\r\n DOM_COMMENT_NODE,\r\n DOM_DOCUMENT_FRAGMENT_NODE,\r\n DOM_DOCUMENT_NODE,\r\n DOM_DOCUMENT_TYPE_NODE,\r\n DOM_ELEMENT_NODE,\r\n DOM_PROCESSING_INSTRUCTION_NODE,\r\n DOM_TEXT_NODE\r\n} from '../constants';\r\nimport { XNode } from './xnode';\r\n\r\nexport class XDocument extends XNode {\r\n documentElement: any;\r\n\r\n constructor() {\r\n // NOTE(mesch): According to the DOM Spec, ownerDocument of a\r\n // document node is null.\r\n super(DOM_DOCUMENT_NODE, '#document', null, null);\r\n this.documentElement = null;\r\n }\r\n\r\n appendChild(node: any) {\r\n super.appendChild(node);\r\n if (node.nodeType === DOM_ELEMENT_NODE && !this.documentElement) {\r\n this.documentElement = node;\r\n }\r\n }\r\n\r\n createElement(name: string): XNode {\r\n return XNode.create(DOM_ELEMENT_NODE, name, null, this);\r\n }\r\n\r\n createElementNS(namespace: any, name: any) {\r\n return XNode.create(DOM_ELEMENT_NODE, name, null, this, namespace);\r\n }\r\n\r\n createDocumentFragment(): XNode {\r\n return XNode.create(DOM_DOCUMENT_FRAGMENT_NODE, '#document-fragment', null, this);\r\n }\r\n\r\n createTextNode(value: any) {\r\n return XNode.create(DOM_TEXT_NODE, '#text', value, this);\r\n }\r\n\r\n createAttribute(name: any) {\r\n return XNode.create(DOM_ATTRIBUTE_NODE, name, null, this);\r\n }\r\n\r\n createAttributeNS(namespace: any, name: any) {\r\n return XNode.create(DOM_ATTRIBUTE_NODE, name, null, this, namespace);\r\n }\r\n\r\n createComment(data: any) {\r\n return XNode.create(DOM_COMMENT_NODE, '#comment', data, this);\r\n }\r\n\r\n createCDATASection(data: any) {\r\n return XNode.create(DOM_CDATA_SECTION_NODE, '#cdata-section', data, this);\r\n }\r\n\r\n createDTDSection(data: any) {\r\n return XNode.create(DOM_DOCUMENT_TYPE_NODE, '#dtd-section', data, this);\r\n }\r\n\r\n createProcessingInstruction(target: string, data: any) {\r\n return XNode.create(DOM_PROCESSING_INSTRUCTION_NODE, target, data, this);\r\n }\r\n}\r\n","// Copyright 2026 Design Liquido\r\n// All Rights Reserved\r\n\r\nimport {\r\n DOM_ATTRIBUTE_NODE,\r\n DOM_CDATA_SECTION_NODE,\r\n DOM_COMMENT_NODE,\r\n DOM_DOCUMENT_FRAGMENT_NODE,\r\n DOM_DOCUMENT_NODE,\r\n DOM_DOCUMENT_TYPE_NODE,\r\n DOM_ELEMENT_NODE,\r\n DOM_PROCESSING_INSTRUCTION_NODE,\r\n DOM_TEXT_NODE\r\n} from '../constants';\r\nimport { XDocument } from './xdocument';\r\nimport { XNode } from './xnode';\r\n\r\n/**\r\n * Converts a native browser DOM Document or Node into an XDocument/XNode tree\r\n * compatible with the XSLT processor. This allows browser users who already\r\n * have a parsed DOM to skip the string-based xmlParse() step.\r\n *\r\n * @param nativeNode A browser DOM Document, Element, or other Node.\r\n * @returns An XDocument representing the same tree structure.\r\n */\r\nexport function domDocumentToXDocument(nativeNode: Document | Node): XDocument {\r\n if (nativeNode.nodeType === DOM_DOCUMENT_NODE) {\r\n const xDoc = new XDocument();\r\n const childNodes = nativeNode.childNodes;\r\n for (let i = 0; i < childNodes.length; i++) {\r\n const converted = convertNode(childNodes[i], xDoc);\r\n if (converted) {\r\n converted.siblingPosition = xDoc.childNodes.length;\r\n xDoc.appendChild(converted);\r\n }\r\n }\r\n return xDoc;\r\n }\r\n\r\n // If a non-document node is passed, wrap it in an XDocument\r\n const xDoc = new XDocument();\r\n const converted = convertNode(nativeNode, xDoc);\r\n if (converted) {\r\n converted.siblingPosition = 0;\r\n xDoc.appendChild(converted);\r\n }\r\n return xDoc;\r\n}\r\n\r\nfunction convertNode(nativeNode: Node, ownerDoc: XDocument): XNode | null {\r\n switch (nativeNode.nodeType) {\r\n case DOM_ELEMENT_NODE: {\r\n const element = nativeNode as Element;\r\n const xNode = XNode.create(\r\n DOM_ELEMENT_NODE,\r\n element.nodeName,\r\n null,\r\n ownerDoc,\r\n element.namespaceURI\r\n );\r\n xNode.prefix = element.prefix || null;\r\n xNode.localName = element.localName || element.nodeName;\r\n\r\n // Convert attributes from NamedNodeMap to XNode children\r\n const attrs = element.attributes;\r\n for (let i = 0; i < attrs.length; i++) {\r\n const attr = attrs[i];\r\n const attrNode = XNode.create(\r\n DOM_ATTRIBUTE_NODE,\r\n attr.name,\r\n attr.value,\r\n xNode,\r\n attr.namespaceURI\r\n );\r\n attrNode.prefix = attr.prefix || null;\r\n attrNode.localName = attr.localName || attr.name;\r\n attrNode.parentNode = xNode;\r\n attrNode.siblingPosition = xNode.childNodes.length;\r\n xNode.appendChild(attrNode);\r\n }\r\n\r\n // Convert child nodes\r\n const childNodes = nativeNode.childNodes;\r\n for (let i = 0; i < childNodes.length; i++) {\r\n const converted = convertNode(childNodes[i], ownerDoc);\r\n if (converted) {\r\n converted.siblingPosition = xNode.childNodes.length;\r\n xNode.appendChild(converted);\r\n }\r\n }\r\n\r\n return xNode;\r\n }\r\n\r\n case DOM_TEXT_NODE:\r\n return XNode.create(DOM_TEXT_NODE, '#text', nativeNode.nodeValue || '', ownerDoc);\r\n\r\n case DOM_CDATA_SECTION_NODE:\r\n return XNode.create(DOM_CDATA_SECTION_NODE, '#cdata-section', nativeNode.nodeValue || '', ownerDoc);\r\n\r\n case DOM_COMMENT_NODE:\r\n return XNode.create(DOM_COMMENT_NODE, '#comment', nativeNode.nodeValue || '', ownerDoc);\r\n\r\n case DOM_PROCESSING_INSTRUCTION_NODE: {\r\n const pi = nativeNode as ProcessingInstruction;\r\n return XNode.create(DOM_PROCESSING_INSTRUCTION_NODE, pi.target, pi.data, ownerDoc);\r\n }\r\n\r\n case DOM_DOCUMENT_TYPE_NODE: {\r\n const dt = nativeNode as DocumentType;\r\n return XNode.create(DOM_DOCUMENT_TYPE_NODE, '#dtd-section', dt.name, ownerDoc);\r\n }\r\n\r\n case DOM_DOCUMENT_FRAGMENT_NODE: {\r\n const fragment = XNode.create(DOM_DOCUMENT_FRAGMENT_NODE, '#document-fragment', null, ownerDoc);\r\n const childNodes = nativeNode.childNodes;\r\n for (let i = 0; i < childNodes.length; i++) {\r\n const converted = convertNode(childNodes[i], ownerDoc);\r\n if (converted) {\r\n converted.siblingPosition = fragment.childNodes.length;\r\n fragment.appendChild(converted);\r\n }\r\n }\r\n return fragment;\r\n }\r\n\r\n default:\r\n return null;\r\n }\r\n}\r\n","// Copyright 2023-2026 Design Liquido\r\n// Copyright 2018 Johannes Wilm\r\n// Copyright 2005 Google Inc.\r\n// All Rights Reserved\r\n\r\nimport { XDocument } from \"./xdocument\";\r\nimport { XNode } from './xnode';\r\n\r\n// Wrapper around DOM methods so we can condense their invocations.\r\nexport function domGetAttributeValue(node: XNode, name: string) {\r\n return node.getAttributeValue(name);\r\n}\r\n\r\nexport function domSetAttribute(node: XNode, name: string, value: any) {\r\n return node.setAttribute(name, value);\r\n}\r\n\r\nexport function domAppendChild(node: XNode, child: any) {\r\n return node.appendChild(child);\r\n}\r\n\r\nexport function domCreateTextNode(node: XDocument, text: string) {\r\n return node.createTextNode(text);\r\n}\r\n\r\nexport function domCreateElement(doc: XDocument, name: string) {\r\n return doc.createElement(name);\r\n}\r\n\r\nexport function domCreateCDATASection(doc: XDocument, data: any) {\r\n return doc.createCDATASection(data);\r\n}\r\n\r\nexport function domCreateComment(doc: any, text: any) {\r\n return doc.createComment(text);\r\n}\r\n\r\nexport function domCreateDocumentFragment(doc: XDocument): XNode {\r\n return doc.createDocumentFragment();\r\n}\r\n\r\nexport function domCreateDTDSection(doc: XDocument, data: any) {\r\n return doc.createDTDSection(data);\r\n}\r\n\r\nexport function domCreateProcessingInstruction(doc: XDocument, target: string, data: any) {\r\n return doc.createProcessingInstruction(target, data);\r\n}\r\n\r\n//XDocument.prototype = new XNode(DOM_DOCUMENT_NODE, '#document');\r\n","/**\r\n * HTML Entity Decoder\r\n * Decodes HTML entities to their corresponding characters.\r\n * Replaces the 'he' dependency.\r\n */\r\n\r\n// Common HTML entities mapping\r\nconst NAMED_ENTITIES: { [key: string]: string } = {\r\n 'amp': '&',\r\n 'lt': '<',\r\n 'gt': '>',\r\n 'quot': '\"',\r\n 'apos': \"'\",\r\n 'nbsp': '\\u00A0',\r\n 'copy': '\\u00A9',\r\n 'reg': '\\u00AE',\r\n 'times': '\\u00D7',\r\n 'divide': '\\u00F7',\r\n 'euro': '\\u20AC',\r\n 'pound': '\\u00A3',\r\n 'yen': '\\u00A5',\r\n 'cent': '\\u00A2',\r\n 'sect': '\\u00A7',\r\n 'para': '\\u00B6',\r\n 'hellip': '\\u2026',\r\n 'middot': '\\u00B7',\r\n 'deg': '\\u00B0',\r\n};\r\n\r\n/**\r\n * Decode HTML entities in a string\r\n * Supports:\r\n * - Named entities: & < > " '\r\n * - Numeric entities: { or «\r\n */\r\nexport function htmlEntityDecode(text: string): string {\r\n if (!text) {\r\n return text;\r\n }\r\n\r\n // Replace named entities\r\n let result = text.replace(/&([a-zA-Z]+);/g, (match: string, entity: string) => {\r\n const lower = entity.toLowerCase();\r\n return NAMED_ENTITIES[lower] || match;\r\n });\r\n\r\n // Replace decimal numeric entities: {\r\n result = result.replace(/&#(\\d+);/g, (match: string, code: string) => {\r\n try {\r\n const num = parseInt(code, 10);\r\n return String.fromCharCode(num);\r\n } catch {\r\n return match;\r\n }\r\n });\r\n\r\n // Replace hexadecimal numeric entities: « or «\r\n result = result.replace(/&#[xX]([0-9a-fA-F]+);/g, (match: string, code: string) => {\r\n try {\r\n const num = parseInt(code, 16);\r\n return String.fromCharCode(num);\r\n } catch {\r\n return match;\r\n }\r\n });\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Encode text to HTML entities (basic implementation)\r\n */\r\nexport function htmlEntityEncode(text: string): string {\r\n if (!text) {\r\n return text;\r\n }\r\n\r\n return text\r\n .replace(/&/g, '&')\r\n .replace(/</g, '<')\r\n .replace(/>/g, '>')\r\n .replace(/\"/g, '"')\r\n .replace(/'/g, ''');\r\n}\r\n","import { htmlEntityDecode } from './html-entity-decoder';\r\n\r\nimport {\r\n DOM_ATTRIBUTE_NODE,\r\n DOM_CDATA_SECTION_NODE,\r\n DOM_COMMENT_NODE,\r\n DOM_DOCUMENT_FRAGMENT_NODE,\r\n DOM_DOCUMENT_NODE,\r\n DOM_DOCUMENT_TYPE_NODE,\r\n DOM_ELEMENT_NODE,\r\n DOM_PROCESSING_INSTRUCTION_NODE,\r\n DOM_TEXT_NODE\r\n} from '../constants';\r\nimport { domGetAttributeValue } from './functions';\r\nimport { XNode } from './xnode';\r\nimport { XDocument } from './xdocument';\r\nimport { XmlOutputOptions } from './xml-output-options';\r\nimport { XBrowserNode } from './xbrowser-node';\r\n\r\n/**\r\n * Returns the text value of a node; for nodes without children this\r\n * is the nodeValue, for nodes with children this is the concatenation\r\n * of the value of all children. Browser-specific optimizations are used by\r\n * default; they can be disabled by passing \"true\" in as the second parameter.\r\n * @param node The Node (not exactly a `XNode` here).\r\n * @param disallowBrowserSpecificOptimization A boolean, to avoid browser optimization.\r\n * @returns The XML value as a string.\r\n */\r\nexport function xmlValue(node: XNode, disallowBrowserSpecificOptimization: boolean = false): string {\r\n if (!node) {\r\n return '';\r\n }\r\n\r\n let ret = '';\r\n switch (node.nodeType) {\r\n case DOM_DOCUMENT_TYPE_NODE:\r\n return `<!DOCTYPE ${node.nodeValue}>`;\r\n case DOM_TEXT_NODE:\r\n case DOM_CDATA_SECTION_NODE:\r\n case DOM_ATTRIBUTE_NODE:\r\n return node.nodeValue;\r\n case DOM_ELEMENT_NODE:\r\n case DOM_DOCUMENT_NODE:\r\n case DOM_DOCUMENT_FRAGMENT_NODE:\r\n if (!disallowBrowserSpecificOptimization) {\r\n // Only returns something if node has either `innerText` or `textContent` (not an XNode).\r\n // IE, Safari, Opera, and friends (`innerText`)\r\n const browserNode = node as XBrowserNode;\r\n const innerText = browserNode.innerText;\r\n if (innerText !== undefined) {\r\n return innerText;\r\n }\r\n // Firefox (`textContent`)\r\n const textContent = browserNode.textContent;\r\n if (textContent !== undefined) {\r\n return textContent;\r\n }\r\n }\r\n\r\n const textNodes = node.childNodes.filter((n: XNode) => n.nodeType !== DOM_ATTRIBUTE_NODE);\r\n for (let i = 0; i < textNodes.length; ++i) {\r\n ret += xmlValue(textNodes[i]);\r\n }\r\n\r\n return ret;\r\n }\r\n}\r\n\r\n/**\r\n * The older version to obtain a XML value from a node.\r\n * For now, this form is only used to get text from attribute nodes, \r\n * and it should be removed in future versions.\r\n * @param node The attribute node.\r\n * @param disallowBrowserSpecificOptimization A boolean, to avoid browser optimization.\r\n * @returns The XML value as a string.\r\n */\r\nexport function xmlValueLegacyBehavior(node: XNode, disallowBrowserSpecificOptimization: boolean = false) {\r\n if (!node) {\r\n return '';\r\n }\r\n\r\n let returnedXmlString = '';\r\n switch (node.nodeType) {\r\n case DOM_ATTRIBUTE_NODE:\r\n case DOM_TEXT_NODE:\r\n returnedXmlString += node.nodeValue;\r\n break;\r\n case DOM_CDATA_SECTION_NODE:\r\n returnedXmlString += node.nodeValue;\r\n break;\r\n case DOM_DOCUMENT_NODE:\r\n case DOM_DOCUMENT_FRAGMENT_NODE:\r\n case DOM_ELEMENT_NODE:\r\n if (!disallowBrowserSpecificOptimization) {\r\n // IE, Safari, Opera, and friends\r\n const browserNode = node as XBrowserNode;\r\n const innerText = browserNode.innerText;\r\n if (innerText !== undefined) {\r\n return innerText;\r\n }\r\n // Firefox\r\n const textContent = browserNode.textContent;\r\n if (textContent !== undefined) {\r\n return textContent;\r\n }\r\n }\r\n\r\n const len = node.childNodes.length;\r\n for (let i = 0; i < len; ++i) {\r\n returnedXmlString += xmlValue(node.childNodes[i]);\r\n }\r\n\r\n break;\r\n }\r\n\r\n return returnedXmlString;\r\n}\r\n\r\n/**\r\n * Returns the representation of a node as XML text.\r\n * In general it is not used by XSLT, that uses `xmlTransformedText` instead.\r\n * @param {XNode} node The starting node.\r\n * @param {XmlOutputOptions} options XML output options.\r\n * @returns The XML string.\r\n * @see xmlTransformedText\r\n */\r\nexport function xmlText(\r\n node: XNode,\r\n options: XmlOutputOptions = {\r\n cData: true,\r\n escape: true,\r\n selfClosingTags: true,\r\n outputMethod: 'xml'\r\n }\r\n) {\r\n const buffer: string[] = [];\r\n xmlTextRecursive(node, buffer, options);\r\n return buffer.join('');\r\n}\r\n\r\n/**\r\n * The recursive logic to transform a node in XML text.\r\n * It can be considered legacy, since it does not work with transformed nodes, and\r\n * probably will be removed in the future.\r\n * @param {XNode} node The node.\r\n * @param {string[]} buffer The buffer, that will represent the transformed XML text.\r\n * @param {XmlOutputOptions} options XML output options.\r\n */\r\nfunction xmlTextRecursive(node: XNode, buffer: string[], options: XmlOutputOptions) {\r\n if (node.nodeType == DOM_TEXT_NODE) {\r\n buffer.push(xmlEscapeText(node.nodeValue));\r\n } else if (node.nodeType == DOM_CDATA_SECTION_NODE) {\r\n if (options.cData) {\r\n buffer.push(node.nodeValue);\r\n } else {\r\n buffer.push(`<![CDATA[${node.nodeValue}]]>`);\r\n }\r\n } else if (node.nodeType == DOM_COMMENT_NODE) {\r\n buffer.push(`<!--${node.nodeValue}-->`);\r\n } else if (node.nodeType == DOM_ELEMENT_NODE) {\r\n buffer.push(`<${xmlFullNodeName(node)}`);\r\n\r\n for (let i = 0; i < node.childNodes.length; ++i) {\r\n const childNode = node.childNodes[i];\r\n if (!childNode || childNode.nodeType !== DOM_ATTRIBUTE_NODE) {\r\n continue;\r\n }\r\n\r\n if (childNode.nodeName && childNode.nodeValue) {\r\n buffer.push(` ${xmlFullNodeName(childNode)}=\"${xmlEscapeAttr(childNode.nodeValue)}\"`);\r\n }\r\n }\r\n\r\n if (node.childNodes.length === 0) {\r\n if (\r\n options.selfClosingTags ||\r\n (options.outputMethod === 'html' && ['hr', 'link'].includes(node.nodeName))\r\n ) {\r\n buffer.push('/>');\r\n } else {\r\n buffer.push(`></${xmlFullNodeName(node)}>`);\r\n }\r\n } else {\r\n buffer.push('>');\r\n for (let i = 0; i < node.childNodes.length; ++i) {\r\n xmlTextRecursive(node.childNodes[i], buffer, options);\r\n }\r\n buffer.push(`</${xmlFullNodeName(node)}>`);\r\n }\r\n } else if (node.nodeType == DOM_DOCUMENT_NODE || node.nodeType == DOM_DOCUMENT_FRAGMENT_NODE) {\r\n for (let i = 0; i < node.childNodes.length; ++i) {\r\n xmlTextRecursive(node.childNodes[i], buffer, options);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Returns the representation of a node as XML text.\r\n * @param {XNode} node The starting node.\r\n * @param {XmlOutputOptions} options XML output options.\r\n * @returns The XML string.\r\n */\r\nexport function xmlTransformedText(\r\n node: XNode,\r\n options: XmlOutputOptions = {\r\n cData: true,\r\n escape: true,\r\n selfClosingTags: true,\r\n outputMethod: 'xml'\r\n }\r\n) {\r\n const buffer: string[] = [];\r\n xmlTransformedTextRecursive(node, buffer, options);\r\n return buffer.join('');\r\n}\r\n\r\n/**\r\n * The recursive logic to transform a node in XML text.\r\n * @param {XNode} node The node.\r\n * @param {string[]} buffer The buffer, that will represent the transformed XML text.\r\n * @param {XmlOutputOptions} options XML output options.\r\n */\r\nfunction xmlTransformedTextRecursive(node: XNode, buffer: string[], options: XmlOutputOptions) {\r\n if (node.visited) return;\r\n const nodeType = node.nodeType\r\n const nodeValue = node.nodeValue;\r\n if (nodeType === DOM_TEXT_NODE) {\r\n // For text nodes created by xsl:text, don't trim whitespace\r\n // For other text nodes, skip whitespace-only ones\r\n const isFromXslText = node.fromXslText === true;\r\n if (node.nodeValue && (isFromXslText || node.nodeValue.trim() !== '')) {\r\n const finalText =\r\n node.escape && options.escape ? xmlEscapeText(node.nodeValue): xmlUnescapeText(node.nodeValue);\r\n buffer.push(finalText);\r\n }\r\n } else if (nodeType === DOM_CDATA_SECTION_NODE) {\r\n if (options.outputMethod === 'text') {\r\n // For text output, extract the raw content without CDATA markers\r\n buffer.push(nodeValue);\r\n } else if (options.cData) {\r\n buffer.push(xmlEscapeText(nodeValue));\r\n } else {\r\n buffer.push(`<![CDATA[${nodeValue}]]>`);\r\n }\r\n } else if (nodeType == DOM_COMMENT_NODE) {\r\n if (options.outputMethod !== 'text') {\r\n buffer.push(`<!-- ${nodeValue} -->`);\r\n }\r\n } else if (nodeType === DOM_PROCESSING_INSTRUCTION_NODE) {\r\n if (options.outputMethod !== 'text') {\r\n // Processing instruction: <?target data?>\r\n if (nodeValue && nodeValue.trim()) {\r\n buffer.push(`<?${node.nodeName} ${nodeValue}?>`);\r\n } else {\r\n buffer.push(`<?${node.nodeName}?>`);\r\n }\r\n }\r\n } else if (nodeType == DOM_ELEMENT_NODE) {\r\n if (options.outputMethod === 'text') {\r\n // For text output, only extract text content from elements\r\n xmlElementLogicTextOnly(node, buffer, options);\r\n } else {\r\n // If node didn't have a transformed name, but its children\r\n // had transformations, children should be present at output.\r\n // This is called here \"muted logic\".\r\n if (node.nodeName !== null && node.nodeName !== undefined) {\r\n xmlElementLogicTrivial(node, buffer, options);\r\n } else {\r\n xmlElementLogicMuted(node, buffer, options);\r\n }\r\n }\r\n } else if (nodeType === DOM_DOCUMENT_NODE || nodeType === DOM_DOCUMENT_FRAGMENT_NODE) {\r\n let childNodes = node.firstChild ? [] : node.childNodes;\r\n if (node.firstChild) {\r\n let child = node.firstChild;\r\n while (child) {\r\n childNodes.push(child);\r\n child = child.nextSibling;\r\n }\r\n }\r\n childNodes.sort((a, b) => a.siblingPosition - b.siblingPosition);\r\n\r\n for (let i = 0; i < childNodes.length; ++i) {\r\n xmlTransformedTextRecursive(childNodes[i], buffer, options);\r\n }\r\n }\r\n\r\n node.visited = true;\r\n}\r\n\r\n/**\r\n * XML element output, trivial logic.\r\n * @param node The XML node.\r\n * @param buffer The XML buffer.\r\n * @param cdata If using CDATA configuration.\r\n */\r\nfunction xmlElementLogicTrivial(node: XNode, buffer: string[], options: XmlOutputOptions) {\r\n buffer.push(`<${xmlFullNodeName(node)}`);\r\n\r\n let attributes: XNode[] = [];\r\n if (node.firstChild) {\r\n let child = node.firstChild;\r\n while (child) {\r\n if (child.nodeType === DOM_ATTRIBUTE_NODE) {\r\n attributes.push(child);\r\n }\r\n child = child.nextSibling;\r\n }\r\n }\r\n if (attributes.length === 0) {\r\n attributes = node.childNodes.filter((n) => n.nodeType === DOM_ATTRIBUTE_NODE);\r\n }\r\n\r\n for (let i = 0; i < attributes.length; ++i) {\r\n const attribute = attributes[i];\r\n if (!attribute) {\r\n continue;\r\n }\r\n\r\n // In HTML output mode, skip only XHTML namespace declarations (redundant in HTML)\r\n if (options.outputMethod === 'html' &&\r\n attribute.nodeName === 'xmlns' &&\r\n attribute.nodeValue === 'http://www.w3.org/1999/xhtml') {\r\n continue;\r\n }\r\n\r\n if (attribute.nodeName && attribute.nodeValue !== null && attribute.nodeValue !== undefined) {\r\n buffer.push(` ${xmlFullNodeName(attribute)}=\"${xmlEscapeAttr(attribute.nodeValue)}\"`);\r\n }\r\n }\r\n\r\n let childNodes: XNode[] = [];\r\n if (node.firstChild) {\r\n let child = node.firstChild;\r\n while (child) {\r\n if (child.nodeType !== DOM_ATTRIBUTE_NODE) {\r\n childNodes.push(child);\r\n }\r\n child = child.nextSibling;\r\n }\r\n }\r\n if (childNodes.length === 0) {\r\n childNodes = node.childNodes.filter((n) => n.nodeType !== DOM_ATTRIBUTE_NODE);\r\n }\r\n\r\n childNodes = childNodes.sort((a, b) => a.siblingPosition - b.siblingPosition);\r\n if (childNodes.length === 0) {\r\n if (options.outputMethod === 'html' && ['hr', 'link', 'meta'].includes(node.nodeName)) {\r\n buffer.push('>');\r\n } else if (options.selfClosingTags) {\r\n buffer.push('/>');\r\n } else {\r\n buffer.push(`></${xmlFullNodeName(node)}>`);\r\n }\r\n } else {\r\n buffer.push('>');\r\n for (let i = 0; i < childNodes.length; ++i) {\r\n xmlTransformedTextRecursive(childNodes[i], buffer, options);\r\n }\r\n buffer.push(`</${xmlFullNodeName(node)}>`);\r\n }\r\n}\r\n\r\n/**\r\n * XML element output, muted logic.\r\n * In other words, this element should not be printed, but its\r\n * children can be printed if they have transformed values.\r\n * @param node The XML node.\r\n * @param buffer The XML buffer.\r\n * @param cdata If using CDATA configuration.\r\n */\r\nfunction xmlElementLogicMuted(node: XNode, buffer: any[], options: XmlOutputOptions) {\r\n let childNodes: XNode[] = [];\r\n if (node.firstChild) {\r\n let child = node.firstChild;\r\n while (child) {\r\n childNodes.push(child);\r\n child = child.nextSibling;\r\n }\r\n } else {\r\n childNodes = node.childNodes;\r\n }\r\n childNodes = childNodes.sort((a, b) => a.siblingPosition - b.siblingPosition);\r\n for (let i = 0; i < childNodes.length; ++i) {\r\n xmlTransformedTextRecursive(childNodes[i], buffer, options);\r\n }\r\n}\r\n\r\n/**\r\n * XML element output for text mode - extracts only text content without tags.\r\n * @param node The XML node.\r\n * @param buffer The output buffer.\r\n * @param options XML output options.\r\n */\r\nfunction xmlElementLogicTextOnly(node: XNode, buffer: string[], options: XmlOutputOptions) {\r\n let childNodes: XNode[] = [];\r\n if (node.firstChild) {\r\n let child = node.firstChild;\r\n while (child) {\r\n childNodes.push(child);\r\n child = child.nextSibling;\r\n }\r\n } else {\r\n childNodes = node.childNodes;\r\n }\r\n childNodes = childNodes.sort((a, b) => a.siblingPosition - b.siblingPosition);\r\n for (let i = 0; i < childNodes.length; ++i) {\r\n xmlTransformedTextRecursive(childNodes[i], buffer, options);\r\n }\r\n}\r\n\r\n/**\r\n * Gets the full node name.\r\n * When namespace is set, the node name is `namespace:node`.\r\n * @param node The node.\r\n * @returns The full node name as a string.\r\n */\r\nfunction xmlFullNodeName(node: XNode): string {\r\n const nodeName = node.nodeName;\r\n if (node.prefix && nodeName.indexOf(`${node.prefix}:`) != 0) {\r\n return `${node.prefix}:${nodeName}`;\r\n }\r\n\r\n return nodeName;\r\n}\r\n\r\n/**\r\n * Replaces HTML/XML entities to their literal characters.\r\n * Currently implementing only tag delimiters.\r\n * @param text The text to be transformed.\r\n * @returns The unescaped text.\r\n */\r\nexport function xmlUnescapeText(text: string): string {\r\n return `${text}`.replace(/</g, '<').replace(/>/g, '>');\r\n}\r\n\r\n/**\r\n * Escape XML special markup characters: tag delimiter <, >, and entity\r\n * reference start delimiter &. The escaped string can be used in XML\r\n * text portions (i.e. between tags).\r\n * @param s The string to be escaped.\r\n * @returns The escaped string.\r\n */\r\nexport function xmlEscapeText(s: string): string {\r\n return `${s}`\r\n .replace(/&/g, '&')\r\n .replace(/&amp;/g, '&')\r\n .replace(/</g, '<')\r\n .replace(/>/g, '>');\r\n}\r\n\r\n/**\r\n * Escape XML special markup characters: tag delimiter, <, >, entity\r\n * reference start delimiter &, and double quotes (\"). The escaped string can be\r\n * used in double quoted XML attribute value portions (i.e. in\r\n * attributes within start tags).\r\n * @param s The string to be escaped.\r\n * @returns The escaped string.\r\n */\r\nfunction xmlEscapeAttr(s: string): string {\r\n return xmlEscapeText(s).replace(/\"/g, '"');\r\n}\r\n\r\n/**\r\n * Wrapper function to access attribute values of template element\r\n * nodes. Currently this calls htmlEntityDecode because in some DOM\r\n * implementations the return value of node.getAttributeValue()\r\n * contains unresolved XML entities, although the DOM spec requires\r\n * that entity references are resolved by the DOM.\r\n * @param node TODO\r\n * @param name TODO\r\n * @returns TODO\r\n */\r\nexport function xmlGetAttribute(node: XNode, name: string): string {\r\n // TODO(mesch): This should not be necessary if the DOM is working\r\n // correctly. The DOM is responsible for resolving entities, not the\r\n // application.\r\n const value = domGetAttributeValue(node, name);\r\n if (value) {\r\n return htmlEntityDecode(value);\r\n }\r\n\r\n return value;\r\n}\r\n\r\n/**\r\n * Wrapper function to access the owner document uniformly for document\r\n * and other nodes: for the document node, the owner document is the\r\n * node itself, for all others it's the ownerDocument property.\r\n *\r\n * @param {XNode} node\r\n * @return {XDocument}\r\n */\r\nexport function xmlOwnerDocument(node: XNode): XDocument {\r\n if (node === null || node === undefined) {\r\n throw new Error('Node has no valid owner document.');\r\n }\r\n\r\n if (node.nodeType === DOM_DOCUMENT_NODE) {\r\n return node as XDocument;\r\n }\r\n\r\n return xmlOwnerDocument(node.ownerDocument);\r\n}\r\n\r\n/**\r\n * Converts an XNode to a JSON-serializable object.\r\n * Uses JSON.parse(JSON.stringify()) approach to filter out unwanted properties.\r\n * @param node The node to convert.\r\n * @returns A JSON-serializable object representation of the node.\r\n */\r\nfunction nodeToJsonObject(node: XNode): any {\r\n if (!node) {\r\n return null;\r\n }\r\n\r\n const nodeType = node.nodeType;\r\n\r\n // Handle text nodes\r\n if (nodeType === DOM_TEXT_NODE || nodeType === DOM_CDATA_SECTION_NODE) {\r\n const text = node.nodeValue ? node.nodeValue.trim() : '';\r\n return text.length > 0 ? text : null;\r\n }\r\n\r\n // Handle comment nodes\r\n if (nodeType === DOM_COMMENT_NODE) {\r\n return null; // Skip comments in JSON output\r\n }\r\n\r\n // Handle document and document fragments\r\n if (nodeType === DOM_DOCUMENT_NODE || nodeType === DOM_DOCUMENT_FRAGMENT_NODE) {\r\n const children = node.childNodes || [];\r\n const childObjects = [];\r\n \r\n for (let i = 0; i < children.length; i++) {\r\n const child = children[i];\r\n const childObj = nodeToJsonObject(child);\r\n if (childObj !== null) {\r\n childObjects.push(childObj);\r\n }\r\n }\r\n\r\n if (childObjects.length === 0) {\r\n return null;\r\n } else if (childObjects.length === 1) {\r\n return childObjects[0];\r\n } else {\r\n return childObjects;\r\n }\r\n }\r\n\r\n // Handle element nodes\r\n if (nodeType === DOM_ELEMENT_NODE) {\r\n const obj: any = {};\r\n const element = node as any;\r\n const hasAttributes = element.attributes && element.attributes.length > 0;\r\n \r\n // Add attributes with @ prefix\r\n if (hasAttributes) {\r\n for (let i = 0; i < element.attributes.length; i++) {\r\n const attr = element.attributes[i];\r\n obj['@' + attr.nodeName] = attr.nodeValue;\r\n }\r\n }\r\n\r\n // Process child nodes\r\n const children = element.childNodes || [];\r\n let textContent = '';\r\n let hasElementChildren = false;\r\n const childElements: { [key: string]: any } = {};\r\n\r\n for (let i = 0; i < children.length; i++) {\r\n const child = children[i];\r\n const childType = child.nodeType;\r\n\r\n if (childType === DOM_TEXT_NODE || childType === DOM_CDATA_SECTION_NODE) {\r\n const text = child.nodeValue ? child.nodeValue.trim() : '';\r\n if (text.length > 0) {\r\n textContent += text;\r\n }\r\n } else if (childType === DOM_ELEMENT_NODE) {\r\n hasElementChildren = true;\r\n const childElement = child as any;\r\n const childName = childElement.localName || childElement.nodeName;\r\n const childObj = nodeToJsonObject(child);\r\n\r\n if (childObj !== null) {\r\n if (childElements[childName]) {\r\n // Multiple elements with same name - convert to array\r\n if (!Array.isArray(childElements[childName])) {\r\n childElements[childName] = [childElements[childName]];\r\n }\r\n childElements[childName].push(childObj);\r\n } else {\r\n childElements[childName] = childObj;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Add child elements to object\r\n Object.assign(obj, childElements);\r\n\r\n // Add text content if no element children and has text\r\n if (!hasElementChildren && textContent.length > 0) {\r\n if (!hasAttributes && Object.keys(childElements).length === 0) {\r\n // Only text, no attributes or element children\r\n return textContent;\r\n } else {\r\n // Has attributes and/or element children plus text\r\n obj['#text'] = textContent;\r\n }\r\n }\r\n\r\n // If completely empty (no attributes, no children, no text), return null\r\n if (Object.keys(obj).length === 0) {\r\n return null;\r\n }\r\n\r\n return obj;\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Detects the most appropriate output format for a node based on its structure.\r\n * This implements XSLT 3.1 adaptive output behavior.\r\n * @param node The node to analyze.\r\n * @returns The detected output method: 'text' or 'xml'.\r\n */\r\nexport function detectAdaptiveOutputFormat(node: XNode): 'text' | 'xml' {\r\n if (!node) {\r\n return 'xml';\r\n }\r\n\r\n const nodeType = node.nodeType;\r\n\r\n // If it's a document or fragment, check its children\r\n if (nodeType === DOM_DOCUMENT_NODE || nodeType === DOM_DOCUMENT_FRAGMENT_NODE) {\r\n const children = node.childNodes || [];\r\n let elementCount = 0;\r\n let textCount = 0;\r\n let hasSignificantText = false;\r\n\r\n for (let i = 0; i < children.length; i++) {\r\n const child = children[i];\r\n if (child.nodeType === DOM_ELEMENT_NODE) {\r\n elementCount++;\r\n } else if (child.nodeType === DOM_TEXT_NODE) {\r\n const text = child.nodeValue ? child.nodeValue.trim() : '';\r\n if (text.length > 0) {\r\n textCount++;\r\n hasSignificantText = true;\r\n }\r\n }\r\n }\r\n\r\n // If there's only text content and no elements, use text output\r\n if (elementCount === 0 && hasSignificantText) {\r\n return 'text';\r\n }\r\n // Otherwise, use XML output\r\n return 'xml';\r\n }\r\n\r\n // If it's a single text node with content, use text output\r\n if (nodeType === DOM_TEXT_NODE || nodeType === DOM_CDATA_SECTION_NODE) {\r\n const text = node.nodeValue ? node.nodeValue.trim() : '';\r\n if (text.length > 0) {\r\n return 'text';\r\n }\r\n }\r\n\r\n // For elements and other node types, use XML output\r\n return 'xml';\r\n}\r\n\r\n/**\r\n * Converts an XML document to a JSON string.\r\n * The root element becomes the top-level object.\r\n * Element attributes are prefixed with '@'.\r\n * Text nodes become the '#text' property or the value itself.\r\n * @param node The root node to convert.\r\n * @returns A JSON string representation of the document.\r\n */\r\nexport function xmlToJson(node: XNode): string {\r\n if (!node) {\r\n return '{}';\r\n }\r\n\r\n // For document nodes, find the root element and wrap it\r\n let rootElement: XNode = node;\r\n if (node.nodeType === DOM_DOCUMENT_NODE || node.nodeType === DOM_DOCUMENT_FRAGMENT_NODE) {\r\n const children = node.childNodes || [];\r\n for (let i = 0; i < children.length; i++) {\r\n if (children[i].nodeType === DOM_ELEMENT_NODE) {\r\n rootElement = children[i];\r\n break;\r\n }\r\n }\r\n }\r\n\r\n // Convert the root element to JSON\r\n const element = rootElement as any;\r\n const rootName = element.localName || element.nodeName;\r\n const jsonObj: any = {};\r\n \r\n // Build the root element object\r\n const elementContent = nodeToJsonObject(rootElement);\r\n \r\n if (elementContent === null) {\r\n // Empty root element\r\n jsonObj[rootName] = {};\r\n } else if (typeof elementContent === 'object' && !Array.isArray(elementContent)) {\r\n // Object with properties/attributes\r\n jsonObj[rootName] = elementContent;\r\n } else {\r\n // Simple text content\r\n jsonObj[rootName] = elementContent;\r\n }\r\n\r\n // Use JSON.stringify to clean up the object and then JSON.parse and stringify again\r\n // This ensures we only have plain properties without circular references\r\n try {\r\n const cleaned = JSON.parse(JSON.stringify(jsonObj));\r\n return JSON.stringify(cleaned);\r\n } catch (error) {\r\n // Fallback if stringification fails\r\n return JSON.stringify(jsonObj);\r\n }\r\n}\r\n","// Copyright 2023-2026 Design Liquido\r\n// Copyright 2018 Johannes Wilm\r\n// Copyright 2006 Google Inc.\r\n// All Rights Reserved\r\n//\r\n// Defines regular expression patterns to extract XML tokens from string.\r\n// See <http://www.w3.org/TR/REC-xml/#sec-common-syn>,\r\n// <http://www.w3.org/TR/xml11/#sec-common-syn> and\r\n// <http://www.w3.org/TR/REC-xml-names/#NT-NCName> for the specifications.\r\n//\r\n// Original author: Junji Takagi <jtakagi@google.com>\r\n\r\n// Common tokens in XML 1.0 and XML 1.1.\r\n\r\nconst XML_S = '[ \\t\\r\\n]+';\r\nconst XML_EQ = `(${XML_S})?=(${XML_S})?`;\r\nexport const XML_CHAR_REF = '&#[0-9]+;|&#x[0-9a-fA-F]+;';\r\n\r\n// XML 1.0 tokens.\r\n\r\nexport const XML10_VERSION_INFO = `${XML_S}version${XML_EQ}(\"1\\\\.0\"|'1\\\\.0')`;\r\nconst XML10_BASE_CHAR =\r\n '\\u0041-\\u005a\\u0061-\\u007a\\u00c0-\\u00d6\\u00d8-\\u00f6\\u00f8-\\u00ff' +\r\n '\\u0100-\\u0131\\u0134-\\u013e\\u0141-\\u0148\\u014a-\\u017e\\u0180-\\u01c3' +\r\n '\\u01cd-\\u01f0\\u01f4-\\u01f5\\u01fa-\\u0217\\u0250-\\u02a8\\u02bb-\\u02c1\\u0386' +\r\n '\\u0388-\\u038a\\u038c\\u038e-\\u03a1\\u03a3-\\u03ce\\u03d0-\\u03d6\\u03da\\u03dc' +\r\n '\\u03de\\u03e0\\u03e2-\\u03f3\\u0401-\\u040c\\u040e-\\u044f\\u0451-\\u045c' +\r\n '\\u045e-\\u0481\\u0490-\\u04c4\\u04c7-\\u04c8\\u04cb-\\u04cc\\u04d0-\\u04eb' +\r\n '\\u04ee-\\u04f5\\u04f8-\\u04f9\\u0531-\\u0556\\u0559\\u0561-\\u0586\\u05d0-\\u05ea' +\r\n '\\u05f0-\\u05f2\\u0621-\\u063a\\u0641-\\u064a\\u0671-\\u06b7\\u06ba-\\u06be' +\r\n '\\u06c0-\\u06ce\\u06d0-\\u06d3\\u06d5\\u06e5-\\u06e6\\u0905-\\u0939\\u093d' +\r\n '\\u0958-\\u0961\\u0985-\\u098c\\u098f-\\u0990\\u0993-\\u09a8\\u09aa-\\u09b0\\u09b2' +\r\n '\\u09b6-\\u09b9\\u09dc-\\u09dd\\u09df-\\u09e1\\u09f0-\\u09f1\\u0a05-\\u0a0a' +\r\n '\\u0a0f-\\u0a10\\u0a13-\\u0a28\\u0a2a-\\u0a30\\u0a32-\\u0a33\\u0a35-\\u0a36' +\r\n '\\u0a38-\\u0a39\\u0a59-\\u0a5c\\u0a5e\\u0a72-\\u0a74\\u0a85-\\u0a8b\\u0a8d' +\r\n '\\u0a8f-\\u0a91\\u0a93-\\u0aa8\\u0aaa-\\u0ab0\\u0ab2-\\u0ab3\\u0ab5-\\u0ab9' +\r\n '\\u0abd\\u0ae0\\u0b05-\\u0b0c\\u0b0f-\\u0b10\\u0b13-\\u0b28\\u0b2a-\\u0b30' +\r\n '\\u0b32-\\u0b33\\u0b36-\\u0b39\\u0b3d\\u0b5c-\\u0b5d\\u0b5f-\\u0b61\\u0b85-\\u0b8a' +\r\n '\\u0b8e-\\u0b90\\u0b92-\\u0b95\\u0b99-\\u0b9a\\u0b9c\\u0b9e-\\u0b9f\\u0ba3-\\u0ba4' +\r\n '\\u0ba8-\\u0baa\\u0bae-\\u0bb5\\u0bb7-\\u0bb9\\u0c05-\\u0c0c\\u0c0e-\\u0c10' +\r\n '\\u0c12-\\u0c28\\u0c2a-\\u0c33\\u0c35-\\u0c39\\u0c60-\\u0c61\\u0c85-\\u0c8c' +\r\n '\\u0c8e-\\u0c90\\u0c92-\\u0ca8\\u0caa-\\u0cb3\\u0cb5-\\u0cb9\\u0cde\\u0ce0-\\u0ce1' +\r\n '\\u0d05-\\u0d0c\\u0d0e-\\u0d10\\u0d12-\\u0d28\\u0d2a-\\u0d39\\u0d60-\\u0d61' +\r\n '\\u0e01-\\u0e2e\\u0e30\\u0e32-\\u0e33\\u0e40-\\u0e45\\u0e81-\\u0e82\\u0e84' +\r\n '\\u0e87-\\u0e88\\u0e8a\\u0e8d\\u0e94-\\u0e97\\u0e99-\\u0e9f\\u0ea1-\\u0ea3\\u0ea5' +\r\n '\\u0ea7\\u0eaa-\\u0eab\\u0ead-\\u0eae\\u0eb0\\u0eb2-\\u0eb3\\u0ebd\\u0ec0-\\u0ec4' +\r\n '\\u0f40-\\u0f47\\u0f49-\\u0f69\\u10a0-\\u10c5\\u10d0-\\u10f6\\u1100\\u1102-\\u1103' +\r\n '\\u1105-\\u1107\\u1109\\u110b-\\u110c\\u110e-\\u1112\\u113c\\u113e\\u1140\\u114c' +\r\n '\\u114e\\u1150\\u1154-\\u1155\\u1159\\u115f-\\u1161\\u1163\\u1165\\u1167\\u1169' +\r\n '\\u116d-\\u116e\\u1172-\\u1173\\u1175\\u119e\\u11a8\\u11ab\\u11ae-\\u11af' +\r\n '\\u11b7-\\u11b8\\u11ba\\u11bc-\\u11c2\\u11eb\\u11f0\\u11f9\\u1e00-\\u1e9b' +\r\n '\\u1ea0-\\u1ef9\\u1f00-\\u1f15\\u1f18-\\u1f1d\\u1f20-\\u1f45\\u1f48-\\u1f4d' +\r\n '\\u1f50-\\u1f57\\u1f59\\u1f5b\\u1f5d\\u1f5f-\\u1f7d\\u1f80-\\u1fb4\\u1fb6-\\u1fbc' +\r\n '\\u1fbe\\u1fc2-\\u1fc4\\u1fc6-\\u1fcc\\u1fd0-\\u1fd3\\u1fd6-\\u1fdb\\u1fe0-\\u1fec' +\r\n '\\u1ff2-\\u1ff4\\u1ff6-\\u1ffc\\u2126\\u212a-\\u212b\\u212e\\u2180-\\u2182' +\r\n '\\u3041-\\u3094\\u30a1-\\u30fa\\u3105-\\u312c\\uac00-\\ud7a3';\r\nconst XML10_IDEOGRAPHIC = '\\u4e00-\\u9fa5\\u3007\\u3021-\\u3029';\r\nconst XML10_COMBINING_CHAR =\r\n '\\u0300-\\u0345\\u0360-\\u0361\\u0483-\\u0486\\u0591-\\u05a1\\u05a3-\\u05b9' +\r\n '\\u05bb-\\u05bd\\u05bf\\u05c1-\\u05c2\\u05c4\\u064b-\\u0652\\u0670\\u06d6-\\u06dc' +\r\n '\\u06dd-\\u06df\\u06e0-\\u06e4\\u06e7-\\u06e8\\u06ea-\\u06ed\\u0901-\\u0903\\u093c' +\r\n '\\u093e-\\u094c\\u094d\\u0951-\\u0954\\u0962-\\u0963\\u0981-\\u0983\\u09bc\\u09be' +\r\n '\\u09bf\\u09c0-\\u09c4\\u09c7-\\u09c8\\u09cb-\\u09cd\\u09d7\\u09e2-\\u09e3\\u0a02' +\r\n '\\u0a3c\\u0a3e\\u0a3f\\u0a40-\\u0a42\\u0a47-\\u0a48\\u0a4b-\\u0a4d\\u0a70-\\u0a71' +\r\n '\\u0a81-\\u0a83\\u0abc\\u0abe-\\u0ac5\\u0ac7-\\u0ac9\\u0acb-\\u0acd\\u0b01-\\u0b03' +\r\n '\\u0b3c\\u0b3e-\\u0b43\\u0b47-\\u0b48\\u0b4b-\\u0b4d\\u0b56-\\u0b57\\u0b82-\\u0b83' +\r\n '\\u0bbe-\\u0bc2\\u0bc6-\\u0bc8\\u0bca-\\u0bcd\\u0bd7\\u0c01-\\u0c03\\u0c3e-\\u0c44' +\r\n '\\u0c46-\\u0c48\\u0c4a-\\u0c4d\\u0c55-\\u0c56\\u0c82-\\u0c83\\u0cbe-\\u0cc4' +\r\n '\\u0cc6-\\u0cc8\\u0cca-\\u0ccd\\u0cd5-\\u0cd6\\u0d02-\\u0d03\\u0d3e-\\u0d43' +\r\n '\\u0d46-\\u0d48\\u0d4a-\\u0d4d\\u0d57\\u0e31\\u0e34-\\u0e3a\\u0e47-\\u0e4e\\u0eb1' +\r\n '\\u0eb4-\\u0eb9\\u0ebb-\\u0ebc\\u0ec8-\\u0ecd\\u0f18-\\u0f19\\u0f35\\u0f37\\u0f39' +\r\n '\\u0f3e\\u0f3f\\u0f71-\\u0f84\\u0f86-\\u0f8b\\u0f90-\\u0f95\\u0f97\\u0f99-\\u0fad' +\r\n '\\u0fb1-\\u0fb7\\u0fb9\\u20d0-\\u20dc\\u20e1\\u302a-\\u302f\\u3099\\u309a';\r\nconst XML10_DIGIT =\r\n '\\u0030-\\u0039\\u0660-\\u0669\\u06f0-\\u06f9\\u0966-\\u096f\\u09e6-\\u09ef' +\r\n '\\u0a66-\\u0a6f\\u0ae6-\\u0aef\\u0b66-\\u0b6f\\u0be7-\\u0bef\\u0c66-\\u0c6f' +\r\n '\\u0ce6-\\u0cef\\u0d66-\\u0d6f\\u0e50-\\u0e59\\u0ed0-\\u0ed9\\u0f20-\\u0f29';\r\nconst XML10_EXTENDER = '\\u00b7\\u02d0\\u02d1\\u0387\\u0640\\u0e46\\u0ec6\\u3005\\u3031-\\u3035' + '\\u309d-\\u309e\\u30fc-\\u30fe';\r\nconst XML10_LETTER = XML10_BASE_CHAR + XML10_IDEOGRAPHIC;\r\nconst XML10_NAME_CHAR = `${XML10_LETTER + XML10_DIGIT}\\\\._:${XML10_COMBINING_CHAR}${XML10_EXTENDER}-`;\r\nexport const XML10_NAME = `[${XML10_LETTER}_:][${XML10_NAME_CHAR}]*`;\r\n\r\nexport const XML10_ENTITY_REF = `&${XML10_NAME};`;\r\nconst XML10_REFERENCE = `${XML10_ENTITY_REF}|${XML_CHAR_REF}`;\r\nexport const XML10_ATT_VALUE = `\"(([^<&\"]|${XML10_REFERENCE})*)\"|'(([^<&']|${XML10_REFERENCE})*)'`;\r\nexport const XML10_ATTRIBUTE = `(${XML10_NAME})${XML_EQ}(${XML10_ATT_VALUE})`;\r\n\r\n// XML 1.1 tokens.\r\n// TODO(jtakagi): NameStartChar also includes \\u10000-\\ueffff.\r\n// ECMAScript Language Specifiction defines UnicodeEscapeSequence as\r\n// \"\\u HexDigit HexDigit HexDigit HexDigit\" and we may need to use\r\n// surrogate pairs, but any browser doesn't support surrogate paris in\r\n// character classes of regular expression, so avoid including them for now.\r\n\r\nexport const XML11_VERSION_INFO = `${XML_S}version${XML_EQ}(\"1\\\\.1\"|'1\\\\.1')`;\r\nconst XML11_NAME_START_CHAR =\r\n ':A-Z_a-z\\u00c0-\\u00d6\\u00d8-\\u00f6\\u00f8-\\u02ff\\u0370-\\u037d' +\r\n '\\u037f-\\u1fff\\u200c-\\u200d\\u2070-\\u218f\\u2c00-\\u2fef\\u3001-\\ud7ff' +\r\n '\\uf900-\\ufdcf\\ufdf0-\\ufffd';\r\nconst XML11_NAME_CHAR = XML11_NAME_START_CHAR + '\\\\.0-9\\u00b7\\u0300-\\u036f\\u203f-\\u2040-';\r\nexport const XML11_NAME = `[${XML11_NAME_START_CHAR}][${XML11_NAME_CHAR}]*`;\r\n\r\nexport const XML11_ENTITY_REF = `&${XML11_NAME};`;\r\nconst XML11_REFERENCE = `${XML11_ENTITY_REF}|${XML_CHAR_REF}`;\r\nexport const XML11_ATT_VALUE = `\"(([^<&\"]|${XML11_REFERENCE})*)\"|'(([^<&']|${XML11_REFERENCE})*)'`;\r\nexport const XML11_ATTRIBUTE = `(${XML11_NAME})${XML_EQ}(${XML11_ATT_VALUE})`;\r\n\r\n// XML Namespace tokens.\r\n// Used in XML parser and XPath parser.\r\n\r\nconst XML_NC_NAME_CHAR = `${XML10_LETTER + XML10_DIGIT}\\\\._${XML10_COMBINING_CHAR}${XML10_EXTENDER}-`;\r\nexport const XML_NC_NAME = `[${XML10_LETTER}_][${XML_NC_NAME_CHAR}]*`;\r\n","import { htmlEntityDecode } from './html-entity-decoder';\r\nimport {\r\n domCreateElement,\r\n domSetAttribute,\r\n domAppendChild,\r\n domCreateTextNode,\r\n domCreateComment,\r\n domCreateCDATASection,\r\n domCreateDTDSection\r\n} from './functions';\r\n\r\nimport { XDocument } from './xdocument';\r\nimport {\r\n XML10_ATTRIBUTE,\r\n XML10_NAME,\r\n XML10_VERSION_INFO,\r\n XML11_ATTRIBUTE,\r\n XML11_NAME,\r\n XML11_VERSION_INFO\r\n} from './xmltoken';\r\nimport { XNode } from './xnode';\r\nimport { DOM_ATTRIBUTE_NODE } from '../constants';\r\n\r\n/**\r\n * Original author: Steffen Meschkat <mesch@google.com> (the `xmlParse` function,\r\n * now `xmlStrictParse`).\r\n *\r\n * An XML parse and a minimal DOM implementation that just supports\r\n * the subset of the W3C DOM that is used in the XSLT implementation.\r\n */\r\nexport class XmlParser {\r\n regexEmpty = /\\/$/;\r\n\r\n XML10_TAGNAME_REGEXP = new RegExp(`^(${XML10_NAME})`);\r\n XML10_ATTRIBUTE_REGEXP = new RegExp(XML10_ATTRIBUTE, 'g');\r\n\r\n XML11_TAGNAME_REGEXP = new RegExp(`^(${XML11_NAME})`);\r\n XML11_ATTRIBUTE_REGEXP = new RegExp(XML11_ATTRIBUTE, 'g');\r\n\r\n lenientHtmlTags = ['hr', 'link', 'meta'];\r\n\r\n /**\r\n * The entry point for this parser.\r\n * It verifies whether the document seems to be HTML.\r\n * HTML is a special case if XML and it should be parsed differently.\r\n * @param xmlOrHtml The XML or HTML content to be parsed.\r\n * @returns A DOM document.\r\n */\r\n xmlParse(xmlOrHtml: string): XDocument {\r\n if (xmlOrHtml.toUpperCase().startsWith('<!DOCTYPE HTML')) {\r\n return this.htmlParse(xmlOrHtml);\r\n }\r\n\r\n return this.xmlStrictParse(xmlOrHtml);\r\n }\r\n\r\n /**\r\n * Given an XNode, returns an object mapping prefixes to their corresponding namespaces in its scope.\r\n * Default namespace is treated as if its prefix were the empty string.\r\n * @param node The Node.\r\n * @returns An object with prefixes and namespace URLs.\r\n */\r\n private namespaceMapAt(node: XNode): { [prefix: string]: string } {\r\n const map = {\r\n // reserved namespaces: https://www.w3.org/TR/REC-xml-names/#xmlReserved\r\n xmlns: 'http://www.w3.org/2000/xmlns/',\r\n xml: 'http://www.w3.org/XML/1998/namespace'\r\n };\r\n let n = node;\r\n while (n !== null) {\r\n for (let i = 0; i < n.childNodes.length; i++) {\r\n const childNode = n.childNodes[i];\r\n if (childNode.nodeType !== DOM_ATTRIBUTE_NODE) {\r\n continue;\r\n }\r\n\r\n if (childNode.nodeName.startsWith('xmlns:')) {\r\n const prefix = childNode.nodeName.split(':')[1];\r\n if (!(prefix in map)) map[prefix] = childNode.nodeValue;\r\n } else if (childNode.nodeName == 'xmlns') {\r\n if (!('' in map)) map[''] = childNode.nodeValue || null;\r\n }\r\n }\r\n n = n.parentNode;\r\n }\r\n return map;\r\n }\r\n\r\n /**\r\n * HTML needs to be parsed differently because it's a special case of XML.\r\n * Sources:\r\n *\r\n * - https://blog.teamtreehouse.com/to-close-or-not-to-close-tags-in-html5\r\n * @param htmlText The HTML text\r\n * @returns A DOM document.\r\n */\r\n private htmlParse(htmlText: string): XDocument {\r\n const xmlDocument = new XDocument();\r\n const root = xmlDocument;\r\n const stack = [];\r\n\r\n let parent: XNode = root;\r\n stack.push(parent);\r\n\r\n let tag = false,\r\n quotes = false,\r\n doublequotes = false,\r\n start = 0;\r\n for (let i = 0; i < htmlText.length; ++i) {\r\n let char = htmlText.charAt(i);\r\n\r\n if (tag) {\r\n if (!doublequotes && char === \"'\") {\r\n quotes = !quotes;\r\n } else if (!quotes && char === '\"') {\r\n doublequotes = !doublequotes;\r\n } else if (!quotes && !doublequotes && char === '>') {\r\n let text = htmlText.slice(start, i);\r\n\r\n if (text.charAt(0) === '/') { // {\r\n stack.pop();\r\n parent = stack[stack.length - 1];\r\n } else if (text.charAt(0) === '!') {\r\n // Ignore comments\r\n // console.log(`Ignored ${text}`);\r\n } else {\r\n const empty = text.match(this.regexEmpty);\r\n const tagName = this.XML10_TAGNAME_REGEXP.exec(text)[1];\r\n let node = domCreateElement(xmlDocument, tagName);\r\n\r\n let attribute;\r\n while ((attribute = this.XML10_ATTRIBUTE_REGEXP.exec(text))) {\r\n const val = htmlEntityDecode(attribute[5] || attribute[7] || '');\r\n domSetAttribute(node, attribute[1], val);\r\n }\r\n\r\n node.siblingPosition = parent.childNodes.length;\r\n domAppendChild(parent, node);\r\n\r\n // The fundamental difference between this parse function\r\n // and the strict XML parse is here:\r\n // HTML is lenient with certain tags, that don't need to be closed.\r\n if (!empty && !this.lenientHtmlTags.includes(tagName)) {\r\n parent = node;\r\n stack.push(node);\r\n }\r\n }\r\n\r\n start = i + 1;\r\n tag = false;\r\n quotes = false;\r\n doublequotes = false;\r\n }\r\n } else {\r\n if (char === '<') {\r\n let text = htmlText.slice(start, i);\r\n if (text && parent !== root) {\r\n domAppendChild(parent, domCreateTextNode(xmlDocument, text));\r\n }\r\n if (htmlText.slice(i + 1, i + 4) === '!--') {\r\n let endTagIndex = htmlText.slice(i + 4).indexOf('-->');\r\n if (endTagIndex) {\r\n let node = domCreateComment(xmlDocument, htmlText.slice(i + 4, i + endTagIndex + 4));\r\n domAppendChild(parent, node);\r\n i += endTagIndex + 6;\r\n }\r\n } else if (htmlText.slice(i + 1, i + 9) === '!DOCTYPE') {\r\n let endTagIndex = htmlText.slice(i + 9).indexOf('>');\r\n if (endTagIndex) {\r\n const dtdValue = htmlText.slice(i + 9, i + endTagIndex + 9).trimStart();\r\n // TODO: Not sure if this is a good solution.\r\n // Trying to implement this: https://github.com/DesignLiquido/xslt-processor/issues/30\r\n const node = domCreateDTDSection(xmlDocument, dtdValue);\r\n domAppendChild(parent, node);\r\n i += endTagIndex + dtdValue.length + 5;\r\n }\r\n } else {\r\n tag = true;\r\n }\r\n start = i + 1;\r\n }\r\n }\r\n }\r\n\r\n return xmlDocument;\r\n }\r\n\r\n /**\r\n * Parses the given XML string with our custom, JavaScript XML parser.\r\n * @param xml The XML String.\r\n * @returns A XDocument.\r\n * @author Steffen Meschkat <mesch@google.com>\r\n */\r\n private xmlStrictParse(xml: string): XDocument {\r\n let regexTagname: RegExp;\r\n let regexAttribute: RegExp;\r\n if (xml.match(/^<\\?xml/)) {\r\n // When an XML document begins with an XML declaration\r\n // VersionInfo must appear.\r\n if (xml.search(new RegExp(XML10_VERSION_INFO)) === 5) {\r\n regexTagname = this.XML10_TAGNAME_REGEXP;\r\n regexAttribute = this.XML10_ATTRIBUTE_REGEXP;\r\n } else if (xml.search(new RegExp(XML11_VERSION_INFO)) === 5) {\r\n regexTagname = this.XML11_TAGNAME_REGEXP;\r\n regexAttribute = this.XML11_ATTRIBUTE_REGEXP;\r\n } else {\r\n throw new Error('XML VersionInfo has an unknown version number.');\r\n }\r\n } else {\r\n // When an XML declaration is missing it's an XML 1.0 document.\r\n regexTagname = this.XML10_TAGNAME_REGEXP;\r\n regexAttribute = this.XML10_ATTRIBUTE_REGEXP;\r\n }\r\n\r\n const xmlDocument = new XDocument();\r\n const root = xmlDocument;\r\n const stack = [];\r\n\r\n let parent: XNode = root;\r\n stack.push(parent);\r\n\r\n let tag = false,\r\n quotes = false,\r\n doublequotes = false,\r\n start = 0;\r\n for (let i = 0; i < xml.length; ++i) {\r\n let char = xml.charAt(i);\r\n if (tag && !doublequotes && char === \"'\") {\r\n quotes = !quotes;\r\n } else if (tag && !quotes && char === '\"') {\r\n doublequotes = !doublequotes;\r\n } else if (tag && char === '>' && !quotes && !doublequotes) {\r\n let text = xml.slice(start, i);\r\n if (text.charAt(0) === '/') {\r\n stack.pop();\r\n parent = stack[stack.length - 1];\r\n } else if (text.charAt(0) === '?') {\r\n // Ignore XML declaration and processing instructions\r\n } else if (text.charAt(0) === '!') {\r\n // Ignore comments\r\n // console.log(`Ignored ${text}`);\r\n } else {\r\n const empty = text.match(this.regexEmpty);\r\n const tagname = regexTagname.exec(text)[1];\r\n let node = domCreateElement(xmlDocument, tagname);\r\n\r\n let attribute;\r\n while ((attribute = regexAttribute.exec(text))) {\r\n const val = htmlEntityDecode(attribute[5] || attribute[7] || '');\r\n domSetAttribute(node, attribute[1], val);\r\n }\r\n\r\n node.siblingPosition = parent.childNodes.length;\r\n domAppendChild(parent, node);\r\n if (!empty) {\r\n parent = node;\r\n stack.push(node);\r\n }\r\n\r\n const namespaceMap = this.namespaceMapAt(node);\r\n if (node.prefix !== null) {\r\n if (node.prefix in namespaceMap) node.namespaceUri = namespaceMap[node.prefix];\r\n // else, prefix is undefined. do anything?\r\n } else {\r\n if ('' in namespaceMap) node.namespaceUri = namespaceMap[''];\r\n }\r\n\r\n for (let i = 0; i < node.childNodes.length; ++i) {\r\n const childNode = node.childNodes[i];\r\n if (childNode.nodeType !== DOM_ATTRIBUTE_NODE) {\r\n continue;\r\n }\r\n\r\n if (childNode.prefix !== null && childNode.prefix in namespaceMap) {\r\n childNode.namespaceUri = namespaceMap[childNode.prefix];\r\n // else, prefix undefined.\r\n }\r\n // elements with no prefix always have no namespace, so do nothing here.\r\n }\r\n }\r\n start = i + 1;\r\n tag = false;\r\n quotes = false;\r\n doublequotes = false;\r\n } else if (!tag && char === '<') {\r\n let text = xml.slice(start, i);\r\n if (text && parent !== root) {\r\n domAppendChild(parent, domCreateTextNode(xmlDocument, htmlEntityDecode(text)));\r\n }\r\n if (xml.slice(i + 1, i + 4) === '!--') {\r\n let endTagIndex = xml.slice(i + 4).indexOf('-->');\r\n if (endTagIndex) {\r\n let node = domCreateComment(xmlDocument, xml.slice(i + 4, i + endTagIndex + 4));\r\n domAppendChild(parent, node);\r\n i += endTagIndex + 6;\r\n }\r\n } else if (xml.slice(i + 1, i + 9) === '![CDATA[') {\r\n let endTagIndex = xml.slice(i + 9).indexOf(']]>');\r\n if (endTagIndex) {\r\n let node = domCreateCDATASection(xmlDocument, xml.slice(i + 9, i + endTagIndex + 9));\r\n domAppendChild(parent, node);\r\n i += endTagIndex + 11;\r\n }\r\n } else if (xml.slice(i + 1, i + 9) === '!DOCTYPE') { // \"!DOCTYPE\" can be used in a XSLT template.\r\n let endTagIndex = xml.slice(i + 9).indexOf('>');\r\n if (endTagIndex) {\r\n const dtdValue = xml.slice(i + 9, i + endTagIndex + 9).trimStart();\r\n // TODO: Not sure if this is a good solution.\r\n // Trying to implement this: https://github.com/DesignLiquido/xslt-processor/issues/30\r\n const node = domCreateDTDSection(xmlDocument, dtdValue);\r\n domAppendChild(parent, node);\r\n i += endTagIndex + dtdValue.length + 5;\r\n }\r\n } else {\r\n tag = true;\r\n }\r\n start = i + 1;\r\n }\r\n }\r\n\r\n return root;\r\n }\r\n}\r\n","import { XPathNode } from './node';\r\n\r\n/**\r\n * Type for custom XPath functions that can be registered in the context.\r\n */\r\nexport type XPathFunction = (...args: any[]) => any;\r\n\r\n/**\r\n * Type for the variables map in the context.\r\n */\r\nexport type XPathVariables = Record<string, any>;\r\n\r\n/**\r\n * Type for the custom functions map in the context.\r\n */\r\nexport type XPathFunctions = Record<string, XPathFunction>;\r\n\r\n/**\r\n * Type for namespace bindings (prefix -> namespace URI).\r\n */\r\nexport type XPathNamespaces = Record<string, string>;\r\n\r\n/**\r\n * Type for available documents mapping (URI -> root node).\r\n * Used by fn:doc() and related functions (XPath 2.0+).\r\n */\r\nexport type XPathDocuments = Record<string, XPathNode | null>;\r\n\r\n/**\r\n * Type for available collections mapping (URI -> sequence of nodes).\r\n * Used by fn:collection() function (XPath 2.0+).\r\n */\r\nexport type XPathCollections = Record<string, XPathNode[]>;\r\n\r\n/**\r\n * Type for function implementations registry.\r\n * Maps function names (with optional namespace) to their implementations.\r\n */\r\nexport type XPathFunctionRegistry = Record<string, XPathFunction>;\r\n\r\n/**\r\n * The evaluation context for XPath expressions.\r\n *\r\n * This context is passed to all expression evaluate() methods and contains:\r\n * - The current context node\r\n * - Position information for predicates\r\n * - Variable bindings\r\n * - Custom function definitions\r\n * - Dynamic properties like current dateTime, available documents, etc.\r\n */\r\nexport interface XPathContext {\r\n /**\r\n * The current context node being evaluated.\r\n */\r\n node?: XPathNode;\r\n\r\n /**\r\n * The position of the context node within the current node set (1-based).\r\n * Used by position() function and numeric predicates.\r\n */\r\n position?: number;\r\n\r\n /**\r\n * The size of the current node set.\r\n * Used by last() function.\r\n */\r\n size?: number;\r\n\r\n /**\r\n * The full node list for the current context.\r\n * Used by the 'self-and-siblings' axis (XSLT-specific).\r\n */\r\n nodeList?: XPathNode[];\r\n\r\n /**\r\n * Variable bindings available during evaluation.\r\n * Variables are referenced in XPath as $variableName.\r\n */\r\n variables?: XPathVariables;\r\n\r\n /**\r\n * Custom functions available during evaluation.\r\n * These extend the built-in XPath 1.0 function library.\r\n */\r\n functions?: XPathFunctions;\r\n\r\n /**\r\n * Namespace bindings for resolving prefixes in XPath expressions.\r\n * Maps namespace prefixes to namespace URIs.\r\n * Example: { \"atom\": \"http://www.w3.org/2005/Atom\" }\r\n */\r\n namespaces?: XPathNamespaces;\r\n\r\n /**\r\n * XSLT version ('1.0', '2.0', '3.0') for version-specific behavior.\r\n * Used by functions like json-to-xml() which are only available in XSLT 3.0+\r\n */\r\n xsltVersion?: string;\r\n\r\n /**\r\n * XPath specification version being used.\r\n * Default: '1.0'\r\n *\r\n * This affects:\r\n * - Function library available\r\n * - Type system behavior\r\n * - Sequence vs node-set handling\r\n */\r\n xpathVersion?: '1.0' | '2.0' | '3.0' | '3.1';\r\n\r\n /**\r\n * Enable XPath 1.0 backward compatibility mode (Phase 8.1).\r\n * When true, XPath 2.0+ expressions follow XPath 1.0 type conversion rules.\r\n * This enables:\r\n * - XPath 1.0 boolean conversion semantics\r\n * - XPath 1.0 numeric conversion (with NaN for empty sequences)\r\n * - XPath 1.0 comparison rules (node-set to string conversion)\r\n * - XPath 1.0 logical operator behavior (short-circuit, error suppression)\r\n * Default: false (XPath 2.0 semantics)\r\n */\r\n xpath10CompatibilityMode?: boolean;\r\n\r\n /**\r\n * Default collation for string comparisons (XPath 2.0+).\r\n * Default: Unicode codepoint collation\r\n */\r\n defaultCollation?: string;\r\n\r\n /**\r\n * Base URI for resolving relative URIs (XPath 2.0+).\r\n */\r\n baseUri?: string;\r\n\r\n /**\r\n * Implicit timezone as duration offset from UTC (XPath 2.0+).\r\n * Example: '-PT5H' for US Eastern Time (UTC-5)\r\n */\r\n implicitTimezone?: string;\r\n\r\n /**\r\n * Extension data for XSLT or custom implementations.\r\n * This allows attaching arbitrary data to the context without\r\n * polluting the main interface.\r\n */\r\n extensions?: Record<string, any>;\r\n\r\n // ===== XPath 2.0+ Dynamic Context (Section 2.1.2) =====\r\n\r\n /**\r\n * Current dateTime in the dynamic context (XPath 2.0+).\r\n * Returned by fn:current-dateTime().\r\n * If not provided, defaults to system time when accessed.\r\n */\r\n currentDateTime?: Date;\r\n\r\n /**\r\n * Available documents mapping for fn:doc() function (XPath 2.0+).\r\n * Maps document URIs to their root document nodes.\r\n * Example: { \"http://example.com/data.xml\": rootNode }\r\n */\r\n availableDocuments?: XPathDocuments;\r\n\r\n /**\r\n * Available collections mapping for fn:collection() function (XPath 2.0+).\r\n * Maps collection URIs to sequences of nodes.\r\n * Example: { \"http://example.com/collection\": [node1, node2, ...] }\r\n */\r\n availableCollections?: XPathCollections;\r\n\r\n /**\r\n * Default collection URI when fn:collection() is called without arguments (XPath 2.0+).\r\n * If provided, fn:collection() returns availableCollections[defaultCollection].\r\n */\r\n defaultCollection?: string;\r\n\r\n /**\r\n * Function implementations registry (XPath 2.0+).\r\n * Maps QName function names to their implementations.\r\n * Allows defining custom/XSLT functions at evaluation time.\r\n * Format: \"localName\" or \"prefix:localName\"\r\n */\r\n functionRegistry?: XPathFunctionRegistry;\r\n}\r\n\r\n/**\r\n * Represents an XPath 3.0 function item.\r\n * This is a simplified interface to avoid circular dependencies.\r\n */\r\nexport interface XPathFunctionItem {\r\n __isFunctionItem: true;\r\n implementation: (...args: any[]) => any;\r\n arity: number;\r\n name?: string;\r\n namespace?: string;\r\n}\r\n\r\n/**\r\n * Result types that can be returned from XPath evaluation.\r\n *\r\n * XPath 1.0: node-set, string, number, boolean\r\n * XPath 2.0+: sequences (which subsume node-sets), atomic values, functions\r\n */\r\nexport type XPathResult =\r\n | XPathNode[] // Node set (XPath 1.0) or sequence of nodes (XPath 2.0+)\r\n | string // String\r\n | number // Number\r\n | boolean // Boolean\r\n | any[] // Sequence (XPath 2.0+)\r\n | Map<any, any> // Map (XPath 3.0+)\r\n | null // Empty sequence (XPath 2.0+)\r\n | XPathFunctionItem; // Function item (XPath 3.0+)\r\n\r\n/**\r\n * Creates a new XPath context with the given node as the context node.\r\n */\r\nexport function createContext(node: XPathNode, options?: Partial<XPathContext>): XPathContext {\r\n return {\r\n node,\r\n position: 1,\r\n size: 1,\r\n ...options,\r\n };\r\n}\r\n\r\n/**\r\n * Creates a child context for predicate evaluation.\r\n * Preserves variables and functions from parent context.\r\n */\r\nexport function createPredicateContext(\r\n parent: XPathContext,\r\n node: XPathNode,\r\n position: number,\r\n size: number\r\n): XPathContext {\r\n return {\r\n ...parent,\r\n node,\r\n position,\r\n size,\r\n };\r\n}\r\n","import { XNode, xmlValue } from \"../../dom\";\r\nimport { NodeValue } from \"./node-value\";\r\n\r\nexport class NodeSetValue implements NodeValue {\r\n value: XNode[];\r\n type: string;\r\n\r\n constructor(value: XNode[]) {\r\n this.value = value;\r\n this.type = 'node-set';\r\n }\r\n\r\n stringValue(): string {\r\n if (this.value.length === 0) {\r\n return '';\r\n }\r\n\r\n return xmlValue(this.value[0]);\r\n }\r\n\r\n booleanValue() {\r\n return this.value.length > 0;\r\n }\r\n\r\n numberValue() {\r\n return parseInt(this.stringValue()) - 0;\r\n }\r\n\r\n nodeSetValue(): XNode[] {\r\n return this.value;\r\n }\r\n}\r\n","import { XNode } from \"../../dom\";\r\nimport { NodeValue } from \"./node-value\";\r\n\r\nexport class StringValue implements NodeValue {\r\n value: any;\r\n type: string;\r\n\r\n constructor(value: any) {\r\n this.value = value;\r\n this.type = 'string';\r\n }\r\n\r\n stringValue(): string {\r\n return String(this.value);\r\n }\r\n\r\n booleanValue() {\r\n return this.value.length > 0;\r\n }\r\n\r\n numberValue() {\r\n const text = String(this.value).trim();\r\n if (text.length === 0) {\r\n return NaN;\r\n }\r\n return Number(text);\r\n }\r\n\r\n nodeSetValue(): XNode[] {\r\n throw this;\r\n }\r\n}\r\n","import { XNode } from \"../../dom\";\r\nimport { NodeValue } from \"./node-value\";\r\n\r\nexport class NumberValue implements NodeValue {\r\n value: any;\r\n type: string;\r\n\r\n constructor(value: any) {\r\n this.value = value;\r\n this.type = 'number';\r\n }\r\n\r\n stringValue(): string {\r\n return `${this.value}`;\r\n }\r\n\r\n booleanValue() {\r\n return !!this.value;\r\n }\r\n\r\n numberValue() {\r\n return this.value - 0;\r\n }\r\n\r\n nodeSetValue(): XNode[] {\r\n throw this;\r\n }\r\n}\r\n","import { XNode } from \"../../dom\";\r\nimport { NodeValue } from \"./node-value\";\r\n\r\nexport class BooleanValue implements NodeValue {\r\n value: any;\r\n type: string;\r\n\r\n constructor(value: any) {\r\n this.value = value;\r\n this.type = 'boolean';\r\n }\r\n\r\n stringValue(): string {\r\n return `${this.value}`;\r\n }\r\n\r\n booleanValue() {\r\n return this.value;\r\n }\r\n\r\n numberValue() {\r\n return this.value ? 1 : 0;\r\n }\r\n\r\n nodeSetValue(): XNode[] {\r\n throw this;\r\n }\r\n}\r\n","import { XNode } from \"../../dom\";\r\nimport { NodeValue } from \"./node-value\";\r\n\r\nexport class MapValue implements NodeValue {\r\n value: any;\r\n type: string;\r\n\r\n constructor(value: any) {\r\n this.value = value;\r\n this.type = 'map';\r\n }\r\n\r\n stringValue(): string {\r\n // For maps, string-value is not well-defined in XPath 3.1\r\n // but for XSLT output we can use JSON representation\r\n const clean: Record<string, any> = {};\r\n for (const key in this.value) {\r\n if (key !== '__isMap') {\r\n clean[key] = this.value[key];\r\n }\r\n }\r\n return JSON.stringify(clean);\r\n }\r\n\r\n booleanValue(): boolean {\r\n return true;\r\n }\r\n\r\n numberValue(): number {\r\n return NaN;\r\n }\r\n\r\n nodeSetValue(): XNode[] {\r\n return [];\r\n }\r\n}\r\n","import { XNode } from \"../../dom\";\r\nimport { NodeValue } from \"./node-value\";\r\n\r\nexport class ArrayValue implements NodeValue {\r\n value: any;\r\n type: string;\r\n\r\n constructor(value: any) {\r\n this.value = value;\r\n this.type = 'array';\r\n }\r\n\r\n stringValue(): string {\r\n // For arrays, string-value is not well-defined in XPath 3.1\r\n // but for XSLT output we can use JSON representation\r\n return JSON.stringify(this.value.members || []);\r\n }\r\n\r\n booleanValue(): boolean {\r\n return true;\r\n }\r\n\r\n numberValue(): number {\r\n return NaN;\r\n }\r\n\r\n nodeSetValue(): XNode[] {\r\n return [];\r\n }\r\n}\r\n","import { XNode } from \"../../dom\";\r\nimport { NodeValue } from \"./node-value\";\r\n\r\nexport class FunctionValue implements NodeValue {\r\n value: any;\r\n type: string;\r\n\r\n constructor(value: any) {\r\n this.value = value;\r\n this.type = 'function';\r\n }\r\n\r\n stringValue(): string {\r\n // Functions don't have a string value in XPath 3.1\r\n // Usually, serialization results in something like \"function(...)\"\r\n const name = this.value.name ? `${this.value.name}#${this.value.arity}` : `(anonymous)#${this.value.arity}`;\r\n return `function ${name}`;\r\n }\r\n\r\n booleanValue(): boolean {\r\n return true;\r\n }\r\n\r\n numberValue(): number {\r\n return NaN;\r\n }\r\n\r\n nodeSetValue(): XNode[] {\r\n return [];\r\n }\r\n}\r\n","import { ExprContext } from \"../expr-context\";\r\nimport { XNode } from \"../../dom\";\r\nimport { XPathContext, XPathResult, createContext } from \"../lib/src/context\";\r\nimport { XPathNode } from \"../lib/src/node\";\r\nimport { NodeSetValue } from \"../values/node-set-value\";\r\nimport { StringValue } from \"../values/string-value\";\r\nimport { NumberValue } from \"../values/number-value\";\r\nimport { BooleanValue } from \"../values/boolean-value\";\r\nimport { MapValue } from \"../values/map-value\";\r\nimport { ArrayValue } from \"../values/array-value\";\r\nimport { FunctionValue } from \"../values/function-value\";\r\nimport { NodeValue } from \"../values\";\r\nimport { JsonToXmlConverter } from \"../lib/src/expressions/json-to-xml-converter\";\r\nimport { xmlValue } from \"../../dom\";\r\nimport { DOM_DOCUMENT_NODE, DOM_TEXT_NODE, DOM_ELEMENT_NODE, DOM_ATTRIBUTE_NODE, DOM_COMMENT_NODE, DOM_PROCESSING_INSTRUCTION_NODE } from \"../../constants\";\r\n\r\n/**\r\n * Handles conversion between ExprContext and XPathContext.\r\n * Uses XNode directly as XPathNode-compatible objects to preserve node identity.\r\n */\r\nexport class NodeConverter {\r\n /**\r\n * Convert ExprContext to XPathContext for the new XPath implementation.\r\n * XNodes are used directly since they implement enough of the XPathNode interface.\r\n */\r\n exprContextToXPathContext(exprContext: ExprContext): XPathContext {\r\n const currentNode = exprContext.nodeList[exprContext.position];\r\n // Use XNode directly - it's compatible enough with XPathNode\r\n const xpathNode = this.adaptXNode(currentNode);\r\n\r\n // Convert all nodes in the node list (needed for 'self-and-siblings' axis)\r\n const nodeList = exprContext.nodeList.map(node => this.adaptXNode(node));\r\n\r\n // Build extensions object to pass through XSLT-specific context data\r\n const extensions: Record<string, any> = {};\r\n\r\n // Search up the parent chain for XSLT-specific context data\r\n // (since xsltChildNodes clones context, we need to look up the chain)\r\n let ctx: ExprContext | undefined = exprContext;\r\n while (ctx) {\r\n // Pass through regex groups for xsl:analyze-string / regex-group() function\r\n if (!extensions.regexGroups && ctx.regexGroups) {\r\n extensions.regexGroups = ctx.regexGroups;\r\n }\r\n // Pass through current group for xsl:for-each-group / current-group() function\r\n if (!extensions.currentGroup && ctx.currentGroup) {\r\n extensions.currentGroup = ctx.currentGroup;\r\n }\r\n // Pass through current grouping key for xsl:for-each-group / current-grouping-key() function\r\n if (!extensions.currentGroupingKey && ctx.currentGroupingKey !== undefined) {\r\n extensions.currentGroupingKey = ctx.currentGroupingKey;\r\n }\r\n ctx = ctx.parent;\r\n }\r\n\r\n return createContext(xpathNode, {\r\n position: exprContext.position + 1, // XPath is 1-based\r\n size: exprContext.nodeList.length,\r\n nodeList: nodeList,\r\n variables: this.convertVariables(exprContext),\r\n functions: this.createCustomFunctions(exprContext),\r\n namespaces: exprContext.knownNamespaces,\r\n xsltVersion: exprContext.xsltVersion,\r\n extensions: Object.keys(extensions).length > 0 ? extensions : undefined,\r\n });\r\n }\r\n\r\n /**\r\n * Adapt XNode to be compatible with XPathNode interface.\r\n * We add missing properties but keep the original XNode reference.\r\n */\r\n adaptXNode(node: XNode): XPathNode {\r\n if (!node) return null;\r\n\r\n // XNode already has most properties, we just need to handle some differences\r\n // We add adapter properties without modifying the original object\r\n const adapted = node as any;\r\n\r\n // Add XPathNode-compatible properties if not present\r\n // namespaceUri is now the standard property in XPathNode interface\r\n\r\n if (!('textContent' in adapted)) {\r\n Object.defineProperty(adapted, 'textContent', {\r\n get() { return this._getTextContent(); },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n }\r\n\r\n if (!('_getTextContent' in adapted)) {\r\n adapted._getTextContent = function() {\r\n if (this.nodeType === 3 || this.nodeType === 2) { // TEXT_NODE or ATTRIBUTE_NODE\r\n return this.nodeValue || '';\r\n }\r\n if (!this.childNodes) return '';\r\n let text = '';\r\n for (const child of this.childNodes) {\r\n if (child.nodeType === 3) {\r\n text += child.nodeValue || '';\r\n } else if (child.nodeType === 1) {\r\n text += this._getTextContent.call(child);\r\n }\r\n }\r\n return text;\r\n };\r\n }\r\n\r\n if (!('attributes' in adapted)) {\r\n Object.defineProperty(adapted, 'attributes', {\r\n get() {\r\n return this.childNodes ? this.childNodes.filter((n: any) => n.nodeType === 2) : [];\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n }\r\n\r\n if (!('getAttribute' in adapted)) {\r\n adapted.getAttribute = function(name: string) {\r\n return this.getAttributeValue ? this.getAttributeValue(name) : null;\r\n };\r\n }\r\n\r\n return adapted as XPathNode;\r\n }\r\n\r\n /**\r\n * Convert XPathNode result back to XNode.\r\n * Since we're now using XNodes directly, this is mostly a type cast.\r\n */\r\n xPathNodeToXNode(xpathNode: XPathNode): XNode | null {\r\n if (!xpathNode) return null;\r\n \r\n // Check if this is already an XNode (from native parsing)\r\n if (xpathNode instanceof XNode) {\r\n return xpathNode as unknown as XNode;\r\n }\r\n \r\n // Otherwise, convert XPathNode interface (from json-to-xml or xpath/lib) to XNode\r\n return this.convertXPathNodeToXNode(xpathNode);\r\n }\r\n\r\n /**\r\n * Get text content from an XNode.\r\n */\r\n private getTextContent(node: XNode): string {\r\n if (node.nodeType === 3 || node.nodeType === 2) { // TEXT_NODE or ATTRIBUTE_NODE\r\n return node.nodeValue || '';\r\n }\r\n\r\n if (!node.childNodes) return '';\r\n\r\n let text = '';\r\n for (const child of node.childNodes) {\r\n if (child.nodeType === 3) { // TEXT_NODE\r\n text += child.nodeValue || '';\r\n } else if (child.nodeType === 1) { // ELEMENT_NODE\r\n text += this.getTextContent(child);\r\n }\r\n }\r\n return text;\r\n }\r\n\r\n /**\r\n * Convert variables from ExprContext format to XPathContext format.\r\n */\r\n private convertVariables(exprContext: ExprContext): Record<string, any> {\r\n const variables: Record<string, any> = {};\r\n\r\n const contexts: ExprContext[] = [];\r\n let ctx: ExprContext | undefined = exprContext;\r\n while (ctx) {\r\n contexts.push(ctx);\r\n ctx = ctx.parent;\r\n }\r\n\r\n for (let i = contexts.length - 1; i >= 0; i--) {\r\n const current = contexts[i];\r\n for (const [name, value] of Object.entries(current.variables || {})) {\r\n if (value && typeof value === 'object' && 'stringValue' in value) {\r\n // It's a NodeValue, extract the raw value\r\n // Cast to any to access the type property which exists on concrete implementations\r\n const nodeValue = value as any;\r\n if (nodeValue.type === 'node-set') {\r\n variables[name] = (value as NodeSetValue).nodeSetValue().map(n => this.adaptXNode(n));\r\n } else if (nodeValue.type === 'string') {\r\n variables[name] = value.stringValue();\r\n } else if (nodeValue.type === 'number') {\r\n variables[name] = value.numberValue();\r\n } else if (nodeValue.type === 'boolean') {\r\n variables[name] = value.booleanValue();\r\n } else if (nodeValue.type === 'map') {\r\n variables[name] = nodeValue.value;\r\n } else if (nodeValue.type === 'array') {\r\n variables[name] = nodeValue.value;\r\n } else if (nodeValue.type === 'function') {\r\n variables[name] = nodeValue.value;\r\n } else {\r\n // Unknown type, try to get string value\r\n variables[name] = value.stringValue();\r\n }\r\n } else {\r\n variables[name] = value;\r\n }\r\n }\r\n }\r\n\r\n return variables;\r\n }\r\n\r\n /**\r\n * Create custom functions for XPath context (like key(), document(), etc.).\r\n * Note: Custom functions receive the XPathContext as their first argument,\r\n * followed by the evaluated function arguments.\r\n */\r\n private createCustomFunctions(exprContext: ExprContext): Record<string, (...args: any[]) => any> {\r\n const functions: Record<string, (...args: any[]) => any> = {};\r\n\r\n // key() function - XSLT specific\r\n // Signature: key(context, keyName, keyValue)\r\n functions['key'] = (_context: XPathContext, keyName: string, keyValue: string) => {\r\n const keyDef = exprContext.keys?.[keyName];\r\n if (keyDef && keyDef[keyValue]) {\r\n const nodeSetValue = keyDef[keyValue];\r\n return nodeSetValue.nodeSetValue().map((n: XNode) => this.adaptXNode(n));\r\n }\r\n return [];\r\n };\r\n\r\n // current() function - XSLT specific\r\n // Signature: current(context)\r\n functions['current'] = (_context: XPathContext) => {\r\n const currentNode = exprContext.nodeList[exprContext.position];\r\n return [this.adaptXNode(currentNode)];\r\n };\r\n\r\n // format-number() function - XSLT specific\r\n // Signature: format-number(context, number, format, decimalFormatName?)\r\n functions['format-number'] = (_context: XPathContext, number: number, format: string, decimalFormatName?: string) => {\r\n const settings = exprContext.decimalFormatSettings;\r\n // Basic implementation - can be expanded\r\n return number.toLocaleString();\r\n };\r\n\r\n // xml-to-json() function - XSLT 3.0 specific\r\n // Signature: xml-to-json(context, nodes)\r\n functions['xml-to-json'] = (_context: XPathContext, nodes: any) => {\r\n // Check XSLT version - only supported in 3.0\r\n if (exprContext.xsltVersion !== '3.0') {\r\n throw new Error('xml-to-json() is only supported in XSLT 3.0. Use version=\"3.0\" in your stylesheet.');\r\n }\r\n\r\n // Handle node set or single node\r\n const node = Array.isArray(nodes) ? nodes[0] : nodes;\r\n if (!node) {\r\n return '\"\"';\r\n }\r\n\r\n // Convert XML node to JSON string\r\n return this.xmlToJson(node);\r\n };\r\n\r\n // json-to-xml() function - XSLT 3.0 specific\r\n // Signature: json-to-xml(context, jsonText)\r\n functions['json-to-xml'] = (_context: XPathContext, jsonText: any) => {\r\n // Check XSLT version - only supported in 3.0\r\n if (exprContext.xsltVersion !== '3.0') {\r\n throw new Error('json-to-xml() is only supported in XSLT 3.0. Use version=\"3.0\" in your stylesheet.');\r\n }\r\n\r\n // Handle node set or single value\r\n const jsonStr = Array.isArray(jsonText) ? jsonText[0] : jsonText;\r\n if (!jsonStr) {\r\n return [];\r\n }\r\n\r\n // Convert JSON string to XML document node using xpath lib converter\r\n const converter = new JsonToXmlConverter();\r\n const xpathNode = converter.convert(String(jsonStr));\r\n \r\n if (!xpathNode) {\r\n return null;\r\n }\r\n\r\n // Get owner document from context\r\n const ownerDoc = exprContext.nodeList && exprContext.nodeList.length > 0 \r\n ? exprContext.nodeList[0].ownerDocument \r\n : null;\r\n\r\n // Convert XPathNode interface tree to actual XNode objects\r\n const convertedNode = this.convertXPathNodeToXNode(xpathNode, ownerDoc);\r\n \r\n // Return as array for consistency with xpath processor\r\n return convertedNode ? [convertedNode] : [];\r\n };\r\n\r\n // system-property() function - XSLT specific (Section 12.4)\r\n // Signature: system-property(context, propertyName)\r\n functions['system-property'] = (_context: XPathContext, propertyName: any) => {\r\n const propName = String(propertyName);\r\n\r\n // Required system properties per XSLT 1.0 spec\r\n const systemProperties: Record<string, string> = {\r\n 'xsl:version': exprContext.xsltVersion || '1.0',\r\n 'xsl:vendor': 'Design Liquido',\r\n 'xsl:vendor-url': 'https://github.com/DesignLiquido/xslt-processor'\r\n };\r\n\r\n // Check custom system properties from context\r\n if (exprContext.systemProperties && exprContext.systemProperties[propName]) {\r\n return exprContext.systemProperties[propName];\r\n }\r\n\r\n return systemProperties[propName] || '';\r\n };\r\n\r\n // element-available() function - XSLT specific (Section 15)\r\n // Signature: element-available(context, elementName)\r\n functions['element-available'] = (_context: XPathContext, elementName: any) => {\r\n const name = String(elementName);\r\n\r\n // List of supported XSLT 1.0 elements\r\n const xsltElements = [\r\n 'xsl:apply-imports',\r\n 'xsl:apply-templates',\r\n 'xsl:attribute',\r\n 'xsl:attribute-set',\r\n 'xsl:call-template',\r\n 'xsl:choose',\r\n 'xsl:comment',\r\n 'xsl:copy',\r\n 'xsl:copy-of',\r\n 'xsl:decimal-format',\r\n 'xsl:element',\r\n 'xsl:fallback',\r\n 'xsl:for-each',\r\n 'xsl:if',\r\n 'xsl:import',\r\n 'xsl:include',\r\n 'xsl:key',\r\n 'xsl:message',\r\n 'xsl:namespace-alias',\r\n 'xsl:number',\r\n 'xsl:otherwise',\r\n 'xsl:output',\r\n 'xsl:param',\r\n 'xsl:preserve-space',\r\n 'xsl:processing-instruction',\r\n 'xsl:sort',\r\n 'xsl:strip-space',\r\n 'xsl:stylesheet',\r\n 'xsl:template',\r\n 'xsl:text',\r\n 'xsl:transform',\r\n 'xsl:value-of',\r\n 'xsl:variable',\r\n 'xsl:when',\r\n 'xsl:with-param'\r\n ];\r\n\r\n // Handle with or without prefix\r\n const normalizedName = name.startsWith('xsl:') ? name : `xsl:${name}`;\r\n return xsltElements.includes(normalizedName) || xsltElements.includes(name);\r\n };\r\n\r\n // function-available() function - XSLT specific (Section 15)\r\n // Signature: function-available(context, functionName)\r\n functions['function-available'] = (_context: XPathContext, functionName: any) => {\r\n const name = String(functionName);\r\n\r\n // Core XPath 1.0 functions\r\n const xpathCoreFunctions = [\r\n 'boolean', 'ceiling', 'concat', 'contains', 'count',\r\n 'false', 'floor', 'id', 'lang', 'last', 'local-name',\r\n 'name', 'namespace-uri', 'normalize-space', 'not', 'number',\r\n 'position', 'round', 'starts-with', 'string', 'string-length',\r\n 'substring', 'substring-after', 'substring-before', 'sum',\r\n 'translate', 'true'\r\n ];\r\n\r\n // XSLT 1.0 additional functions\r\n const xsltFunctions = [\r\n 'current', 'document', 'element-available', 'format-number',\r\n 'function-available', 'generate-id', 'key', 'system-property',\r\n 'unparsed-entity-uri'\r\n ];\r\n\r\n // Additional functions supported by this processor\r\n const additionalFunctions = [\r\n 'matches', 'ends-with', 'xml-to-json', 'json-to-xml'\r\n ];\r\n\r\n const allFunctions = [...xpathCoreFunctions, ...xsltFunctions, ...additionalFunctions];\r\n return allFunctions.includes(name);\r\n };\r\n\r\n // document() function - XSLT specific (Section 12.1)\r\n // Signature: document(context, uriOrNodeSet, baseNode?)\r\n // Note: This is a basic implementation. Full implementation requires document loading.\r\n functions['document'] = (_context: XPathContext, uriOrNodeSet: any, _baseNode?: any) => {\r\n // If a document loader is provided in context, use it\r\n if (exprContext.documentLoader) {\r\n const uri = Array.isArray(uriOrNodeSet)\r\n ? (uriOrNodeSet[0]?.textContent || String(uriOrNodeSet[0] || ''))\r\n : String(uriOrNodeSet || '');\r\n\r\n if (!uri) {\r\n // Empty string returns the current document\r\n return exprContext.root ? [this.adaptXNode(exprContext.root)] : [];\r\n }\r\n\r\n try {\r\n const doc = exprContext.documentLoader(uri);\r\n if (doc) {\r\n return [this.adaptXNode(doc)];\r\n }\r\n } catch (e) {\r\n // Document loading failed, return empty node-set\r\n const warn = exprContext.warningsCallback ?? console.warn;\r\n warn(`document() failed to load: ${uri}`, e);\r\n }\r\n }\r\n\r\n // Return empty node-set if no document loader or loading failed\r\n return [];\r\n };\r\n\r\n // unparsed-entity-uri() function - XSLT specific (Section 12.4)\r\n // Signature: unparsed-entity-uri(context, entityName)\r\n // Note: This requires DTD parsing support which is not commonly available in JavaScript\r\n functions['unparsed-entity-uri'] = (_context: XPathContext, entityName: any) => {\r\n const name = String(entityName);\r\n\r\n // Check if unparsed entities are provided in context\r\n if (exprContext.unparsedEntities && exprContext.unparsedEntities[name]) {\r\n return exprContext.unparsedEntities[name];\r\n }\r\n\r\n // Return empty string if entity not found (per XSLT spec)\r\n return '';\r\n };\r\n\r\n // Add user-defined XSLT functions (xsl:function)\r\n // Search up the parent chain to find userDefinedFunctions\r\n let ctx: ExprContext | undefined = exprContext;\r\n while (ctx) {\r\n if (ctx.userDefinedFunctions) {\r\n ctx.userDefinedFunctions.forEach((funcInfo, funcName) => {\r\n if (!functions[funcName]) {\r\n // Execute the function synchronously\r\n functions[funcName] = (_context: XPathContext, ...args: any[]) => {\r\n return funcInfo.executor(exprContext, funcInfo.functionDef, args);\r\n };\r\n }\r\n });\r\n break;\r\n }\r\n ctx = ctx.parent;\r\n }\r\n\r\n return functions;\r\n }\r\n\r\n /**\r\n * Convert an XPathNode interface tree to actual XNode objects.\r\n * This is needed to convert json-to-xml() output to XSLT-compatible nodes.\r\n */\r\n private convertXPathNodeToXNode(xpathNode: XPathNode, ownerDoc?: any): XNode | null {\r\n if (!xpathNode) {\r\n return null;\r\n }\r\n\r\n let node: XNode;\r\n\r\n if (xpathNode.nodeType === DOM_DOCUMENT_NODE) {\r\n // For document nodes, extract and return the root element\r\n if (xpathNode.childNodes && xpathNode.childNodes.length > 0) {\r\n const rootChild = xpathNode.childNodes[0] as any;\r\n node = this.convertXPathNodeToXNode(rootChild, ownerDoc);\r\n return node;\r\n }\r\n return null;\r\n } else if (xpathNode.nodeType === DOM_TEXT_NODE) {\r\n // Create a text node\r\n const textContent = xpathNode.textContent || '';\r\n node = new XNode(\r\n DOM_TEXT_NODE,\r\n '#text',\r\n textContent,\r\n ownerDoc\r\n );\r\n } else {\r\n // Element node (DOM_ELEMENT_NODE)\r\n node = new XNode(\r\n DOM_ELEMENT_NODE,\r\n xpathNode.nodeName || 'element',\r\n '',\r\n ownerDoc\r\n );\r\n\r\n // Copy namespace URI if present\r\n if (xpathNode.namespaceUri) {\r\n node.namespaceUri = xpathNode.namespaceUri;\r\n }\r\n\r\n // Recursively convert child nodes\r\n if (xpathNode.childNodes && xpathNode.childNodes.length > 0) {\r\n for (let i = 0; i < xpathNode.childNodes.length; i++) {\r\n const childXPathNode = xpathNode.childNodes[i] as any;\r\n const childXNode = this.convertXPathNodeToXNode(childXPathNode, ownerDoc);\r\n if (childXNode) {\r\n childXNode.parentNode = node;\r\n node.childNodes.push(childXNode);\r\n }\r\n }\r\n if (node.childNodes.length > 0) {\r\n node.firstChild = node.childNodes[0];\r\n node.lastChild = node.childNodes[node.childNodes.length - 1];\r\n }\r\n }\r\n }\r\n\r\n return node;\r\n }\r\n\r\n /**\r\n * Convert an XML node to a JSON string representation.\r\n * This is a simplified implementation of XSLT 3.0's xml-to-json().\r\n */\r\n private xmlToJson(node: any): string {\r\n if (!node) {\r\n return '\"\"';\r\n }\r\n\r\n // Use the well-tested xmlValue function which handles all node types correctly\r\n // Pass true to disable browser-specific optimizations since we're in Node.js\r\n const textContent = xmlValue(node as XNode, true);\r\n return JSON.stringify(textContent);\r\n }\r\n\r\n /**\r\n * Wrap XPath result in appropriate NodeValue type.\r\n */\r\n wrapResult(result: XPathResult, exprContext: ExprContext): NodeValue {\r\n if (result === null || result === undefined) {\r\n return new NodeSetValue([]);\r\n }\r\n\r\n if (Array.isArray(result)) {\r\n // Node set - nodes are already XNodes (we use them directly)\r\n // But we must distinguish between node-set and sequence of other items.\r\n // If it's a sequence of nodes, we treat it as NodeSetValue.\r\n const nodes = result.map(node => this.xPathNodeToXNode(node)).filter(n => n !== null) as XNode[];\r\n \r\n // If we have nodes OR it's an empty sequence, default to NodeSetValue for backward compatibility\r\n // In XPath 1.0, everything was a node-set (or primitive).\r\n if (nodes.length > 0 || result.length === 0) {\r\n return new NodeSetValue(nodes);\r\n }\r\n \r\n // If it's a sequence of non-nodes, we should ideally have a SequenceValue.\r\n // For now, let's treat it as a StringValue joined by space (common XSLT 2.0 behavior for sequences in some contexts)\r\n // or just take the first item's string value.\r\n return new StringValue(result.map(item => String(item)).join(' '));\r\n }\r\n\r\n if (typeof result === 'string') {\r\n return new StringValue(result);\r\n }\r\n\r\n if (typeof result === 'number') {\r\n return new NumberValue(result);\r\n }\r\n\r\n if (typeof result === 'boolean') {\r\n return new BooleanValue(result);\r\n }\r\n\r\n if (typeof result === 'object') {\r\n if ((result as any).__isMap) {\r\n return new MapValue(result);\r\n }\r\n if ((result as any).__isArray) {\r\n return new ArrayValue(result);\r\n }\r\n if ((result as any).__isFunctionItem) {\r\n return new FunctionValue(result);\r\n }\r\n }\r\n\r\n // Default to empty node set\r\n return new NodeSetValue([]);\r\n }\r\n\r\n /**\r\n * Clear any internal state if needed.\r\n */\r\n clearCache() {\r\n // No caches to clear now that we use XNodes directly\r\n }\r\n}","import { ExprContext, NodeValue } from \"..\";\r\nimport { XPathExpression, XPathLocationPath } from \"../lib/src/expressions\";\r\nimport { NodeConverter } from \"./node-converter\";\r\n\r\n/**\r\n * Expression wrapper that provides backward-compatible interface.\r\n * Wraps new XPath expressions to work with old ExprContext.\r\n */\r\nexport class Expression {\r\n protected xpathExpression: XPathExpression;\r\n protected nodeConverter: NodeConverter;\r\n\r\n // Properties for LocationPath compatibility\r\n absolute?: boolean;\r\n steps?: any[];\r\n\r\n constructor(xpathExpression: XPathExpression, nodeConverter: NodeConverter) {\r\n this.xpathExpression = xpathExpression;\r\n this.nodeConverter = nodeConverter;\r\n\r\n // Extract properties if this is a location path\r\n if (xpathExpression instanceof XPathLocationPath) {\r\n this.absolute = xpathExpression.absolute;\r\n this.steps = xpathExpression.steps.map((step, index) => ({\r\n axis: step.axis,\r\n nodeTest: step.nodeTest,\r\n predicates: step.predicates,\r\n // Add methods needed by old code\r\n hasPositionalPredicate: false, // TODO: implement proper detection\r\n predicate: step.predicates || [],\r\n evaluate: (ctx: ExprContext) => {\r\n // Evaluate just this step\r\n const xpathCtx = this.nodeConverter.exprContextToXPathContext(ctx);\r\n const result = step.evaluate(xpathCtx);\r\n return this.nodeConverter.wrapResult(result, ctx);\r\n }\r\n }));\r\n }\r\n }\r\n\r\n /**\r\n * Evaluate the expression in the given context.\r\n */\r\n evaluate(context: ExprContext): NodeValue {\r\n const xpathContext = this.nodeConverter.exprContextToXPathContext(context);\r\n const result = this.xpathExpression.evaluate(xpathContext);\r\n return this.nodeConverter.wrapResult(result, context);\r\n }\r\n}","import { XPathExpression, XPathLocationPath } from \"../lib/src/expressions\";\r\nimport { Expression } from \"./expression\";\r\nimport { NodeConverter } from \"./node-converter\";\r\n\r\n/**\r\n * Location expression wrapper for XSLT pattern matching.\r\n */\r\nexport class LocationExpr extends Expression {\r\n declare absolute: boolean;\r\n declare steps: any[];\r\n\r\n constructor(xpathExpression: XPathLocationPath, nodeConverter: NodeConverter) {\r\n super(xpathExpression, nodeConverter);\r\n this.absolute = xpathExpression.absolute;\r\n this.steps = xpathExpression.steps.map(step => ({\r\n axis: step.axis,\r\n nodeTest: step.nodeTest,\r\n predicates: step.predicates || [],\r\n predicate: step.predicates || [],\r\n hasPositionalPredicate: this.hasPositionalPredicate(step.predicates || []),\r\n }));\r\n }\r\n\r\n private hasPositionalPredicate(predicates: XPathExpression[]): boolean {\r\n // TODO: Implement proper detection of positional predicates\r\n // For now, assume no positional predicates\r\n return false;\r\n }\r\n\r\n appendStep(step: any) {\r\n this.steps.push(step);\r\n }\r\n\r\n prependStep(step: any) {\r\n this.steps.unshift(step);\r\n }\r\n}\r\n","import { XPathExpression, XPathUnionExpression } from \"../lib/src/expressions\";\r\nimport { Expression } from \"./expression\";\r\nimport { NodeConverter } from \"./node-converter\";\r\n\r\n/**\r\n * Union expression wrapper.\r\n */\r\nexport class UnionExpr extends Expression {\r\n expr1: Expression;\r\n expr2: Expression;\r\n\r\n constructor(\r\n xpathExpression: XPathUnionExpression,\r\n nodeConverter: NodeConverter,\r\n expr1: Expression,\r\n expr2: Expression\r\n ) {\r\n super(xpathExpression, nodeConverter);\r\n this.expr1 = expr1;\r\n this.expr2 = expr2;\r\n }\r\n}\r\n","// Copyright 2023-2026 Design Liquido\r\n// XPath tokens and axis constants\r\n\r\n// The axes of XPath expressions.\r\nexport const xPathAxis = {\r\n ANCESTOR_OR_SELF: 'ancestor-or-self',\r\n ANCESTOR: 'ancestor',\r\n ATTRIBUTE: 'attribute',\r\n CHILD: 'child',\r\n DESCENDANT_OR_SELF: 'descendant-or-self',\r\n DESCENDANT: 'descendant',\r\n FOLLOWING_SIBLING: 'following-sibling',\r\n FOLLOWING: 'following',\r\n NAMESPACE: 'namespace',\r\n PARENT: 'parent',\r\n PRECEDING_SIBLING: 'preceding-sibling',\r\n PRECEDING: 'preceding',\r\n SELF: 'self',\r\n SELF_AND_SIBLINGS: 'self-and-siblings' // Doesn't exist officially.\r\n // It is here for a special case of `<xsl:apply-templates>`.\r\n};\r\n\r\n// Token rule for number matching (used by expr-context.ts)\r\nexport const TOK_NUMBER = {\r\n label: '[number]',\r\n prec: 35,\r\n re: new RegExp('^\\\\d+(\\\\.\\\\d*)?'),\r\n key: undefined\r\n};\r\n","import { DOM_DOCUMENT_NODE } from '../constants';\r\nimport { BooleanValue } from './values/boolean-value';\r\nimport { NodeSetValue } from './values/node-set-value';\r\nimport { NumberValue } from './values/number-value';\r\nimport { StringValue } from './values/string-value';\r\nimport { MapValue } from './values/map-value';\r\nimport { ArrayValue } from './values/array-value';\r\nimport { FunctionValue } from './values/function-value';\r\nimport { TOK_NUMBER } from './tokens';\r\nimport { XNode } from '../dom';\r\nimport { XsltDecimalFormatSettings } from '../xslt/types';\r\nimport { NodeValue } from './values';\r\n\r\n/**\r\n * XPath expression evaluation context. An XPath context consists of a\r\n * DOM node, a list of DOM nodes that contains this node, a number\r\n * that represents the position of the single node in the list, and a\r\n * current set of variable bindings. (See XPath spec.)\r\n *\r\n * setVariable(name, expr) -- binds given XPath expression to the\r\n * name.\r\n *\r\n * getVariable(name) -- what the name says.\r\n *\r\n * setNode(position) -- sets the context to the node at the given\r\n * position. Needed to implement scoping rules for variables in\r\n * XPath. (A variable is visible to all subsequent siblings, not\r\n * only to its children.)\r\n *\r\n * set/isCaseInsensitive -- specifies whether node name tests should\r\n * be case sensitive. If you're executing xpaths against a regular\r\n * HTML DOM, you probably don't want case-sensitivity, because\r\n * browsers tend to disagree about whether elements & attributes\r\n * should be upper/lower case. If you're running xpaths in an\r\n * XSLT instance, you probably DO want case sensitivity, as per the\r\n * XSL spec.\r\n *\r\n * set/isReturnOnFirstMatch -- whether XPath evaluation should quit as soon\r\n * as a result is found. This is an optimization that might make sense if you\r\n * only care about the first result.\r\n *\r\n * set/isIgnoreNonElementNodesForNTA -- whether to ignore non-element nodes\r\n * when evaluating the \"node()\" any node test. While technically this is\r\n * contrary to the XPath spec, practically it can enhance performance\r\n * significantly, and makes sense if you a) use \"node()\" when you mean \"*\",\r\n * and b) use \"//\" when you mean \"/descendant::* /\".\r\n */\r\nexport class ExprContext {\r\n position: number;\r\n nodeList: XNode[];\r\n xsltVersion: '1.0' | '2.0' | '3.0';\r\n\r\n variables: { [name: string]: NodeValue };\r\n keys: { [name: string]: { [key: string]: NodeValue } };\r\n knownNamespaces: { [alias: string]: string };\r\n\r\n /**\r\n * Custom system properties for system-property() function.\r\n * Overrides the default properties (xsl:version, xsl:vendor, xsl:vendor-url).\r\n */\r\n systemProperties?: { [name: string]: string };\r\n\r\n /**\r\n * Document loader function for the document() function.\r\n * Takes a URI and returns an XNode document, or null if loading fails.\r\n */\r\n documentLoader?: (uri: string) => XNode | null;\r\n\r\n /**\r\n * Unparsed entity URIs for the unparsed-entity-uri() function.\r\n * Maps entity names to their URIs (from DTD declarations).\r\n */\r\n unparsedEntities?: { [name: string]: string };\r\n\r\n /**\r\n * Warning callback for non-fatal XPath/XSLT warnings.\r\n */\r\n warningsCallback?: (...args: any[]) => void;\r\n\r\n caseInsensitive: any;\r\n ignoreAttributesWithoutValue: any;\r\n returnOnFirstMatch: any;\r\n ignoreNonElementNodesForNTA: any;\r\n\r\n parent: ExprContext;\r\n root: XNode;\r\n decimalFormatSettings: XsltDecimalFormatSettings;\r\n\r\n inApplyTemplates: boolean;\r\n baseTemplateMatched: boolean;\r\n\r\n /**\r\n * Regex groups from xsl:analyze-string for regex-group() function.\r\n * Index 0 is the full match, 1+ are captured groups.\r\n */\r\n regexGroups?: string[];\r\n\r\n /**\r\n * Current group from xsl:for-each-group for current-group() function.\r\n * Contains the nodes/items in the current group being processed.\r\n */\r\n currentGroup?: XNode[];\r\n\r\n /**\r\n * Current grouping key from xsl:for-each-group for current-grouping-key() function.\r\n * Contains the key value of the current group being processed.\r\n */\r\n currentGroupingKey?: any;\r\n\r\n /**\r\n * User-defined XSLT functions from xsl:function declarations.\r\n * Maps QName (namespace:localname) to function definition info.\r\n */\r\n userDefinedFunctions?: Map<string, {\r\n functionDef: XNode;\r\n executor: (context: ExprContext, functionDef: XNode, args: any[]) => any;\r\n }>;\r\n\r\n /**\r\n * Constructor -- gets the node, its position, the node set it\r\n * belongs to, and a parent context as arguments. The parent context\r\n * is used to implement scoping rules for variables: if a variable\r\n * is not found in the current context, it is looked for in the\r\n * parent context, recursively. Except for node, all arguments have\r\n * default values: default position is 0, default node set is the\r\n * set that contains only the node, and the default parent is null.\r\n *\r\n * Notice that position starts at 0 at the outside interface;\r\n * inside XPath expressions this shows up as position()=1.\r\n * @param nodeList The list of nodes that contains the current node. This is needed to implement the position() and last() functions, and to evaluate predicates.\r\n * @param xsltVersion The XSLT version in use, which may affect certain function behaviors (e.g. 1.0 vs 2.0).\r\n * @param opt_position The position of the current node in the nodeList. Defaults to 0.\r\n * @param opt_parent The parent expression context, used for variable scoping. Defaults to null.\r\n * @param opt_caseInsensitive Whether node name tests should be case insensitive. Defaults to false.\r\n * @param opt_ignoreAttributesWithoutValue Whether to ignore attributes that have no value (e.g. <input disabled>) when evaluating XPath expressions. Defaults to false.\r\n * @param opt_returnOnFirstMatch Whether XPath evaluation should return as soon as the first match is found. Defaults to false.\r\n * @param opt_ignoreNonElementNodesForNTA Whether to ignore non-element nodes when evaluating the \"node()\" any node test. Defaults to false.\r\n */\r\n constructor(\r\n nodeList: XNode[],\r\n xsltVersion: '1.0' | '2.0' | '3.0' = '1.0',\r\n opt_position?: number,\r\n opt_decimalFormatSettings?: XsltDecimalFormatSettings,\r\n opt_variables?: { [name: string]: any },\r\n opt_knownNamespaces?: { [alias: string]: string },\r\n opt_parent?: ExprContext,\r\n opt_caseInsensitive?: any,\r\n opt_ignoreAttributesWithoutValue?: any,\r\n opt_returnOnFirstMatch?: any,\r\n opt_ignoreNonElementNodesForNTA?: any,\r\n opt_warningsCallback?: (...args: any[]) => void\r\n ) {\r\n this.nodeList = nodeList;\r\n this.xsltVersion = xsltVersion;\r\n\r\n this.position = opt_position || 0;\r\n\r\n this.variables = opt_variables || {};\r\n this.keys = opt_parent?.keys || {};\r\n this.knownNamespaces = opt_knownNamespaces || {};\r\n\r\n this.parent = opt_parent || null;\r\n this.caseInsensitive = opt_caseInsensitive || false;\r\n this.ignoreAttributesWithoutValue = opt_ignoreAttributesWithoutValue || false;\r\n this.returnOnFirstMatch = opt_returnOnFirstMatch || false;\r\n this.ignoreNonElementNodesForNTA = opt_ignoreNonElementNodesForNTA || false;\r\n this.inApplyTemplates = false;\r\n this.baseTemplateMatched = false;\r\n this.warningsCallback = opt_warningsCallback ?? opt_parent?.warningsCallback;\r\n\r\n this.decimalFormatSettings = opt_decimalFormatSettings || {\r\n decimalSeparator: '.',\r\n groupingSeparator: ',',\r\n infinity: 'Infinity',\r\n minusSign: '-',\r\n naN: 'NaN',\r\n percent: '%',\r\n perMille: '‰',\r\n zeroDigit: '0',\r\n digit: '#',\r\n patternSeparator: ';'\r\n };\r\n\r\n if (opt_parent) {\r\n this.root = opt_parent.root;\r\n } else if (this.nodeList[this.position].nodeType == DOM_DOCUMENT_NODE) {\r\n // NOTE(mesch): DOM Spec stipulates that the ownerDocument of a\r\n // document is null. Our root, however is the document that we are\r\n // processing, so the initial context is created from its document\r\n // node, which case we must handle here explicitly.\r\n this.root = this.nodeList[this.position];\r\n } else {\r\n this.root = this.nodeList[this.position].ownerDocument;\r\n }\r\n }\r\n\r\n /**\r\n * clone() -- creates a new context with the current context as\r\n * parent. If passed as argument to clone(), the new context has a\r\n * different node, position, or node set. What is not passed is\r\n * inherited from the cloned context.\r\n * @param opt_nodeList The node list for the new context. If not provided, the new context inherits the node list of the current context.\r\n * @param opt_position The position for the new context. If not provided, the new context inherits the position of the current context.\r\n * @returns A new ExprContext instance with the specified node list and position, and the current context as its parent.\r\n */\r\n clone(opt_nodeList?: XNode[], opt_position?: number) {\r\n return new ExprContext(\r\n opt_nodeList || this.nodeList,\r\n this.xsltVersion,\r\n typeof opt_position !== 'undefined' ? opt_position : this.position,\r\n this.decimalFormatSettings,\r\n Object.create(this.variables || {}),\r\n this.knownNamespaces,\r\n this,\r\n this.caseInsensitive,\r\n this.ignoreAttributesWithoutValue,\r\n this.returnOnFirstMatch,\r\n this.ignoreNonElementNodesForNTA,\r\n this.warningsCallback\r\n );\r\n }\r\n\r\n setVariable(name?: string, value?: NodeValue | string) {\r\n if (\r\n value instanceof StringValue ||\r\n value instanceof BooleanValue ||\r\n value instanceof NumberValue ||\r\n value instanceof NodeSetValue ||\r\n value instanceof MapValue ||\r\n value instanceof ArrayValue ||\r\n value instanceof FunctionValue\r\n ) {\r\n this.variables[name] = value;\r\n return;\r\n }\r\n\r\n if ('true' === value) {\r\n this.variables[name] = new BooleanValue(true);\r\n } else if ('false' === value) {\r\n this.variables[name] = new BooleanValue(false);\r\n } else if (TOK_NUMBER.re.test(String(value))) {\r\n this.variables[name] = new NumberValue(value);\r\n } else {\r\n // DGF What if it's null?\r\n this.variables[name] = new StringValue(value);\r\n }\r\n }\r\n\r\n getVariable(name: string): NodeValue {\r\n if (typeof this.variables[name] != 'undefined') {\r\n return this.variables[name];\r\n }\r\n\r\n if (this.parent) {\r\n return this.parent.getVariable(name);\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * Gets a regex group from xsl:analyze-string context.\r\n * Searches up the parent chain for regexGroups.\r\n * @param index Group index (0 = full match, 1+ = captured groups)\r\n * @returns The group value or empty string if not found\r\n */\r\n getRegexGroup(index: number): string {\r\n if (this.regexGroups && index >= 0 && index < this.regexGroups.length) {\r\n return this.regexGroups[index] ?? '';\r\n }\r\n\r\n if (this.parent) {\r\n return this.parent.getRegexGroup(index);\r\n }\r\n\r\n return '';\r\n }\r\n\r\n setNode(position: number) {\r\n this.position = position;\r\n }\r\n\r\n contextSize() {\r\n return this.nodeList.length;\r\n }\r\n\r\n isCaseInsensitive() {\r\n return this.caseInsensitive;\r\n }\r\n\r\n setCaseInsensitive(caseInsensitive: boolean): boolean {\r\n return (this.caseInsensitive = caseInsensitive);\r\n }\r\n\r\n isIgnoreAttributesWithoutValue(): boolean {\r\n return this.ignoreAttributesWithoutValue;\r\n }\r\n\r\n setIgnoreAttributesWithoutValue(ignore: boolean): boolean {\r\n return (this.ignoreAttributesWithoutValue = ignore);\r\n }\r\n\r\n isReturnOnFirstMatch(): boolean {\r\n return this.returnOnFirstMatch;\r\n }\r\n\r\n setReturnOnFirstMatch(returnOnFirstMatch: boolean): boolean {\r\n return (this.returnOnFirstMatch = returnOnFirstMatch);\r\n }\r\n\r\n isIgnoreNonElementNodesForNTA(): boolean {\r\n return this.ignoreNonElementNodesForNTA;\r\n }\r\n\r\n setIgnoreNonElementNodesForNTA(ignoreNonElementNodesForNTA: boolean): boolean {\r\n return (this.ignoreNonElementNodesForNTA = ignoreNonElementNodesForNTA);\r\n }\r\n}\r\n","// Copyright 2023-2026 Design Liquido\r\n// Match resolver that works with the new XPath implementation.\r\n\r\nimport { XNode } from '../dom';\r\nimport { ExprContext } from './expr-context';\r\nimport { Expression } from './expressions/expression';\r\nimport { LocationExpr } from './expressions/location-expr';\r\nimport { UnionExpr } from './expressions/union-expr';\r\n\r\n/**\r\n * Class that resolves XPath expressions, returning nodes.\r\n * This is used for XSLT pattern matching.\r\n */\r\nexport class MatchResolver {\r\n\r\n /**\r\n * Entry point for expression matching.\r\n * @param expression The expression to be resolved.\r\n * @param context The Expression Context.\r\n * @returns An array of nodes.\r\n */\r\n expressionMatch(expression: Expression, context: ExprContext): XNode[] {\r\n if (expression instanceof LocationExpr) {\r\n return this.locationExpressionMatch(expression, context);\r\n }\r\n\r\n if (expression instanceof UnionExpr) {\r\n return this.unionExpressionMatch(expression, context);\r\n }\r\n\r\n // For other expression types, evaluate and return node set\r\n try {\r\n const result = expression.evaluate(context);\r\n return result.nodeSetValue();\r\n } catch {\r\n return [];\r\n }\r\n }\r\n\r\n /**\r\n * Resolves a LocationExpr.\r\n * @param expression The Location Expression.\r\n * @param context The Expression Context.\r\n * @returns Either the results of a relative resolution, or the results of an\r\n * absolute resolution.\r\n */\r\n private locationExpressionMatch(expression: LocationExpr, context: ExprContext): XNode[] {\r\n if (!expression.steps || expression.steps.length <= 0) {\r\n // Handle \"/\" alone - matches the document root\r\n if (expression.absolute) {\r\n // Check if context node is the document node\r\n const contextNode = context.nodeList[context.position];\r\n if (contextNode.nodeName === '#document') {\r\n return [contextNode];\r\n }\r\n // Otherwise, no match\r\n return [];\r\n }\r\n // For relative expressions without steps, return current context node\r\n return [context.nodeList[context.position]];\r\n }\r\n\r\n if (expression.absolute) {\r\n // If expression is absolute and the axis of first step is self,\r\n // the match starts by the #document node.\r\n const firstStep = expression.steps[0];\r\n if (firstStep.axis === 'self') {\r\n return this.absoluteXsltMatchByDocumentNode(expression, context);\r\n }\r\n\r\n return this.absoluteXsltMatch(expression, context);\r\n }\r\n\r\n return this.relativeXsltMatch(expression, context);\r\n }\r\n\r\n /**\r\n * Resolves a UnionExpr.\r\n * @param expression The Union Expression.\r\n * @param context The Expression Context.\r\n * @returns The concatenated result of evaluating both sides of the expression.\r\n */\r\n private unionExpressionMatch(expression: UnionExpr, context: ExprContext): XNode[] {\r\n const expr1Nodes = this.expressionMatch(expression.expr1, context);\r\n return expr1Nodes.concat(this.expressionMatch(expression.expr2, context));\r\n }\r\n\r\n /**\r\n * Finds all the nodes through absolute XPath search, starting on\r\n * the #document parent node.\r\n * @param expression The Expression.\r\n * @param context The Expression Context.\r\n * @returns The list of found nodes.\r\n */\r\n private absoluteXsltMatchByDocumentNode(expression: LocationExpr, context: ExprContext): XNode[] {\r\n const clonedContext = context.clone([context.root], 0);\r\n const matchedNodes = expression.evaluate(clonedContext).nodeSetValue();\r\n const finalList: XNode[] = [];\r\n\r\n for (const element of matchedNodes) {\r\n if (element.id === context.nodeList[context.position].id) {\r\n finalList.push(element);\r\n }\r\n }\r\n\r\n return finalList;\r\n }\r\n\r\n /**\r\n * Finds all the nodes through absolute XPath search, starting with the\r\n * first child of the #document node.\r\n * @param expression The Expression.\r\n * @param context The Expression Context.\r\n * @returns The list of found nodes.\r\n */\r\n private absoluteXsltMatch(expression: LocationExpr, context: ExprContext): XNode[] {\r\n const firstChildOfRoot = context.root.childNodes.find((c: XNode) => c.nodeName !== '#dtd-section');\r\n if (!firstChildOfRoot) return [];\r\n\r\n const clonedContext = context.clone([firstChildOfRoot], 0);\r\n const matchedNodes = expression.evaluate(clonedContext).nodeSetValue();\r\n const finalList: XNode[] = [];\r\n\r\n // If the context is pointing to #document node, its child node is considered.\r\n let nodeList: XNode[];\r\n if (context.nodeList.length === 1 && context.nodeList[0].nodeName === '#document') {\r\n nodeList = [context.nodeList[0].childNodes.find((c: XNode) => c.nodeName !== '#dtd-section')];\r\n } else {\r\n nodeList = context.nodeList;\r\n }\r\n\r\n for (const element of matchedNodes) {\r\n if (element.id === nodeList[context.position]?.id) {\r\n finalList.push(element);\r\n }\r\n }\r\n\r\n return finalList;\r\n }\r\n\r\n /**\r\n * Tries to find relative nodes from the actual context position.\r\n * If found nodes are already in the context, or if they are children of\r\n * nodes in the context, they are returned.\r\n * @param expression The expression used.\r\n * @param context The Expression Context.\r\n * @returns The list of found nodes.\r\n */\r\n private relativeXsltMatch(expression: LocationExpr, context: ExprContext): XNode[] {\r\n const clonedContext = context.clone();\r\n const nodes = expression.evaluate(clonedContext).nodeSetValue();\r\n\r\n if (nodes.length === 1 && nodes[0].nodeName === '#document') {\r\n // As we don't work with the #document node directly, this part\r\n // returns its first sibling.\r\n return [nodes[0].childNodes[0]];\r\n }\r\n\r\n return nodes;\r\n }\r\n}\r\n","import { BooleanValue } from \"../values/boolean-value\";\r\nimport { NodeTest } from \"./node-test\";\r\n\r\nexport class NodeTestAny implements NodeTest {\r\n value: any;\r\n\r\n constructor() {\r\n this.value = new BooleanValue(true);\r\n }\r\n\r\n evaluate() {\r\n return this.value;\r\n }\r\n}\r\n","import { DOM_COMMENT_NODE } from \"../../constants\";\r\nimport { ExprContext } from \"../expr-context\";\r\nimport { NodeTest } from \"./node-test\";\r\nimport { BooleanValue } from \"../values/boolean-value\";\r\n\r\nexport class NodeTestComment implements NodeTest {\r\n evaluate(ctx: ExprContext) {\r\n return new BooleanValue(ctx.nodeList[ctx.position].nodeType == DOM_COMMENT_NODE);\r\n }\r\n}\r\n","import { DOM_ATTRIBUTE_NODE, DOM_ELEMENT_NODE } from \"../../constants\";\r\nimport { ExprContext } from \"../expr-context\";\r\nimport { BooleanValue } from \"../values/boolean-value\";\r\nimport { NodeTest } from \"./node-test\";\r\n\r\nexport class NodeTestElementOrAttribute implements NodeTest {\r\n evaluate(context: ExprContext) {\r\n const node = context.nodeList[context.position];\r\n return new BooleanValue(node.nodeType == DOM_ELEMENT_NODE || node.nodeType == DOM_ATTRIBUTE_NODE);\r\n }\r\n}\r\n","import { ExprContext } from \"../expr-context\";\r\nimport { NodeValue } from \"../values\";\r\nimport { BooleanValue } from \"../values/boolean-value\";\r\nimport { NodeTest } from \"./node-test\";\r\n\r\nexport class NodeTestName implements NodeTest {\r\n name: string;\r\n namespacePrefix: string;\r\n re: RegExp;\r\n\r\n constructor(name: string) {\r\n this.name = name;\r\n if (name.indexOf(':') > 0) {\r\n const nameAndNamespacePrefix = name.split(':');\r\n this.namespacePrefix = nameAndNamespacePrefix[0];\r\n this.name = nameAndNamespacePrefix[1];\r\n }\r\n\r\n this.re = new RegExp(`^${name}$`, 'i');\r\n }\r\n\r\n evaluate(context: ExprContext): NodeValue {\r\n const node = context.nodeList[context.position];\r\n if (this.namespacePrefix !== undefined) {\r\n const namespaceValue = context.knownNamespaces[this.namespacePrefix];\r\n if (namespaceValue !== node.namespaceUri) {\r\n return new BooleanValue(false);\r\n }\r\n\r\n if (context.caseInsensitive) {\r\n if (node.localName.length !== this.name.length) return new BooleanValue(false);\r\n return new BooleanValue(this.re.test(node.localName));\r\n }\r\n\r\n return new BooleanValue(node.localName === this.name);\r\n }\r\n\r\n if (context.caseInsensitive) {\r\n if (node.nodeName.length !== this.name.length) return new BooleanValue(false);\r\n return new BooleanValue(this.re.test(node.nodeName));\r\n }\r\n\r\n return new BooleanValue(node.nodeName === this.name);\r\n }\r\n}\r\n","import { ExprContext } from \"../expr-context\";\r\nimport { NodeTest } from \"./node-test\";\r\nimport { BooleanValue } from \"../values/boolean-value\";\r\n\r\nexport class NodeTestNC implements NodeTest {\r\n regex: RegExp;\r\n\r\n nsprefix: any;\r\n\r\n constructor(nsprefix: string) {\r\n this.regex = new RegExp(`^${nsprefix}:`);\r\n this.nsprefix = nsprefix;\r\n }\r\n\r\n evaluate(ctx: ExprContext) {\r\n const n = ctx.nodeList[ctx.position];\r\n return new BooleanValue(n.nodeName.match(this.regex));\r\n }\r\n}\r\n","import { DOM_PROCESSING_INSTRUCTION_NODE } from \"../../constants\";\r\nimport { ExprContext } from \"../expr-context\";\r\nimport { BooleanValue } from \"../values/boolean-value\";\r\nimport { NodeTest } from \"./node-test\";\r\n\r\nexport class NodeTestPI implements NodeTest {\r\n target: any;\r\n\r\n constructor(target: any) {\r\n this.target = target;\r\n }\r\n\r\n evaluate(context: ExprContext) {\r\n const node = context.nodeList[context.position];\r\n return new BooleanValue(\r\n node.nodeType == DOM_PROCESSING_INSTRUCTION_NODE && (!this.target || node.nodeName == this.target)\r\n );\r\n }\r\n}\r\n","import { DOM_TEXT_NODE } from \"../../constants\";\r\nimport { ExprContext } from \"../expr-context\";\r\nimport { BooleanValue } from \"../values/boolean-value\";\r\nimport { NodeTest } from \"./node-test\";\r\n\r\nexport class NodeTestText implements NodeTest {\r\n evaluate(ctx: ExprContext) {\r\n return new BooleanValue(ctx.nodeList[ctx.position].nodeType == DOM_TEXT_NODE);\r\n }\r\n}\r\n","import { PackageComponentInterface } from \"./package-component-interface\";\r\n\r\n/**\r\n * Create a component key for looking up components in the registry.\r\n */\r\nexport function makeComponentKey(component: PackageComponentInterface): string {\r\n switch (component.type) {\r\n case 'function':\r\n case 'variable':\r\n case 'attribute-set':\r\n return `${component.type}:${component.name || ''}`;\r\n case 'template':\r\n if (component.name) {\r\n return `template:name:${component.name}`;\r\n } else if (component.match) {\r\n const mode = component.mode || '#default';\r\n return `template:match:${mode}:${component.match}`;\r\n }\r\n return 'template:unknown';\r\n case 'mode':\r\n return `mode:${component.name || '#default'}`;\r\n default:\r\n return `unknown:${component.type}`;\r\n }\r\n}\r\n\r\n/**\r\n * Check if a component is visible (accessible) based on visibility rules.\r\n */\r\nexport function isComponentVisible(component: PackageComponentInterface, fromPackage: boolean): boolean {\r\n // Private components are only visible within the same package\r\n if (component.visibility === 'private') {\r\n return fromPackage;\r\n }\r\n \r\n // Public, final, and abstract components are visible from other packages\r\n return true;\r\n}\r\n\r\n/**\r\n * Check if a component can be overridden.\r\n */\r\nexport function canOverrideComponent(component: PackageComponentInterface): boolean {\r\n // Final components cannot be overridden\r\n if (component.visibility === 'final') {\r\n return false;\r\n }\r\n \r\n // Otherwise check the overridable flag\r\n return component.overridable;\r\n}\r\n","import { XsltPackageInterface } from \"./xslt-package-interface\";\r\n\r\n/**\r\n * Package registry for managing loaded packages.\r\n */\r\nexport class PackageRegistry {\r\n private packages: Map<string, XsltPackageInterface> = new Map();\r\n private loading: Set<string> = new Set();\r\n \r\n /**\r\n * Register a package in the registry.\r\n */\r\n register(pkg: XsltPackageInterface): void {\r\n const key = this.makePackageKey(pkg.name, pkg.version);\r\n this.packages.set(key, pkg);\r\n }\r\n \r\n /**\r\n * Retrieve a package from the registry.\r\n * Supports version constraints: exact, wildcards (1.*), ranges (>=1.0), and combined (>=1.0,<2.0).\r\n */\r\n get(name: string, version?: string): XsltPackageInterface | undefined {\r\n // If no version specified, try to get without version\r\n if (!version) {\r\n return this.packages.get(name);\r\n }\r\n\r\n // Try exact match first\r\n const exactKey = this.makePackageKey(name, version);\r\n const exactMatch = this.packages.get(exactKey);\r\n if (exactMatch) {\r\n return exactMatch;\r\n }\r\n\r\n // Check if version contains constraint operators\r\n const hasConstraint = /[*<>=,]/.test(version);\r\n if (!hasConstraint) {\r\n return undefined;\r\n }\r\n\r\n // Find all packages with matching name and filter by version constraint\r\n const matchingPackages: XsltPackageInterface[] = [];\r\n this.packages.forEach((pkg, key) => {\r\n if (pkg.name === name && pkg.version && this.satisfiesVersion(pkg.version, version)) {\r\n matchingPackages.push(pkg);\r\n }\r\n });\r\n\r\n if (matchingPackages.length === 0) {\r\n return undefined;\r\n }\r\n\r\n // Return highest matching version\r\n matchingPackages.sort((a, b) => this.compareVersions(b.version!, a.version!));\r\n return matchingPackages[0];\r\n }\r\n\r\n /**\r\n * Check if a package version satisfies a version constraint.\r\n */\r\n private satisfiesVersion(packageVersion: string, constraint: string): boolean {\r\n // Handle combined constraints (e.g., \">=1.0.0,<2.0.0\")\r\n if (constraint.includes(',')) {\r\n const constraints = constraint.split(',').map(c => c.trim());\r\n return constraints.every(c => this.satisfiesSingleConstraint(packageVersion, c));\r\n }\r\n return this.satisfiesSingleConstraint(packageVersion, constraint);\r\n }\r\n\r\n /**\r\n * Evaluate a single version constraint.\r\n */\r\n private satisfiesSingleConstraint(packageVersion: string, constraint: string): boolean {\r\n // Handle wildcard (e.g., \"1.*\", \"1.2.*\")\r\n if (constraint.includes('*')) {\r\n const prefix = constraint.replace(/\\*$/, '').replace(/\\.$/, '');\r\n if (!prefix) {\r\n return true; // \"*\" matches everything\r\n }\r\n // Check if package version starts with the prefix\r\n const pkgParts = packageVersion.split('.');\r\n const prefixParts = prefix.split('.');\r\n for (let i = 0; i < prefixParts.length; i++) {\r\n if (pkgParts[i] !== prefixParts[i]) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n // Handle comparison operators\r\n const operatorMatch = constraint.match(/^(>=|<=|>|<|=)?(.+)$/);\r\n if (!operatorMatch) {\r\n return false;\r\n }\r\n\r\n const operator = operatorMatch[1] || '=';\r\n const targetVersion = operatorMatch[2].trim();\r\n const comparison = this.compareVersions(packageVersion, targetVersion);\r\n\r\n switch (operator) {\r\n case '>=':\r\n return comparison >= 0;\r\n case '>':\r\n return comparison > 0;\r\n case '<=':\r\n return comparison <= 0;\r\n case '<':\r\n return comparison < 0;\r\n case '=':\r\n default:\r\n return comparison === 0;\r\n }\r\n }\r\n\r\n /**\r\n * Compare two semantic versions.\r\n * @returns -1 if a < b, 0 if a === b, 1 if a > b\r\n */\r\n private compareVersions(a: string, b: string): number {\r\n const aParts = a.split('.').map(p => parseInt(p, 10) || 0);\r\n const bParts = b.split('.').map(p => parseInt(p, 10) || 0);\r\n const maxLength = Math.max(aParts.length, bParts.length);\r\n\r\n for (let i = 0; i < maxLength; i++) {\r\n const aPart = aParts[i] || 0;\r\n const bPart = bParts[i] || 0;\r\n if (aPart < bPart) return -1;\r\n if (aPart > bPart) return 1;\r\n }\r\n return 0;\r\n }\r\n \r\n /**\r\n * Check if a package exists in the registry.\r\n */\r\n has(name: string, version?: string): boolean {\r\n const key = this.makePackageKey(name, version);\r\n return this.packages.has(key);\r\n }\r\n\r\n /**\r\n * Mark a package as currently being loaded.\r\n * Used to detect circular dependencies.\r\n * @returns true if the package can be loaded, false if it's already being loaded (circular dependency)\r\n */\r\n beginLoading(packageKey: string): boolean {\r\n if (this.loading.has(packageKey)) {\r\n return false; // Circular dependency detected\r\n }\r\n this.loading.add(packageKey);\r\n return true;\r\n }\r\n\r\n /**\r\n * Mark a package as finished loading.\r\n */\r\n endLoading(packageKey: string): void {\r\n this.loading.delete(packageKey);\r\n }\r\n\r\n /**\r\n * Check if a package is currently being loaded.\r\n * Used to detect circular dependencies when a package tries to use another package that is still loading.\r\n */\r\n isLoading(packageKey: string): boolean {\r\n return this.loading.has(packageKey);\r\n }\r\n \r\n /**\r\n * Create a unique key for a package based on name and version.\r\n */\r\n private makePackageKey(name: string, version?: string): string {\r\n return version ? `${name}@${version}` : name;\r\n }\r\n \r\n /**\r\n * Clear all registered packages.\r\n */\r\n clear(): void {\r\n this.packages.clear();\r\n this.loading.clear();\r\n }\r\n}\r\n","import { StreamablePath } from \"./streamable-path-interface\";\r\n\r\n/**\r\n * Utilities for validating and working with streamable patterns.\r\n */\r\nexport class StreamablePatternValidator {\r\n /**\r\n * Validate that a pattern is streamable.\r\n * Streamable patterns have restrictions:\r\n * - No backward axes\r\n * - No ancestor selection\r\n * - Limited predicate support\r\n */\r\n static validatePattern(pattern: string): { isStreamable: boolean; issues: string[] } {\r\n const issues: string[] = [];\r\n \r\n // Check for backward axes\r\n if (pattern.includes('ancestor::') || pattern.includes('ancestor-or-self::')) {\r\n issues.push('Ancestor axes are not permitted in streamable patterns');\r\n }\r\n \r\n // Check for parent axis\r\n if (pattern.includes('parent::')) {\r\n issues.push('Parent axis is not permitted in streamable patterns');\r\n }\r\n \r\n // Check for preceding axes\r\n if (pattern.includes('preceding::') || pattern.includes('preceding-sibling::')) {\r\n issues.push('Preceding axes are not permitted in streamable patterns');\r\n }\r\n \r\n // Check for complex predicates\r\n // (This is simplified - full implementation would parse predicate structure)\r\n const predicateMatches = pattern.match(/\\[.*\\]/g);\r\n if (predicateMatches) {\r\n for (const predicate of predicateMatches) {\r\n if (predicate.includes('[') && predicate.includes(']')) {\r\n // Nested predicates not allowed\r\n if (predicate.includes('[[')) {\r\n issues.push('Nested predicates are not permitted in streamable patterns');\r\n }\r\n }\r\n }\r\n }\r\n \r\n return {\r\n isStreamable: issues.length === 0,\r\n issues\r\n };\r\n }\r\n \r\n /**\r\n * Convert a pattern to streamable form if possible.\r\n */\r\n static toStreamablePath(pattern: string): StreamablePath | null {\r\n // Extract path from pattern\r\n const parts = pattern.split('/').filter(p => p.length > 0);\r\n \r\n if (parts.length === 0) {\r\n return null;\r\n }\r\n \r\n return {\r\n path: parts.map(p => p.split('[')[0]), // Remove predicates for now\r\n fromRoot: pattern.startsWith('/'),\r\n hasPredicates: pattern.includes('['),\r\n hasForwardAxis: pattern.includes('::'),\r\n isDeterministic: true // Simplified check\r\n };\r\n }\r\n}","import { CopyOperationInterface } from \"./copy-operation-interface\";\r\nimport { MergeSourceInterface } from \"./merge-source-interface\";\r\nimport { StreamingEventInterface } from \"./streaming-event-interface\";\r\n\r\n/**\r\n * Streaming context - tracks state during streaming document processing.\r\n */\r\nexport class StreamingContext {\r\n /** Stack of open elements during streaming */\r\n private elementStack: string[] = [];\r\n \r\n /** Current depth in document */\r\n private depth: number = 0;\r\n \r\n /** Copy operations in progress */\r\n private activeCopies: Map<string, CopyOperationInterface> = new Map();\r\n \r\n /** Merge sources being processed */\r\n private mergeSources: MergeSourceInterface[] = [];\r\n \r\n /** Whether streaming is in progress */\r\n private isStreaming: boolean = false;\r\n \r\n /** Buffer for lookahead when needed */\r\n private lookaheadBuffer: StreamingEventInterface[] = [];\r\n \r\n /**\r\n * Start streaming processing.\r\n */\r\n startStreaming(): void {\r\n this.elementStack = [];\r\n this.depth = 0;\r\n this.activeCopies.clear();\r\n this.isStreaming = true;\r\n }\r\n \r\n /**\r\n * End streaming processing.\r\n */\r\n endStreaming(): void {\r\n this.isStreaming = false;\r\n this.activeCopies.clear();\r\n this.lookaheadBuffer = [];\r\n }\r\n \r\n /**\r\n * Register a copy operation.\r\n */\r\n registerCopy(copy: CopyOperationInterface): void {\r\n this.activeCopies.set(copy.id, copy);\r\n }\r\n \r\n /**\r\n * Unregister a copy operation.\r\n */\r\n unregisterCopy(copyId: string): void {\r\n this.activeCopies.delete(copyId);\r\n }\r\n \r\n /**\r\n * Get all active copies.\r\n */\r\n getActiveCopies(): CopyOperationInterface[] {\r\n return Array.from(this.activeCopies.values()).filter(c => c.isActive);\r\n }\r\n \r\n /**\r\n * Push element onto stack when entering.\r\n */\r\n enterElement(name: string): void {\r\n this.elementStack.push(name);\r\n this.depth++;\r\n }\r\n \r\n /**\r\n * Pop element from stack when exiting.\r\n */\r\n exitElement(): string | undefined {\r\n this.depth--;\r\n return this.elementStack.pop();\r\n }\r\n \r\n /**\r\n * Get current element path.\r\n */\r\n getCurrentPath(): string[] {\r\n return [...this.elementStack];\r\n }\r\n \r\n /**\r\n * Get current depth.\r\n */\r\n getDepth(): number {\r\n return this.depth;\r\n }\r\n \r\n /**\r\n * Check if streaming is active.\r\n */\r\n isStreamingActive(): boolean {\r\n return this.isStreaming;\r\n }\r\n \r\n /**\r\n * Buffer event for lookahead.\r\n */\r\n bufferEvent(event: StreamingEventInterface): void {\r\n this.lookaheadBuffer.push(event);\r\n }\r\n \r\n /**\r\n * Get buffered events.\r\n */\r\n getBufferedEvents(): StreamingEventInterface[] {\r\n return this.lookaheadBuffer;\r\n }\r\n \r\n /**\r\n * Clear buffer.\r\n */\r\n clearBuffer(): void {\r\n this.lookaheadBuffer = [];\r\n }\r\n}\r\n","import { CopyOperationInterface as CopyOperationInterface } from \"./copy-operation-interface\";\r\nimport { StreamingEventInterface } from \"./streaming-event-interface\";\r\n\r\n/**\r\n * Copy mechanism for streaming - allows multiple independent processing branches.\r\n */\r\nexport class StreamingCopyManager {\r\n private copies: Map<string, CopyOperationInterface> = new Map();\r\n private copyIdCounter: number = 0;\r\n \r\n /**\r\n * Create a new copy operation.\r\n */\r\n createCopy(handler: (event: StreamingEventInterface) => Promise<void>): CopyOperationInterface {\r\n const id = `copy-${++this.copyIdCounter}`;\r\n const copy: CopyOperationInterface = {\r\n id,\r\n handler,\r\n isActive: true,\r\n eventQueue: [],\r\n currentDepth: 0\r\n };\r\n \r\n this.copies.set(id, copy);\r\n return copy;\r\n }\r\n \r\n /**\r\n * Distribute an event to all active copies.\r\n */\r\n async distributeEvent(event: StreamingEventInterface): Promise<void> {\r\n for (const copy of Array.from(this.copies.values())) {\r\n if (copy.isActive) {\r\n copy.eventQueue.push(event);\r\n // Could implement batching or async distribution here\r\n }\r\n }\r\n }\r\n \r\n /**\r\n * Close a copy operation.\r\n */\r\n closeCopy(copyId: string): void {\r\n const copy = this.copies.get(copyId);\r\n if (copy) {\r\n copy.isActive = false;\r\n }\r\n }\r\n \r\n /**\r\n * Get copy by ID.\r\n */\r\n getCopy(copyId: string): CopyOperationInterface | undefined {\r\n return this.copies.get(copyId);\r\n }\r\n \r\n /**\r\n * Clear all copies.\r\n */\r\n clear(): void {\r\n this.copies.clear();\r\n this.copyIdCounter = 0;\r\n }\r\n}\r\n","import { MergeSourceInterface as MergeSourceInterface } from \"./merge-source-interface\";\r\n\r\n/**\r\n * Merge operation coordinator for xsl:merge.\r\n */\r\nexport class StreamingMergeCoordinator {\r\n private sources: MergeSourceInterface[] = [];\r\n \r\n /**\r\n * Add a merge source.\r\n */\r\n addSource(source: MergeSourceInterface): void {\r\n this.sources.push(source);\r\n }\r\n \r\n /**\r\n * Get next item(s) for merging.\r\n * Returns the item(s) with the smallest merge key value.\r\n */\r\n getNextMergeGroup(): any[] {\r\n if (this.sources.every(s => s.isExhausted)) {\r\n return [];\r\n }\r\n \r\n // Find source with smallest key\r\n let minSource: MergeSourceInterface | null = null;\r\n let minKey: any = null;\r\n \r\n for (const source of this.sources) {\r\n if (!source.isExhausted && source.buffer.length > 0) {\r\n // Get key from first item in buffer\r\n // Simplified - full implementation would extract actual key\r\n if (minSource === null) {\r\n minSource = source;\r\n minKey = source.buffer[0];\r\n }\r\n }\r\n }\r\n \r\n if (minSource === null) {\r\n return [];\r\n }\r\n \r\n // Return all items from this source with same key\r\n const result: any[] = [];\r\n while (minSource.buffer.length > 0 && result.length < 1) { // Simplified\r\n result.push(minSource.buffer.shift());\r\n }\r\n \r\n return result;\r\n }\r\n \r\n /**\r\n * Check if merge is complete.\r\n */\r\n isComplete(): boolean {\r\n return this.sources.every(s => s.isExhausted && s.buffer.length === 0);\r\n }\r\n \r\n /**\r\n * Clear merge state.\r\n */\r\n clear(): void {\r\n this.sources = [];\r\n }\r\n}","import { XNode } from \"../../dom/xnode\";\r\nimport { StreamingMode } from \"./types\";\r\n\r\n/**\r\n * Streaming mode detector - determines how to process a template.\r\n */\r\nexport class StreamingModeDetector {\r\n /**\r\n * Determine streaming mode for a template.\r\n */\r\n static detectMode(templateNode: XNode): StreamingMode {\r\n // Check for streamable attribute\r\n const streamableAttr = templateNode.getAttributeValue?.('streamable');\r\n \r\n if (streamableAttr === 'yes') {\r\n return 'streamed';\r\n }\r\n \r\n if (streamableAttr === 'no') {\r\n return 'non-consuming';\r\n }\r\n \r\n // Default for XSLT 3.0\r\n return 'non-consuming';\r\n }\r\n \r\n /**\r\n * Check if template body is streamable.\r\n */\r\n static isTemplateBodyStreamable(templateNode: XNode): boolean {\r\n // Check for non-streamable instructions\r\n const nonStreamableInstructions = [\r\n 'xsl:variable', // Variables consume input\r\n 'xsl:result-document', // Can't produce multiple documents in streaming\r\n 'xsl:for-each', // Can't iterate over sequences in streaming\r\n ];\r\n \r\n // Simplified check - full implementation would traverse template\r\n return true;\r\n }\r\n}\r\n","import { StreamingEventInterface } from \"./streaming-event-interface\";\r\nimport { StreamingParserInterface } from \"./streaming-parser-interface\";\r\nimport { XmlParser, XNode } from \"../../dom\";\r\nimport {\r\n DOM_ATTRIBUTE_NODE,\r\n DOM_CDATA_SECTION_NODE,\r\n DOM_COMMENT_NODE,\r\n DOM_DOCUMENT_NODE,\r\n DOM_ELEMENT_NODE,\r\n DOM_PROCESSING_INSTRUCTION_NODE,\r\n DOM_TEXT_NODE\r\n} from \"../../constants\";\r\n\r\n/**\r\n * Base implementation of streaming parser.\r\n * This version works with existing DOM-based documents and emits events.\r\n */\r\nexport class StreamingParserBase implements StreamingParserInterface {\r\n /**\r\n * Convert a DOM document to streaming events.\r\n * This is a fallback for when a true streaming parser isn't available.\r\n */\r\n async parse(source: string, handler: (event: StreamingEventInterface) => Promise<void>): Promise<void> {\r\n const parser = new XmlParser();\r\n const document = parser.xmlParse(source);\r\n\r\n // Emit document start event\r\n await handler({\r\n type: 'document-start',\r\n depth: 0\r\n });\r\n\r\n // Emit document content events\r\n for (const child of document.childNodes) {\r\n await this.emitNode(child, handler, 0);\r\n }\r\n\r\n // Emit document end event\r\n await handler({\r\n type: 'document-end',\r\n depth: 0\r\n });\r\n }\r\n \r\n /**\r\n * Check if document can be streamed.\r\n */\r\n async canStream(source: string): Promise<boolean> {\r\n // Streaming is possible for any well-formed XML\r\n // More sophisticated checks could validate structure\r\n return true;\r\n }\r\n\r\n private async emitNode(node: XNode, handler: (event: StreamingEventInterface) => Promise<void>, depth: number): Promise<void> {\r\n switch (node.nodeType) {\r\n case DOM_DOCUMENT_NODE: {\r\n for (const child of node.childNodes) {\r\n await this.emitNode(child, handler, depth);\r\n }\r\n return;\r\n }\r\n case DOM_ELEMENT_NODE: {\r\n const attributeNodes = node.childNodes.filter(n => n.nodeType === DOM_ATTRIBUTE_NODE);\r\n const attributes = attributeNodes.length > 0 ? new Map<string, string>() : undefined;\r\n\r\n if (attributes) {\r\n for (const attribute of attributeNodes) {\r\n attributes.set(attribute.nodeName, `${attribute.nodeValue ?? ''}`);\r\n await handler({\r\n type: 'attribute',\r\n name: attribute.nodeName,\r\n namespaceUri: attribute.namespaceUri || undefined,\r\n content: `${attribute.nodeValue ?? ''}`,\r\n depth: depth + 1\r\n });\r\n }\r\n }\r\n\r\n const nonAttributeChildren = node.childNodes.filter(n => n.nodeType !== DOM_ATTRIBUTE_NODE);\r\n await handler({\r\n type: 'start-element',\r\n name: node.nodeName,\r\n namespaceUri: node.namespaceUri || undefined,\r\n attributes,\r\n selfClosing: nonAttributeChildren.length === 0,\r\n depth: depth + 1\r\n });\r\n\r\n for (const child of nonAttributeChildren) {\r\n await this.emitNode(child, handler, depth + 1);\r\n }\r\n\r\n await handler({\r\n type: 'end-element',\r\n name: node.nodeName,\r\n namespaceUri: node.namespaceUri || undefined,\r\n depth: depth + 1\r\n });\r\n return;\r\n }\r\n case DOM_TEXT_NODE:\r\n case DOM_CDATA_SECTION_NODE: {\r\n const text = `${node.nodeValue ?? ''}`;\r\n if (text.length > 0) {\r\n await handler({\r\n type: 'text',\r\n content: text,\r\n depth: depth + 1\r\n });\r\n }\r\n return;\r\n }\r\n case DOM_COMMENT_NODE: {\r\n await handler({\r\n type: 'comment',\r\n content: `${node.nodeValue ?? ''}`,\r\n depth: depth + 1\r\n });\r\n return;\r\n }\r\n case DOM_PROCESSING_INSTRUCTION_NODE: {\r\n await handler({\r\n type: 'processing-instruction',\r\n name: node.nodeName,\r\n content: `${node.nodeValue ?? ''}`,\r\n depth: depth + 1\r\n });\r\n return;\r\n }\r\n default:\r\n return;\r\n }\r\n }\r\n}\r\n","/**\r\n * XSLT 3.0 Streaming Processor\r\n * \r\n * Encapsulates the streaming-related XSLT instructions:\r\n * - xsl:stream\r\n * - xsl:fork\r\n * - xsl:merge\r\n * \r\n * This class coordinates streaming context, copy management, and merge operations.\r\n */\r\n\r\nimport { XNode } from \"../../dom/xnode\";\r\nimport { ExprContext } from \"../../xpath/expr-context\";\r\nimport { XPath } from \"../../xpath/xpath\";\r\nimport { xmlGetAttribute } from \"../../dom/xml-functions\";\r\nimport { StreamingContext } from \"./streaming-context\";\r\nimport { StreamingCopyManager } from \"./streaming-copy-manager\";\r\nimport { StreamingMergeCoordinator } from \"./streaming-merge-coordinator\";\r\nimport { StreamingParserInterface } from \"./streaming-parser-interface\";\r\nimport { StreamingParserBase } from \"./streaming-parser-base\";\r\nimport { StreamablePatternValidator } from \"./streamable-pattern-validator\";\r\nimport { StreamingModeDetector } from \"./streaming-mode-detector\";\r\nimport { StreamingEventInterface } from \"./streaming-event-interface\";\r\nimport { MergeSourceInterface } from \"./merge-source-interface\";\r\n\r\n/**\r\n * Configuration options for the streaming processor.\r\n */\r\nexport interface StreamingProcessorOptions {\r\n /** Reference to XPath evaluator for expression evaluation */\r\n xPath: XPath;\r\n /** XSLT version being processed */\r\n version: string;\r\n}\r\n\r\n/**\r\n * Callback interface for processing child nodes during streaming.\r\n */\r\nexport interface StreamingChildProcessor {\r\n /**\r\n * Process child nodes of a template element.\r\n * @param context Expression context\r\n * @param template Template node containing children\r\n * @param output Output node for results\r\n */\r\n processChildren(context: ExprContext, template: XNode, output?: XNode): Promise<void>;\r\n \r\n /**\r\n * Check if a node is an XSLT element with the given local name.\r\n * @param node Node to check\r\n * @param name Optional local name to match\r\n */\r\n isXsltElement(node: XNode, name?: string): boolean;\r\n}\r\n\r\n/**\r\n * Streaming processor for XSLT 3.0 streaming instructions.\r\n * Delegates to specialized managers for different streaming operations.\r\n */\r\nexport class StreamingProcessor {\r\n /** Streaming context for tracking state during streaming */\r\n private context: StreamingContext = new StreamingContext();\r\n \r\n /** Copy manager for xsl:fork operations */\r\n private copyManager: StreamingCopyManager = new StreamingCopyManager();\r\n \r\n /** Merge coordinator for xsl:merge operations */\r\n private mergeCoordinator: StreamingMergeCoordinator = new StreamingMergeCoordinator();\r\n \r\n /** Whether streaming is currently enabled */\r\n private enabled: boolean = false;\r\n \r\n /** Streaming parser implementation */\r\n private parser: StreamingParserInterface = new StreamingParserBase();\r\n \r\n /** XPath evaluator reference */\r\n private xPath: XPath;\r\n \r\n /** XSLT version */\r\n private version: string;\r\n\r\n constructor(options: StreamingProcessorOptions) {\r\n this.xPath = options.xPath;\r\n this.version = options.version;\r\n }\r\n\r\n /**\r\n * Update the version (called when version is determined from stylesheet).\r\n */\r\n setVersion(version: string): void {\r\n this.version = version;\r\n }\r\n\r\n /**\r\n * Check if streaming is currently enabled.\r\n */\r\n isEnabled(): boolean {\r\n return this.enabled;\r\n }\r\n\r\n /**\r\n * Get the streaming context.\r\n */\r\n getContext(): StreamingContext {\r\n return this.context;\r\n }\r\n\r\n /**\r\n * Get the copy manager.\r\n */\r\n getCopyManager(): StreamingCopyManager {\r\n return this.copyManager;\r\n }\r\n\r\n /**\r\n * Get the merge coordinator.\r\n */\r\n getMergeCoordinator(): StreamingMergeCoordinator {\r\n return this.mergeCoordinator;\r\n }\r\n\r\n /**\r\n * Set a custom streaming parser implementation.\r\n */\r\n setParser(parser: StreamingParserInterface): void {\r\n this.parser = parser;\r\n }\r\n\r\n /**\r\n * Validate that a pattern is streamable.\r\n */\r\n validatePattern(pattern: string): { isStreamable: boolean; issues: string[] } {\r\n return StreamablePatternValidator.validatePattern(pattern);\r\n }\r\n\r\n /**\r\n * Detect the streaming mode for a template.\r\n */\r\n detectMode(templateNode: XNode): ReturnType<typeof StreamingModeDetector.detectMode> {\r\n return StreamingModeDetector.detectMode(templateNode);\r\n }\r\n\r\n /**\r\n * Implements `<xsl:stream>` (XSLT 3.0 Section 16).\r\n * Enables streaming processing of large documents.\r\n * \r\n * @param exprContext The Expression Context.\r\n * @param template The xsl:stream element.\r\n * @param output The output node.\r\n * @param childProcessor Callback for processing child nodes.\r\n */\r\n async processStream(\r\n exprContext: ExprContext,\r\n template: XNode,\r\n output: XNode | undefined,\r\n childProcessor: StreamingChildProcessor\r\n ): Promise<void> {\r\n // Check XSLT version\r\n if (!this.version || parseFloat(this.version) < 3.0) {\r\n throw new Error('<xsl:stream> is only supported in XSLT 3.0 or later.');\r\n }\r\n\r\n // Get select attribute (required)\r\n const select = xmlGetAttribute(template, 'select');\r\n if (!select) {\r\n throw new Error('<xsl:stream> requires a \"select\" attribute specifying the input document.');\r\n }\r\n\r\n // Enable streaming mode\r\n const previouslyEnabled = this.enabled;\r\n this.enabled = true;\r\n this.context.startStreaming();\r\n\r\n try {\r\n // Evaluate select to get document(s) to stream\r\n const contextClone = exprContext.clone();\r\n const selectedValue = this.xPath.xPathEval(select, contextClone);\r\n\r\n // Process selected document(s) in streaming mode\r\n let nodes: XNode[] = [];\r\n if (selectedValue.type === 'node-set') {\r\n nodes = selectedValue.nodeSetValue();\r\n } else if (selectedValue.type === 'node') {\r\n nodes = [selectedValue] as any as XNode[];\r\n }\r\n\r\n // For each selected node, process its children with streaming\r\n for (const node of nodes) {\r\n await childProcessor.processChildren(exprContext, template, output);\r\n }\r\n } finally {\r\n // Disable streaming mode\r\n this.enabled = previouslyEnabled;\r\n this.context.endStreaming();\r\n this.copyManager.clear();\r\n }\r\n }\r\n\r\n /**\r\n * Implements `<xsl:fork>` (XSLT 3.0 Section 17).\r\n * Creates multiple independent output branches from the input stream.\r\n * \r\n * @param exprContext The Expression Context.\r\n * @param template The xsl:fork element.\r\n * @param output The output node.\r\n * @param childProcessor Callback for processing child nodes.\r\n */\r\n async processFork(\r\n exprContext: ExprContext,\r\n template: XNode,\r\n output: XNode | undefined,\r\n childProcessor: StreamingChildProcessor\r\n ): Promise<void> {\r\n // Check that we're in streaming mode\r\n if (!this.enabled) {\r\n throw new Error('<xsl:fork> can only be used within <xsl:stream>.');\r\n }\r\n\r\n // Process each xsl:fork-sequence child\r\n for (const child of template.childNodes) {\r\n if (childProcessor.isXsltElement(child, 'fork-sequence')) {\r\n // Each fork-sequence creates an independent branch\r\n const copy = this.copyManager.createCopy(async (event: StreamingEventInterface) => {\r\n // Process the fork-sequence with the streaming events\r\n await childProcessor.processChildren(exprContext, child, output);\r\n });\r\n\r\n // Register copy with context for event distribution\r\n this.context.registerCopy(copy);\r\n\r\n // Distribute events from stream to this copy\r\n // Full implementation would integrate with the streaming parser\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Implements `<xsl:merge>` (XSLT 3.0 Section 15).\r\n * Merges multiple sorted input sequences.\r\n * \r\n * @param exprContext The Expression Context.\r\n * @param template The xsl:merge element.\r\n * @param output The output node.\r\n * @param childProcessor Callback for processing child nodes.\r\n */\r\n async processMerge(\r\n exprContext: ExprContext,\r\n template: XNode,\r\n output: XNode | undefined,\r\n childProcessor: StreamingChildProcessor\r\n ): Promise<void> {\r\n // Check XSLT version\r\n if (!this.version || parseFloat(this.version) < 3.0) {\r\n throw new Error('<xsl:merge> is only supported in XSLT 3.0 or later.');\r\n }\r\n\r\n // Get merge sources from xsl:merge-source children\r\n const sources: MergeSourceInterface[] = [];\r\n for (const child of template.childNodes) {\r\n if (childProcessor.isXsltElement(child, 'merge-source')) {\r\n const selectAttr = xmlGetAttribute(child, 'select');\r\n if (!selectAttr) {\r\n throw new Error('<xsl:merge-source> requires a \"select\" attribute.');\r\n }\r\n\r\n // Create merge source\r\n const source: MergeSourceInterface = {\r\n select: selectAttr,\r\n mergeKeys: [],\r\n position: 0,\r\n isExhausted: false,\r\n buffer: []\r\n };\r\n\r\n // Get merge keys from xsl:merge-key children\r\n for (const keyChild of child.childNodes) {\r\n if (childProcessor.isXsltElement(keyChild, 'merge-key')) {\r\n const keySelect = xmlGetAttribute(keyChild, 'select');\r\n const order = (xmlGetAttribute(keyChild, 'order') || 'ascending') as 'ascending' | 'descending';\r\n\r\n source.mergeKeys.push({\r\n select: keySelect || '.',\r\n order\r\n });\r\n }\r\n }\r\n\r\n // Evaluate the select expression to populate the buffer\r\n const result = this.xPath.xPathEval(selectAttr, exprContext);\r\n const nodes = result.nodeSetValue ? result.nodeSetValue() : [];\r\n source.buffer = Array.isArray(nodes) ? nodes.slice() : (nodes ? [nodes] : []);\r\n source.isExhausted = source.buffer.length === 0;\r\n\r\n sources.push(source);\r\n }\r\n }\r\n\r\n if (sources.length === 0) {\r\n throw new Error('<xsl:merge> requires at least one <xsl:merge-source> child element.');\r\n }\r\n\r\n // Add sources to coordinator\r\n for (const source of sources) {\r\n this.mergeCoordinator.addSource(source);\r\n }\r\n\r\n try {\r\n // Process merge groups - iterate through all items in sources\r\n // For a basic implementation, we process merge-action once for each source that has data\r\n let hasData = sources.some(s => s.buffer.length > 0);\r\n \r\n if (hasData) {\r\n // For each source that has items, process the merge-action\r\n for (const source of sources) {\r\n while (source.buffer.length > 0) {\r\n const item = source.buffer.shift();\r\n \r\n // Create context with the current merge item\r\n const mergeContext = exprContext.clone([item], 0);\r\n \r\n // Process merge group with xsl:merge-action\r\n for (const child of template.childNodes) {\r\n if (childProcessor.isXsltElement(child, 'merge-action')) {\r\n await childProcessor.processChildren(mergeContext, child, output);\r\n }\r\n }\r\n }\r\n source.isExhausted = true;\r\n }\r\n }\r\n } finally {\r\n this.mergeCoordinator.clear();\r\n }\r\n }\r\n\r\n /**\r\n * Clear all streaming state.\r\n */\r\n reset(): void {\r\n this.enabled = false;\r\n this.context.endStreaming();\r\n this.copyManager.clear();\r\n this.mergeCoordinator.clear();\r\n }\r\n}\r\n","import { XNode } from \"../dom/xnode\";\r\nimport { DOM_ELEMENT_NODE } from '../constants';\r\nimport { ExprContext, XPath, MatchResolver, Expression, LocationExpr, UnionExpr } from \"../xpath\";\r\n\r\nimport { NodeTestAny, NodeTestComment, NodeTestElementOrAttribute, NodeTestName, NodeTestNC, NodeTestPI, NodeTestText } from \"../xpath/node-tests\";\r\nimport { TemplatePriorityInterface, TemplateSelectionResultInterface } from \"./template-mechanics\";\r\n\r\n/**\r\n * Calculate the default priority for a single step pattern.\r\n *\r\n * According to XSLT 3.0 spec section 6.4:\r\n * - Priority -0.5: node tests of form node(), text(), comment(),\r\n * processing-instruction(), *, @*, namespace::*\r\n * - Priority -0.25: namespace wildcards like ns:*, @ns:*\r\n * - Priority 0: qualified names like foo, @bar, processing-instruction('literal')\r\n * - Priority 0.5: patterns with multiple steps or predicates\r\n */\r\nfunction calculateStepPriority(step: any): number {\r\n const nodeTest = step.nodeTest;\r\n const hasPredicates = (step.predicate && step.predicate.length > 0) ||\r\n (step.predicates && step.predicates.length > 0);\r\n\r\n // Predicates always result in 0.5\r\n if (hasPredicates) {\r\n return 0.5;\r\n }\r\n\r\n // Handle new XPath implementation's object-based node tests\r\n if (nodeTest && typeof nodeTest === 'object' && 'type' in nodeTest) {\r\n switch (nodeTest.type) {\r\n case 'wildcard':\r\n // Check for namespace wildcard like \"ns:*\"\r\n if (nodeTest.name && nodeTest.name.endsWith(':*')) {\r\n return -0.25;\r\n }\r\n // Regular wildcard * or @*\r\n return -0.5;\r\n\r\n case 'node-type':\r\n // node(), text(), comment(), processing-instruction()\r\n if (nodeTest.nodeType === 'processing-instruction' && nodeTest.name) {\r\n // processing-instruction('literal') has priority 0\r\n return 0;\r\n }\r\n return -0.5;\r\n\r\n case 'processing-instruction':\r\n // processing-instruction('literal') or processing-instruction()\r\n // The target is stored in nodeTest.target or nodeTest.name\r\n return (nodeTest.target || nodeTest.name) ? 0 : -0.5;\r\n\r\n case 'name':\r\n // Qualified name like foo, ns:foo, @bar\r\n return 0;\r\n\r\n default:\r\n return 0;\r\n }\r\n }\r\n\r\n // Handle legacy class-based node tests (for backward compatibility)\r\n if (nodeTest instanceof NodeTestAny) {\r\n // node() - matches any node\r\n return -0.5;\r\n }\r\n\r\n if (nodeTest instanceof NodeTestElementOrAttribute) {\r\n // * or @* - wildcard for elements or attributes\r\n return -0.5;\r\n }\r\n\r\n if (nodeTest instanceof NodeTestText) {\r\n // text()\r\n return -0.5;\r\n }\r\n\r\n if (nodeTest instanceof NodeTestComment) {\r\n // comment()\r\n return -0.5;\r\n }\r\n\r\n if (nodeTest instanceof NodeTestPI) {\r\n // processing-instruction() - with literal = 0, without = -0.5\r\n return nodeTest.target ? 0 : -0.5;\r\n }\r\n\r\n if (nodeTest instanceof NodeTestNC) {\r\n // Namespace wildcard like ns:* - priority -0.25\r\n return -0.25;\r\n }\r\n\r\n if (nodeTest instanceof NodeTestName) {\r\n // Qualified name like foo, ns:foo, @bar\r\n return 0;\r\n }\r\n\r\n // Default fallback\r\n return 0;\r\n}\r\n\r\n/**\r\n * Calculate the default priority for a location path expression.\r\n */\r\nfunction calculateLocationPathPriority(expr: LocationExpr): number {\r\n if (!expr.steps || expr.steps.length === 0) {\r\n // \"/\" alone (absolute path with no steps) matches the document root\r\n // According to XSLT spec, this has priority -0.5\r\n if (expr.absolute) {\r\n return -0.5;\r\n }\r\n return 0;\r\n }\r\n\r\n // Multiple steps = priority 0.5\r\n if (expr.steps.length > 1) {\r\n return 0.5;\r\n }\r\n\r\n // Single step - check for explicit axis (other than child/attribute)\r\n const step = expr.steps[0];\r\n const axis = step.axis;\r\n\r\n // If the pattern uses an explicit axis other than the default (child/attribute),\r\n // it's considered a more complex pattern with priority 0.5\r\n // Default axes are: child (for elements) and attribute (for @)\r\n if (axis && axis !== 'child' && axis !== 'attribute' && axis !== 'self-and-siblings') {\r\n return 0.5;\r\n }\r\n\r\n // Single step with default axis - calculate based on the step's node test\r\n return calculateStepPriority(step);\r\n}\r\n\r\n/**\r\n * Calculate the default priority for a union expression.\r\n * For union patterns like \"foo | bar\", each alternative is treated as a\r\n * separate rule. When used as a single template, we return the lowest priority\r\n * among all alternatives (most conservative).\r\n */\r\nfunction calculateUnionExprPriority(expr: UnionExpr, xPath: XPath): number {\r\n const priority1 = calculateDefaultPriorityFromExpression(expr.expr1, xPath);\r\n const priority2 = calculateDefaultPriorityFromExpression(expr.expr2, xPath);\r\n // Return the lowest (most conservative) priority for union patterns\r\n return Math.min(priority1, priority2);\r\n}\r\n\r\n/**\r\n * Calculate the default priority from a parsed expression.\r\n */\r\nfunction calculateDefaultPriorityFromExpression(expr: Expression, xPath: XPath): number {\r\n if (expr instanceof LocationExpr) {\r\n return calculateLocationPathPriority(expr);\r\n }\r\n\r\n if (expr instanceof UnionExpr) {\r\n return calculateUnionExprPriority(expr, xPath);\r\n }\r\n\r\n // For other expression types (filter, path, function call, etc.),\r\n // use priority 0.5 as they represent complex patterns\r\n return 0.5;\r\n}\r\n\r\n/**\r\n * Calculate the default priority for an XSLT pattern string.\r\n *\r\n * @param pattern The match pattern string (e.g., \"book\", \"chapter/title\", \"*\")\r\n * @param xPath The XPath instance for parsing\r\n * @returns The calculated default priority\r\n */\r\nexport function calculateDefaultPriority(\r\n pattern: string,\r\n xPath: XPath,\r\n warningsCallback?: (...args: any[]) => void\r\n): number {\r\n try {\r\n // Parse without axis override to preserve original axis for priority calculation\r\n const expr = xPath.xPathParse(pattern);\r\n return calculateDefaultPriorityFromExpression(expr, xPath);\r\n } catch (e) {\r\n // If parsing fails, return default priority 0\r\n const warn = warningsCallback ?? console.warn;\r\n warn(`Failed to parse pattern \"${pattern}\" for priority calculation:`, e);\r\n return 0;\r\n }\r\n}\r\n\r\n/**\r\n * Check if a template matches the given mode.\r\n * A template matches if:\r\n * - mode is null/undefined and template has no mode attribute\r\n * - mode is '#all' (matches any template)\r\n * - template mode equals the given mode\r\n * - template mode is '#all'\r\n */\r\nfunction matchesMode(template: XNode, mode: string | null): boolean {\r\n const templateMode = template.getAttributeValue('mode');\r\n\r\n // If no mode specified in apply-templates, match templates without mode\r\n if (!mode) {\r\n return !templateMode || templateMode === '#default';\r\n }\r\n\r\n // Mode '#all' in apply-templates matches any template\r\n if (mode === '#all') {\r\n return true;\r\n }\r\n\r\n // Template with mode '#all' matches any mode\r\n if (templateMode === '#all') {\r\n return true;\r\n }\r\n\r\n // Direct mode match\r\n return templateMode === mode;\r\n}\r\n\r\n/**\r\n * Check if a node is an xsl:template element.\r\n */\r\nfunction isTemplate(node: XNode): boolean {\r\n if (node.nodeType !== DOM_ELEMENT_NODE) {\r\n return false;\r\n }\r\n\r\n // Check by namespace URI or prefix\r\n if (node.namespaceUri === 'http://www.w3.org/1999/XSL/Transform') {\r\n return node.localName === 'template';\r\n }\r\n\r\n return node.prefix === 'xsl' && node.localName === 'template';\r\n}\r\n\r\n/**\r\n * Calculate priority for a single pattern alternative (non-union).\r\n * This is used when expanding union patterns into separate template entries.\r\n *\r\n * @param pattern Single pattern alternative (should not contain '|' at top level)\r\n * @param xPath XPath instance for parsing\r\n * @returns The default priority for this single pattern\r\n */\r\nfunction calculateSinglePatternPriority(pattern: string, xPath: XPath): number {\r\n try {\r\n const expr = xPath.xPathParse(pattern);\r\n // Use the same logic as calculateDefaultPriorityFromExpression but\r\n // this should not encounter unions since we've already split them\r\n if (expr instanceof LocationExpr) {\r\n return calculateLocationPathPriority(expr);\r\n }\r\n // For other expressions, use 0.5 as they represent complex patterns\r\n return 0.5;\r\n } catch (e) {\r\n return 0;\r\n }\r\n}\r\n\r\n/**\r\n * Collect all templates from the stylesheet with their priority metadata.\r\n *\r\n * Per XSLT 1.0 Section 5.3: \"If a template rule contains a pattern that is a union\r\n * of multiple alternatives, then the rule is equivalent to a set of template rules,\r\n * one for each alternative.\"\r\n *\r\n * This function expands union patterns (like \"foo|bar\") into separate template\r\n * entries, each with the priority of its specific alternative.\r\n *\r\n * @param stylesheetElement The root element of the stylesheet (xsl:stylesheet or xsl:transform)\r\n * @param mode The mode to filter templates by (null for default mode)\r\n * @param xPath The XPath instance for parsing patterns\r\n * @returns Array of templates with priority metadata\r\n */\r\nexport function collectAndExpandTemplates(\r\n stylesheetElement: XNode,\r\n mode: string | null,\r\n xPath: XPath,\r\n templateSourceMap?: Map<XNode, { importDepth: number; href: string; order: number }>\r\n): TemplatePriorityInterface[] {\r\n const templates: TemplatePriorityInterface[] = [];\r\n let docOrder = 0;\r\n\r\n for (const child of stylesheetElement.childNodes) {\r\n if (!isTemplate(child)) {\r\n continue;\r\n }\r\n\r\n if (!matchesMode(child, mode)) {\r\n continue;\r\n }\r\n\r\n const match = child.getAttributeValue('match');\r\n if (!match) {\r\n // Templates without match attribute are named templates, skip them\r\n continue;\r\n }\r\n\r\n const priorityAttr = child.getAttributeValue('priority');\r\n const explicitPriority = priorityAttr ? parseFloat(priorityAttr) : null;\r\n\r\n // Get import precedence from template source map.\r\n // XSLT import precedence depends first on import depth (shallower = higher),\r\n // and then on import order among stylesheets imported at the same depth\r\n // (later imports have higher precedence).\r\n const metadata = templateSourceMap?.get(child);\r\n let importPrecedence = 0;\r\n if (metadata) {\r\n const DEPTH_WEIGHT = Number.MAX_SAFE_INTEGER / 2;\r\n const depthComponent = -metadata.importDepth * DEPTH_WEIGHT; // Negative so main stylesheet has highest precedence\r\n const orderComponent = (metadata as any).order ?? 0;\r\n importPrecedence = depthComponent + orderComponent;\r\n }\r\n\r\n // Per XSLT 1.0 Section 5.3, expand union patterns into separate entries\r\n // Each alternative gets its own priority calculation\r\n const alternatives = splitUnionPattern(match);\r\n\r\n for (const alternative of alternatives) {\r\n // Calculate default priority for this specific alternative\r\n const defaultPriority = calculateSinglePatternPriority(alternative, xPath);\r\n const effectivePriority = explicitPriority !== null && !isNaN(explicitPriority)\r\n ? explicitPriority\r\n : defaultPriority;\r\n\r\n templates.push({\r\n template: child,\r\n explicitPriority: explicitPriority !== null && !isNaN(explicitPriority) ? explicitPriority : null,\r\n defaultPriority,\r\n effectivePriority,\r\n importPrecedence,\r\n documentOrder: docOrder++,\r\n matchPattern: alternative // Use the individual alternative, not the full union\r\n });\r\n }\r\n }\r\n\r\n return templates;\r\n}\r\n\r\n/**\r\n * Split a pattern string by the union operator '|', respecting brackets and quotes.\r\n * For example: \"@*|node()\" -> [\"@*\", \"node()\"]\r\n * But: \"item[@id='a|b']\" -> [\"item[@id='a|b']\"] (not split inside quotes)\r\n *\r\n * @param pattern The pattern string to split\r\n * @returns Array of pattern alternatives\r\n */\r\nfunction splitUnionPattern(pattern: string): string[] {\r\n const alternatives: string[] = [];\r\n let current = '';\r\n let depth = 0; // Track bracket depth\r\n let inSingleQuote = false;\r\n let inDoubleQuote = false;\r\n\r\n for (let i = 0; i < pattern.length; i++) {\r\n const char = pattern[i];\r\n\r\n if (char === \"'\" && !inDoubleQuote) {\r\n inSingleQuote = !inSingleQuote;\r\n current += char;\r\n } else if (char === '\"' && !inSingleQuote) {\r\n inDoubleQuote = !inDoubleQuote;\r\n current += char;\r\n } else if (!inSingleQuote && !inDoubleQuote) {\r\n if (char === '[' || char === '(') {\r\n depth++;\r\n current += char;\r\n } else if (char === ']' || char === ')') {\r\n depth--;\r\n current += char;\r\n } else if (char === '|' && depth === 0) {\r\n // Union operator at top level\r\n alternatives.push(current.trim());\r\n current = '';\r\n } else {\r\n current += char;\r\n }\r\n } else {\r\n current += char;\r\n }\r\n }\r\n\r\n // Don't forget the last alternative\r\n if (current.trim()) {\r\n alternatives.push(current.trim());\r\n }\r\n\r\n return alternatives;\r\n}\r\n\r\n/**\r\n * Check if a node matches a single (non-union) pattern.\r\n *\r\n * @param node The node to test\r\n * @param pattern The match pattern string (should not contain union operator at top level)\r\n * @param context The original context (for namespace/variable info)\r\n * @param matchResolver The match resolver\r\n * @param xPath The XPath instance\r\n * @returns true if the node matches the pattern\r\n */\r\nfunction nodeMatchesSinglePattern(\r\n node: XNode,\r\n pattern: string,\r\n context: ExprContext,\r\n matchResolver: MatchResolver,\r\n xPath: XPath\r\n): boolean {\r\n // Special case for root pattern \"/\"\r\n if (pattern === '/') {\r\n return node.nodeName === '#document';\r\n }\r\n\r\n // Special case for attribute patterns like \"@class\", \"@*\", \"@ns:name\"\r\n if (pattern.startsWith('@')) {\r\n // Only attribute nodes (nodeType 2) can match attribute patterns\r\n if (node.nodeType !== 2) {\r\n return false;\r\n }\r\n const attrPattern = pattern.substring(1); // Remove '@'\r\n if (attrPattern === '*') {\r\n // @* matches any attribute\r\n return true;\r\n }\r\n // Match by attribute name (considering local name for namespaced attributes)\r\n const attrName = node.localName || node.nodeName;\r\n // Handle namespaced patterns like \"ns:name\" - just compare local names\r\n const patternLocalName = attrPattern.includes(':')\r\n ? attrPattern.substring(attrPattern.indexOf(':') + 1)\r\n : attrPattern;\r\n return attrName === patternLocalName || node.nodeName === attrPattern;\r\n }\r\n\r\n // For patterns starting with '*' (where axis override doesn't work),\r\n // check if the node passes the pattern test directly\r\n if (pattern === '*' && node.nodeType === DOM_ELEMENT_NODE) {\r\n return true;\r\n }\r\n\r\n // For simple element name patterns first (like \"section\" or \"div\")\r\n // Try matching by element name directly\r\n if (!pattern.includes('/') && !pattern.includes('[') && !pattern.startsWith('@')) {\r\n if (pattern === node.nodeName || pattern === node.localName) {\r\n return true;\r\n }\r\n }\r\n\r\n // For patterns with '/' (absolute or descendant paths) or '[' (predicates),\r\n // we need to evaluate from document root and check if node is in result\r\n if (pattern.includes('/') || pattern.includes('[')) {\r\n try {\r\n // Evaluate pattern from document root\r\n // If pattern doesn't start with '/', add '//' to match anywhere in document\r\n const evaluationPattern = pattern.startsWith('/') ? pattern : '//' + pattern;\r\n const rootContext = context.clone([context.root], 0);\r\n \r\n // Use xPathEval for pattern evaluation (handles // patterns correctly)\r\n const evalResult = xPath.xPathEval(evaluationPattern, rootContext);\r\n const nodes = evalResult.nodeSetValue();\r\n\r\n if (nodes.some(n => n.id === node.id)) {\r\n return true;\r\n }\r\n } catch (e) {\r\n // Pattern parsing failed, continue to next approach\r\n }\r\n }\r\n\r\n // For simple element name patterns - try with 'self-and-siblings' axis override as fallback\r\n if (!pattern.includes('/') && !pattern.includes('[') && !pattern.startsWith('@')) {\r\n try {\r\n const nodeContext = context.clone([node], 0);\r\n const expr = xPath.xPathParse(pattern, 'self-and-siblings');\r\n const nodes = matchResolver.expressionMatch(expr, nodeContext);\r\n\r\n // Check if the current node is in the matched nodes\r\n if (nodes.some(n => n.id === node.id)) {\r\n return true;\r\n }\r\n } catch (e) {\r\n // Pattern parsing failed\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Check if a node matches a given pattern.\r\n * This handles union patterns by splitting them and testing each alternative.\r\n *\r\n * @param node The node to test\r\n * @param pattern The match pattern string\r\n * @param context The original context (for namespace/variable info)\r\n * @param matchResolver The match resolver\r\n * @param xPath The XPath instance\r\n * @returns true if the node matches the pattern\r\n */\r\nfunction nodeMatchesPattern(\r\n node: XNode,\r\n pattern: string,\r\n context: ExprContext,\r\n matchResolver: MatchResolver,\r\n xPath: XPath\r\n): boolean {\r\n // Handle union patterns by splitting and testing each alternative\r\n const alternatives = splitUnionPattern(pattern);\r\n\r\n // If there are multiple alternatives, test each one\r\n // Return true if ANY alternative matches\r\n for (const alt of alternatives) {\r\n if (nodeMatchesSinglePattern(node, alt, context, matchResolver, xPath)) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Select the best matching template from a list of templates.\r\n *\r\n * Selection rules (XSLT 3.0 spec section 6.4):\r\n * 1. Import precedence (higher wins)\r\n * 2. Effective priority (higher wins)\r\n * 3. Document order (last template wins if all else is equal)\r\n *\r\n * @param templates Array of templates with priority metadata\r\n * @param context The expression context for matching\r\n * @param matchResolver The match resolver for testing patterns\r\n * @param xPath The XPath instance for parsing\r\n * @returns The selection result\r\n */\r\nexport function selectBestTemplate(\r\n templates: TemplatePriorityInterface[],\r\n context: ExprContext,\r\n matchResolver: MatchResolver,\r\n xPath: XPath,\r\n warningsCallback?: (...args: any[]) => void\r\n): TemplateSelectionResultInterface {\r\n const warn = warningsCallback ?? console.warn;\r\n // 1. Filter to templates that match the current node\r\n const matching: TemplatePriorityInterface[] = [];\r\n const currentNode = context.nodeList[context.position];\r\n\r\n for (const t of templates) {\r\n try {\r\n if (nodeMatchesPattern(currentNode, t.matchPattern, context, matchResolver, xPath)) {\r\n matching.push(t);\r\n }\r\n } catch (e) {\r\n // If pattern matching fails, skip this template\r\n warn(`Failed to match pattern \"${t.matchPattern}\":`, e);\r\n }\r\n }\r\n\r\n if (matching.length === 0) {\r\n return {\r\n selectedTemplate: null,\r\n hasConflict: false,\r\n conflictingTemplates: []\r\n };\r\n }\r\n\r\n // 2. Sort by: importPrecedence DESC, effectivePriority DESC, documentOrder DESC\r\n matching.sort((a, b) => {\r\n // Higher import precedence wins\r\n if (a.importPrecedence !== b.importPrecedence) {\r\n return b.importPrecedence - a.importPrecedence;\r\n }\r\n // Higher priority wins\r\n if (a.effectivePriority !== b.effectivePriority) {\r\n return b.effectivePriority - a.effectivePriority;\r\n }\r\n // Later document order wins (last template wins)\r\n return b.documentOrder - a.documentOrder;\r\n });\r\n\r\n // 3. Detect conflicts - templates with same import precedence and priority\r\n const winner = matching[0];\r\n const conflicts = matching.filter(t =>\r\n t.importPrecedence === winner.importPrecedence &&\r\n t.effectivePriority === winner.effectivePriority\r\n );\r\n\r\n return {\r\n selectedTemplate: winner.template,\r\n hasConflict: conflicts.length > 1,\r\n conflictingTemplates: conflicts.length > 1 ? conflicts : [],\r\n originalComponent: winner.originalComponent\r\n };\r\n}\r\n\r\n/**\r\n * Emit a warning when template conflicts are detected.\r\n *\r\n * @param result The template selection result\r\n * @param node The node being matched\r\n */\r\nexport function emitConflictWarning(\r\n result: TemplateSelectionResultInterface,\r\n node: XNode,\r\n warningsCallback?: (...args: any[]) => void\r\n): void {\r\n if (!result.hasConflict || result.conflictingTemplates.length < 2) {\r\n return;\r\n }\r\n\r\n const patterns = result.conflictingTemplates\r\n .map(t => `\"${t.matchPattern}\" (priority: ${t.effectivePriority})`)\r\n .join(', ');\r\n\r\n const warn = warningsCallback ?? console.warn;\r\n warn(\r\n `XSLT Warning: Ambiguous template match for node <${node.nodeName}>. ` +\r\n `Multiple templates match with equal priority: ${patterns}. ` +\r\n `Using the last one in document order.`\r\n );\r\n}\r\n","/**\r\n * XSLT 3.0 Accumulator Support\r\n * \r\n * Accumulators provide a declarative way to compute values during template processing.\r\n * They are declared at the stylesheet level and updated as the processor traverses nodes.\r\n */\r\n\r\nimport { XNode } from '../dom';\r\n\r\n/**\r\n * Represents a single accumulator rule within an xsl:accumulator declaration\r\n */\r\nexport interface AccumulatorRule {\r\n /**\r\n * Pattern expression (e.g., \"order\", \"item[@type='special']\")\r\n */\r\n match: string;\r\n \r\n /**\r\n * XPath expression to compute the new value\r\n * Can use $value (current accumulated value) and regular XPath functions\r\n */\r\n select: string;\r\n \r\n /**\r\n * Phase: 'start' (before processing), 'end' (after processing), or omitted (both)\r\n * Defaults to processing the node itself (implicitly 'end' equivalent)\r\n */\r\n phase?: 'start' | 'end';\r\n}\r\n\r\n/**\r\n * Represents an xsl:accumulator declaration from the stylesheet\r\n */\r\nexport interface AccumulatorDefinition {\r\n /**\r\n * Accumulator name (must be QName)\r\n */\r\n name: string;\r\n \r\n /**\r\n * XPath expression for initial value (e.g., \"0\", \"[]\", \"''\" )\r\n * Defaults to empty sequence\r\n */\r\n initialValue: string;\r\n \r\n /**\r\n * Type annotation (e.g., \"xs:decimal\", \"xs:integer\", \"xs:string*\")\r\n * Defaults to \"xs:anyAtomicType*\"\r\n */\r\n as: string;\r\n \r\n /**\r\n * Rules for updating the accumulator value\r\n */\r\n rules: AccumulatorRule[];\r\n \r\n /**\r\n * Whether this accumulator is streaming-safe\r\n * Defaults to false\r\n */\r\n streamable?: boolean;\r\n}\r\n\r\n/**\r\n * Current state of an accumulator during processing\r\n */\r\nexport interface AccumulatorState {\r\n /**\r\n * The current accumulated value\r\n */\r\n currentValue: any;\r\n \r\n /**\r\n * Stack of values for nested element processing\r\n */\r\n valueStack: any[];\r\n}\r\n\r\n/**\r\n * Registry of accumulators defined in the stylesheet\r\n */\r\nexport class AccumulatorRegistry {\r\n private accumulators: Map<string, AccumulatorDefinition> = new Map();\r\n private accumulatorStates: Map<string, AccumulatorState> = new Map();\r\n \r\n /**\r\n * Register an accumulator definition\r\n */\r\n registerAccumulator(definition: AccumulatorDefinition): void {\r\n this.accumulators.set(definition.name, definition);\r\n // Initialize state with initial value (will be evaluated later with proper context)\r\n this.accumulatorStates.set(definition.name, {\r\n currentValue: null,\r\n valueStack: []\r\n });\r\n }\r\n \r\n /**\r\n * Get an accumulator definition by name\r\n */\r\n getAccumulator(name: string): AccumulatorDefinition | undefined {\r\n return this.accumulators.get(name);\r\n }\r\n \r\n /**\r\n * Get all registered accumulators\r\n */\r\n getAllAccumulators(): AccumulatorDefinition[] {\r\n return Array.from(this.accumulators.values());\r\n }\r\n \r\n /**\r\n * Get current state of an accumulator\r\n */\r\n getAccumulatorState(name: string): AccumulatorState | undefined {\r\n return this.accumulatorStates.get(name);\r\n }\r\n \r\n /**\r\n * Update accumulator state\r\n */\r\n setAccumulatorState(name: string, state: AccumulatorState): void {\r\n this.accumulatorStates.set(name, state);\r\n }\r\n \r\n /**\r\n * Clear all accumulators\r\n */\r\n clear(): void {\r\n this.accumulators.clear();\r\n this.accumulatorStates.clear();\r\n }\r\n}\r\n","// Copyright 2023-2026 Design Liquido\r\n// Copyright 2018 Johannes Wilm\r\n// Copyright 2005 Google Inc.\r\n// All Rights Reserved\r\n//\r\n// Original author: Steffen Meschkat <mesch@google.com>\r\n\r\nimport {\r\n XDocument,\r\n XNode,\r\n XmlParser,\r\n domAppendChild,\r\n domCreateCDATASection,\r\n domCreateComment,\r\n domCreateDocumentFragment,\r\n domCreateElement,\r\n domCreateProcessingInstruction,\r\n domCreateTextNode,\r\n domGetAttributeValue,\r\n domSetAttribute,\r\n xmlGetAttribute,\r\n xmlTransformedText,\r\n xmlToJson,\r\n detectAdaptiveOutputFormat,\r\n xmlValue,\r\n xmlValueLegacyBehavior\r\n} from '../dom';\r\nimport { ExprContext, XPath, MatchResolver } from '../xpath';\r\n\r\nimport {\r\n DOM_ATTRIBUTE_NODE,\r\n DOM_CDATA_SECTION_NODE,\r\n DOM_COMMENT_NODE,\r\n DOM_DOCUMENT_FRAGMENT_NODE,\r\n DOM_DOCUMENT_NODE,\r\n DOM_ELEMENT_NODE,\r\n DOM_PROCESSING_INSTRUCTION_NODE,\r\n DOM_TEXT_NODE\r\n} from '../constants';\r\n\r\nimport { StringValue, NodeSetValue, NodeValue, NumberValue, BooleanValue } from '../xpath/values';\r\nimport { XsltDecimalFormatSettings, XsltOptions } from './types';\r\nimport { \r\n PackageRegistry, \r\n XsltPackageInterface, \r\n PackageComponentInterface, \r\n UsedPackageInterface,\r\n ComponentVisibility,\r\n ComponentType,\r\n ModeProperties,\r\n makeComponentKey,\r\n isComponentVisible,\r\n canOverrideComponent\r\n} from './package-system';\r\nimport {\r\n StreamingProcessor,\r\n StreamingChildProcessor\r\n} from './streaming';\r\nimport {\r\n collectAndExpandTemplates,\r\n selectBestTemplate,\r\n emitConflictWarning\r\n} from './functions';\r\n\r\nimport {\r\n AccumulatorDefinition,\r\n AccumulatorRule,\r\n AccumulatorState,\r\n AccumulatorRegistry\r\n} from './xslt-accumulator';\r\nimport { TemplatePriorityInterface } from './template-mechanics';\r\n\r\n/**\r\n * Metadata about a stylesheet in the import hierarchy.\r\n * Used to track template precedence for apply-imports.\r\n */\r\ninterface StylesheetMetadata {\r\n /** Import depth: 0 = main stylesheet, 1+ = imported stylesheets */\r\n importDepth: number;\r\n /** Source URI/href of the stylesheet */\r\n href: string;\r\n /** Order in which stylesheet was encountered (for stable sorting) */\r\n order: number;\r\n}\r\n\r\n/**\r\n * Context information about a currently executing template.\r\n * Used by apply-imports to find the next lower-precedence template.\r\n */\r\ninterface CurrentTemplateContext {\r\n /** The template XNode being executed */\r\n template: XNode;\r\n /** Import depth of the stylesheet containing this template */\r\n stylesheetDepth: number;\r\n /** Mode of the template (null for default mode) */\r\n mode: string | null;\r\n /** Match pattern of the template */\r\n match: string | null;\r\n}\r\n\r\ninterface WhitespacePattern {\r\n namespaceUri: string | null;\r\n localName: string;\r\n isWildcard: boolean;\r\n}\r\n\r\n/**\r\n * The main class for XSL-T processing.\r\n *\r\n * References:\r\n *\r\n * [XSLT 1.0] XSL Transformations (XSLT) Version 1.0\r\n * <https://www.w3.org/TR/1999/REC-xslt-19991116>.\r\n *\r\n * [XSLT 2.0] XSL Transformations (XSLT) Version 2.0\r\n * <https://www.w3.org/TR/xslt20/>.\r\n *\r\n * [XSLT 3.0] XSL Transformations (XSLT) Version 3.0\r\n * <https://www.w3.org/TR/xslt-30/>.\r\n *\r\n * [ECMA] ECMAScript Language Specification\r\n * <http://www.ecma-international.org/publications/standards/Ecma-262.htm>.\r\n *\r\n * The XSL processor API has one entry point: the async function\r\n * `xsltProcess()`. It receives as arguments the input XML document\r\n * and the XSL-T stylesheet document (both as `XDocument` instances),\r\n * and returns the transformed output as a string (XML, HTML, JSON,\r\n * or plain text depending on the output method).\r\n *\r\n * NOTE: Strictly speaking, XSL-T processing according to the specification\r\n * is defined as operation on text documents, not as operation on DOM\r\n * trees. This implementation operates on an internal DOM representation,\r\n * complemented by an XML parser and serializer to be complete. Those two\r\n * are found in the `dom` folder.\r\n */\r\nexport class Xslt {\r\n xPath: XPath;\r\n xmlParser: XmlParser;\r\n matchResolver: MatchResolver;\r\n options: XsltOptions;\r\n decimalFormatSettings: XsltDecimalFormatSettings;\r\n warningsCallback: (...args: any[]) => void;\r\n\r\n /**\r\n * Custom fetch function for loading external resources (e.g. xsl:import, xsl:include).\r\n * Takes a URI and returns the fetched content as a string.\r\n * Defaults to using the global `fetch` API.\r\n */\r\n fetchFunction: (uri: string) => Promise<string>;\r\n\r\n outputDocument: XDocument;\r\n outputMethod: 'xml' | 'html' | 'text' | 'name' | 'xhtml' | 'json' | 'adaptive';\r\n outputOmitXmlDeclaration: string;\r\n outputVersion: string;\r\n itemSeparator: string;\r\n version: string;\r\n firstTemplateRan: boolean;\r\n\r\n /**\r\n * Forwards-compatible processing mode (XSLT 1.0 Section 2.5).\r\n * When true, the processor is running a stylesheet with version > 1.0.\r\n * In this mode:\r\n * - Unknown top-level elements are silently ignored\r\n * - Unknown XSLT instructions use xsl:fallback if available, otherwise are ignored\r\n * - Unknown attributes on XSLT elements are ignored\r\n */\r\n forwardsCompatible: boolean;\r\n\r\n /**\r\n * List of element name patterns from xsl:strip-space declarations.\r\n * Whitespace-only text nodes inside matching elements will be stripped.\r\n */\r\n stripSpacePatterns: WhitespacePattern[];\r\n\r\n /**\r\n * List of element name patterns from xsl:preserve-space declarations.\r\n * Whitespace-only text nodes inside matching elements will be preserved.\r\n * preserve-space takes precedence over strip-space for conflicting patterns.\r\n */\r\n preserveSpacePatterns: WhitespacePattern[];\r\n\r\n /**\r\n * Namespace aliases from xsl:namespace-alias declarations.\r\n * Maps stylesheet namespace prefixes to result namespace prefixes.\r\n */\r\n namespaceAliases: Map<string, string>;\r\n\r\n /**\r\n * Set of supported extension element namespaces.\r\n * Processors can register custom extension namespaces here.\r\n * Currently only XSLT namespace is auto-registered.\r\n */\r\n supportedExtensions: Set<string>;\r\n\r\n /**\r\n * Map of attribute sets defined in the stylesheet.\r\n * Keys are attribute set names, values are arrays of xsl:attribute nodes.\r\n */\r\n attributeSets: Map<string, XNode[]>;\r\n\r\n /**\r\n * Map of user-defined functions from xsl:function declarations.\r\n * Keys are QNames (namespace:localname), values are the function definition nodes.\r\n */\r\n userDefinedFunctions: Map<string, XNode>;\r\n\r\n /**\r\n * Result documents created by xsl:result-document.\r\n * Keys are the href URIs, values are the serialized output strings.\r\n */\r\n resultDocuments: Map<string, string>;\r\n\r\n /**\r\n * Stack of stylesheet metadata for tracking import hierarchy.\r\n * Used by apply-imports to find templates from imported stylesheets.\r\n */\r\n private styleSheetStack: StylesheetMetadata[] = [];\r\n\r\n /**\r\n * Map of imported stylesheet HREFs to their parsed XNodes.\r\n * Prevents duplicate imports and allows precedence tracking.\r\n */\r\n private importedStylesheets: Map<string, XNode> = new Map();\r\n\r\n /**\r\n * Map templates to the stylesheet they came from.\r\n * Enables apply-imports to find templates by import precedence.\r\n */\r\n private templateSourceMap: Map<XNode, StylesheetMetadata> = new Map();\r\n\r\n /**\r\n * Stack of currently executing templates with their metadata.\r\n * Used by apply-imports to determine which template called it.\r\n */\r\n private currentTemplateStack: CurrentTemplateContext[] = [];\r\n\r\n /**\r\n * Package registry for XSLT 3.0 package system.\r\n * Manages loaded packages and their components.\r\n */\r\n private packageRegistry: PackageRegistry = new PackageRegistry();\r\n\r\n /**\r\n * Callback for loading external packages.\r\n * Called when a package is not found in the registry.\r\n */\r\n private packageLoader?: (uri: string, version?: string) => Promise<XNode | null>;\r\n\r\n /**\r\n * Current package being processed (for XSLT 3.0).\r\n * null if processing a non-package stylesheet.\r\n */\r\n private currentPackage: XsltPackageInterface | null = null;\r\n\r\n /**\r\n * Current override context (for XSLT 3.0 xsl:original).\r\n * Tracks the original component when executing an override.\r\n */\r\n private currentOverrideContext: PackageComponentInterface | null = null;\r\n\r\n /**\r\n * Accumulator registry for XSLT 3.0 accumulators.\r\n * Stores accumulator definitions and current state during processing.\r\n */\r\n private accumulatorRegistry: AccumulatorRegistry = new AccumulatorRegistry();\r\n\r\n /**\r\n * Streaming processor for XSLT 3.0 streaming processing.\r\n * Encapsulates streaming context, copy management, and merge coordination.\r\n */\r\n private streamingProcessor: StreamingProcessor;\r\n\r\n constructor(\r\n options: Partial<XsltOptions> = {\r\n cData: true,\r\n escape: true,\r\n selfClosingTags: true,\r\n parameters: []\r\n }\r\n ) {\r\n this.xPath = new XPath();\r\n this.xmlParser = new XmlParser();\r\n this.matchResolver = new MatchResolver();\r\n this.options = {\r\n cData: options.cData === true,\r\n escape: options.escape === true,\r\n selfClosingTags: options.selfClosingTags === true,\r\n outputMethod: options.outputMethod,\r\n parameters: options.parameters || []\r\n };\r\n this.outputMethod = options.outputMethod || 'xml';\r\n this.outputOmitXmlDeclaration = 'no';\r\n this.outputVersion = '';\r\n this.itemSeparator = '';\r\n this.stripSpacePatterns = [];\r\n this.preserveSpacePatterns = [];\r\n this.namespaceAliases = new Map();\r\n this.supportedExtensions = new Set(['http://www.w3.org/1999/XSL/Transform']);\r\n this.attributeSets = new Map();\r\n this.userDefinedFunctions = new Map();\r\n this.resultDocuments = new Map();\r\n this.decimalFormatSettings = {\r\n decimalSeparator: '.',\r\n groupingSeparator: ',',\r\n infinity: 'Infinity',\r\n minusSign: '-',\r\n naN: 'NaN',\r\n percent: '%',\r\n perMille: '‰',\r\n zeroDigit: '0',\r\n digit: '#',\r\n patternSeparator: ';'\r\n };\r\n this.firstTemplateRan = false;\r\n this.forwardsCompatible = false;\r\n this.warningsCallback = console.warn.bind(console);\r\n this.fetchFunction = options.fetchFunction || (async (uri: string) => {\r\n const globalFetch =\r\n typeof globalThis !== 'undefined' && typeof (globalThis as any).fetch === 'function'\r\n ? (globalThis as any).fetch\r\n : null;\r\n\r\n if (!globalFetch) {\r\n throw new Error(\r\n 'No global fetch implementation available. ' +\r\n 'Please provide options.fetchFunction or use a runtime that exposes globalThis.fetch.'\r\n );\r\n }\r\n\r\n const response = await globalFetch(uri);\r\n return response.text();\r\n });\r\n this.streamingProcessor = new StreamingProcessor({\r\n xPath: this.xPath,\r\n version: ''\r\n });\r\n }\r\n\r\n /**\r\n * The exported entry point of the XSL-T processor.\r\n * @param xmlDoc The input document root, as DOM node.\r\n * @param stylesheet The stylesheet document root, as DOM node.\r\n * @returns the processed document, as XML text in a string, JSON string if outputMethod is 'json', or text if outputMethod is 'text' or 'adaptive' (with text content).\r\n */\r\n async xsltProcess(xmlDoc: XDocument, stylesheet: XDocument) {\r\n const outputDocument = await this.xsltProcessToDocument(xmlDoc, stylesheet);\r\n\r\n // Handle JSON output format\r\n if (this.outputMethod === 'json') {\r\n return xmlToJson(outputDocument);\r\n }\r\n\r\n // Handle adaptive output format\r\n let outputMethod = this.outputMethod;\r\n if (this.outputMethod === 'adaptive') {\r\n outputMethod = detectAdaptiveOutputFormat(outputDocument);\r\n }\r\n\r\n // Support HTML5 output (method=\"html\" version=\"5.0\")\r\n // Keep method as 'html' for serialization, but track version for HTML5-specific handling\r\n let serializationMethod = outputMethod;\r\n if (outputMethod === 'html' && this.outputVersion === '5.0') {\r\n // HTML5 uses method=\"html\" with version=\"5.0\"\r\n serializationMethod = 'html';\r\n }\r\n\r\n const transformedOutputXml: string = xmlTransformedText(outputDocument, {\r\n cData: this.options.cData,\r\n escape: this.options.escape,\r\n selfClosingTags: this.options.selfClosingTags,\r\n outputMethod: serializationMethod as 'xml' | 'html' | 'text' | 'xhtml',\r\n outputVersion: this.outputVersion,\r\n itemSeparator: this.itemSeparator\r\n });\r\n\r\n return transformedOutputXml;\r\n }\r\n\r\n /**\r\n * Processes the XSLT transformation and returns the output as an XDocument\r\n * instead of a serialized string. This is useful for:\r\n * - Working with the result tree programmatically\r\n * - Converting to a different DOM representation (e.g., React elements)\r\n * - Using browser-native serialization (XMLSerializer) if desired\r\n *\r\n * @param xmlDoc The input document root, as DOM node.\r\n * @param stylesheet The stylesheet document root, as DOM node.\r\n * @returns The processed document as an XDocument tree.\r\n */\r\n async xsltProcessToDocument(xmlDoc: XDocument, stylesheet: XDocument): Promise<XDocument> {\r\n const outputDocument = new XDocument();\r\n this.outputDocument = outputDocument;\r\n const expressionContext = new ExprContext([xmlDoc]);\r\n expressionContext.warningsCallback = this.warningsCallback;\r\n\r\n if (this.options.parameters.length > 0) {\r\n for (const parameter of this.options.parameters) {\r\n expressionContext.setVariable(parameter.name, this.toNodeValue(parameter.value));\r\n }\r\n }\r\n\r\n await this.xsltProcessContext(expressionContext, stylesheet, this.outputDocument);\r\n\r\n return outputDocument;\r\n }\r\n\r\n /**\r\n * The main entry point of the XSL-T processor, as explained on the top of the file.\r\n * @param context The input document root, as XPath `ExprContext`.\r\n * @param template The stylesheet document root, as DOM node.\r\n * @param output If set, the output where the transformation should occur.\r\n */\r\n protected async xsltProcessContext(context: ExprContext, template: XNode, output?: XNode) {\r\n if (!context.warningsCallback) {\r\n context.warningsCallback = this.warningsCallback;\r\n }\r\n if (!this.isXsltElement(template)) {\r\n // Check if this is an unsupported extension element\r\n if (\r\n template.nodeType === DOM_ELEMENT_NODE &&\r\n !this.isExtensionElementSupported(template)\r\n ) {\r\n // This is an extension element - handle with fallback support\r\n await this.xsltExtensionElement(context, template, output);\r\n } else {\r\n // Regular literal result element\r\n await this.xsltPassThrough(context, template, output);\r\n }\r\n } else {\r\n let node: XNode,\r\n select: any,\r\n value: any,\r\n nodes: XNode[];\r\n switch (template.localName) {\r\n case 'apply-imports':\r\n await this.xsltApplyImports(context, template, output);\r\n break;\r\n case 'apply-templates':\r\n await this.xsltApplyTemplates(context, template, output);\r\n break;\r\n case 'analyze-string':\r\n await this.xsltAnalyzeString(context, template, output);\r\n break;\r\n case 'attribute':\r\n await this.xsltAttribute(context, template, output);\r\n break;\r\n case 'attribute-set':\r\n // attribute-set declarations are processed during stylesheet initialization\r\n // in collectAttributeSets(). This case is skipped.\r\n break;\r\n case 'call-template':\r\n await this.xsltCallTemplate(context, template, output);\r\n break;\r\n case 'choose':\r\n await this.xsltChoose(context, template, output);\r\n break;\r\n case 'comment':\r\n await this.xsltComment(context, template, output);\r\n break;\r\n case 'copy':\r\n node = this.xsltCopy(output || this.outputDocument, context.nodeList[context.position]);\r\n if (node) {\r\n await this.xsltChildNodes(context, template, node);\r\n }\r\n break;\r\n case 'copy-of':\r\n select = xmlGetAttribute(template, 'select');\r\n value = this.xPath.xPathEval(select, context);\r\n const destinationNode = output || this.outputDocument;\r\n if (value.type === 'node-set') {\r\n nodes = value.nodeSetValue();\r\n for (let i = 0; i < nodes.length; ++i) {\r\n this.xsltCopyOf(destinationNode, nodes[i]);\r\n }\r\n } else {\r\n let node = domCreateTextNode(this.outputDocument, value.stringValue());\r\n node.siblingPosition = destinationNode.childNodes.length;\r\n domAppendChild(destinationNode, node);\r\n }\r\n break;\r\n case 'accumulator':\r\n this.xsltAccumulator(context, template);\r\n break;\r\n case 'accumulator-rule':\r\n // xsl:accumulator-rule is handled inside xsltAccumulator.\r\n throw new Error(`<xsl:accumulator-rule> must be a child of <xsl:accumulator>.`);\r\n case 'decimal-format':\r\n this.xsltDecimalFormat(context, template);\r\n break;\r\n case 'evaluate':\r\n await this.xsltEvaluate(context, template, output);\r\n break;\r\n case 'element':\r\n await this.xsltElement(context, template, output);\r\n break;\r\n case 'fallback':\r\n // Allow fallback only when its parent is an extension element\r\n const parent = template.parentNode;\r\n const isExtensionParent =\r\n parent &&\r\n parent.nodeType === DOM_ELEMENT_NODE &&\r\n !this.isExtensionElementSupported(parent);\r\n\r\n if (!isExtensionParent) {\r\n throw new Error(\r\n '<xsl:fallback> must be a direct child of an extension element'\r\n );\r\n }\r\n\r\n // Execute the fallback's children in the current context/output\r\n await this.xsltChildNodes(context, template, output);\r\n break;\r\n case 'for-each':\r\n await this.xsltForEach(context, template, output);\r\n break;\r\n case 'for-each-group':\r\n await this.xsltForEachGroup(context, template, output);\r\n break;\r\n case 'function':\r\n // xsl:function is collected during stylesheet initialization\r\n // and not executed during template processing\r\n this.xsltFunction(context, template);\r\n break;\r\n case 'iterate':\r\n await this.xsltIterate(context, template, output);\r\n break;\r\n case 'try':\r\n await this.xsltTry(context, template, output);\r\n break;\r\n case 'if':\r\n await this.xsltIf(context, template, output);\r\n break;\r\n case 'import':\r\n await this.xsltImport(context, template, output);\r\n break;\r\n case 'include':\r\n await this.xsltInclude(context, template, output);\r\n break;\r\n case 'key':\r\n this.xsltKey(context, template);\r\n break;\r\n case 'matching-substring':\r\n // xsl:matching-substring is handled inside xsltAnalyzeString.\r\n throw new Error(`<xsl:matching-substring> must be a child of <xsl:analyze-string>.`);\r\n case 'message':\r\n await this.xsltMessage(context, template);\r\n break;\r\n case 'namespace':\r\n await this.xsltNamespace(context, template, output);\r\n break;\r\n case 'namespace-alias':\r\n this.xsltNamespaceAlias(template);\r\n break;\r\n case 'non-matching-substring':\r\n // xsl:non-matching-substring is handled inside xsltAnalyzeString.\r\n throw new Error(`<xsl:non-matching-substring> must be a child of <xsl:analyze-string>.`);\r\n case 'on-empty':\r\n // xsl:on-empty is handled inside sequence-generating instructions.\r\n throw new Error(`<xsl:on-empty> must be a child of a sequence-generating instruction like <xsl:for-each>, <xsl:for-each-group>, or <xsl:apply-templates>.`);\r\n case 'on-non-empty':\r\n // xsl:on-non-empty is handled inside sequence-generating instructions.\r\n throw new Error(`<xsl:on-non-empty> must be a child of a sequence-generating instruction like <xsl:for-each>, <xsl:for-each-group>, or <xsl:apply-templates>.`);\r\n case 'number':\r\n this.xsltNumber(context, template, output);\r\n break;\r\n case 'otherwise':\r\n // xsl:otherwise is handled inside xsltChoose. If we reach here,\r\n // it means the element was used outside of xsl:choose.\r\n throw new Error(`<xsl:otherwise> must be a child of <xsl:choose>.`);\r\n case 'output':\r\n this.outputMethod = xmlGetAttribute(template, 'method') as 'xml' | 'html' | 'text' | 'name';\r\n this.outputOmitXmlDeclaration = xmlGetAttribute(template, 'omit-xml-declaration');\r\n this.outputVersion = xmlGetAttribute(template, 'version') || '';\r\n this.itemSeparator = xmlGetAttribute(template, 'item-separator') || '';\r\n break;\r\n case 'package':\r\n await this.xsltPackage(context, template, output);\r\n break;\r\n case 'use-package':\r\n await this.xsltUsePackage(context, template, output);\r\n break;\r\n case 'expose':\r\n this.xsltExpose(context, template);\r\n break;\r\n case 'accept':\r\n this.xsltAccept(context, template);\r\n break;\r\n case 'override':\r\n await this.xsltOverride(context, template, output);\r\n break;\r\n case 'original':\r\n await this.xsltOriginal(context, template, output);\r\n break;\r\n case 'param':\r\n await this.xsltVariable(context, template, false);\r\n break;\r\n case 'preserve-space':\r\n this.xsltPreserveSpace(template);\r\n break;\r\n case 'perform-sort':\r\n await this.xsltPerformSort(context, template, output);\r\n break;\r\n case 'processing-instruction':\r\n await this.xsltProcessingInstruction(context, template, output);\r\n break;\r\n case 'result-document':\r\n await this.xsltResultDocument(context, template);\r\n break;\r\n case 'sequence':\r\n await this.xsltSequence(context, template, output);\r\n break;\r\n case 'sort':\r\n this.xsltSort(context, template);\r\n break;\r\n case 'strip-space':\r\n this.xsltStripSpace(template);\r\n break;\r\n case 'stylesheet':\r\n case 'transform':\r\n await this.xsltTransformOrStylesheet(context, template, output);\r\n break;\r\n case 'stream':\r\n await this.xsltStream(context, template, output);\r\n break;\r\n case 'fork':\r\n await this.xsltFork(context, template, output);\r\n break;\r\n case 'merge':\r\n await this.xsltMerge(context, template, output);\r\n break;\r\n case 'mode':\r\n // xsl:mode declaration (XSLT 3.0)\r\n if (this.currentPackage) {\r\n this.xsltMode(context, template);\r\n }\r\n break;\r\n case 'template':\r\n await this.xsltTemplate(context, template, output);\r\n break;\r\n case 'text':\r\n this.xsltText(context, template, output);\r\n break;\r\n case 'value-of':\r\n this.xsltValueOf(context, template, output);\r\n break;\r\n case 'variable':\r\n await this.xsltVariable(context, template, true);\r\n break;\r\n case 'when':\r\n // xsl:when is handled inside xsltChoose. If we reach here,\r\n // it means the element was used outside of xsl:choose.\r\n throw new Error(`<xsl:when> must be a child of <xsl:choose>.`);\r\n case 'with-param':\r\n // xsl:with-param is handled inside xsltWithParam called from\r\n // xsltCallTemplate and xsltApplyTemplates. If we reach here,\r\n // it means the element was used outside of those contexts.\r\n throw new Error(`<xsl:with-param> must be a child of <xsl:call-template> or <xsl:apply-templates>.`);\r\n default:\r\n // Unknown XSLT element - handle according to forwards-compatible mode (Section 2.5)\r\n await this.xsltUnknownInstruction(context, template, output);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Handle unknown XSLT instructions per XSLT 1.0 Section 2.5 (Forwards-Compatible Processing).\r\n *\r\n * In forwards-compatible mode (version > 1.0):\r\n * - If the instruction has an xsl:fallback child, execute the fallback\r\n * - Otherwise, the instruction is silently ignored\r\n *\r\n * In strict mode (version = 1.0):\r\n * - Unknown instructions are an error\r\n *\r\n * @param context The Expression Context\r\n * @param template The unknown XSLT instruction element\r\n * @param output The output node\r\n */\r\n protected async xsltUnknownInstruction(context: ExprContext, template: XNode, output?: XNode): Promise<void> {\r\n const elementName = `xsl:${template.localName}`;\r\n\r\n if (this.forwardsCompatible) {\r\n // Forwards-compatible mode: look for xsl:fallback child\r\n const fallback = this.getFallbackElement(template);\r\n\r\n if (fallback) {\r\n // Execute the fallback content\r\n await this.xsltChildNodes(context, fallback, output);\r\n }\r\n // If no fallback, silently ignore the unknown instruction\r\n // (Per XSLT 1.0 Section 2.5: \"if the instruction element...does not have\r\n // an xsl:fallback child element, then the XSLT element is instantiated\r\n // by instantiating each of its children that is in the XSLT namespace\")\r\n return;\r\n }\r\n\r\n // Strict mode: unknown instruction is an error\r\n throw new Error(\r\n `Unknown XSLT instruction: <${elementName}>. ` +\r\n `This element is not supported in XSLT 1.0. ` +\r\n `If this is a future XSLT version feature, use version=\"2.0\" or higher ` +\r\n `to enable forwards-compatible processing mode.`\r\n );\r\n }\r\n\r\n /**\r\n * Implements `xsl:apply-templates`.\r\n * @param context The Expression Context.\r\n * @param template The template.\r\n * @param output The output. Only used if there's no corresponding output node already defined.\r\n * @protected\r\n */\r\n protected async xsltApplyTemplates(context: ExprContext, template: XNode, output?: XNode) {\r\n const select = xmlGetAttribute(template, 'select');\r\n let nodes: XNode[] = [];\r\n if (select) {\r\n nodes = this.xPath.xPathEval(select, context).nodeSetValue();\r\n } else {\r\n nodes = context.nodeList[context.position].childNodes;\r\n }\r\n\r\n const onEmpty = this.findConditionalChild(template, 'on-empty');\r\n const onNonEmpty = this.findConditionalChild(template, 'on-non-empty');\r\n\r\n if (nodes.length === 0) {\r\n if (onEmpty) {\r\n await this.xsltChildNodes(context.clone(), onEmpty, output);\r\n }\r\n return;\r\n }\r\n\r\n if (onNonEmpty) {\r\n await this.xsltChildNodes(context.clone(), onNonEmpty, output);\r\n return;\r\n }\r\n\r\n // TODO: Check why apply-templates was sorting and filing parameters\r\n // automatically.\r\n /* this.xsltWithParam(sortContext, template);\r\n this.xsltSort(sortContext, template); */\r\n\r\n const mode: string | null = xmlGetAttribute(template, 'mode');\r\n const effectiveMode = mode || null;\r\n const top = template.ownerDocument.documentElement;\r\n\r\n // Collect all templates with their priority metadata\r\n let expandedTemplates: TemplatePriorityInterface[] = collectAndExpandTemplates(top, effectiveMode, this.xPath, this.templateSourceMap);\r\n\r\n // Also collect templates from accepted components in used packages\r\n expandedTemplates = expandedTemplates.concat(this.collectAcceptedTemplates(effectiveMode));\r\n\r\n // Clone context and set any xsl:with-param parameters defined on\r\n // the <xsl:apply-templates> element so they are visible to the\r\n // templates executed for each selected node.\r\n const paramContext = context.clone();\r\n await this.xsltWithParam(paramContext, template);\r\n const modifiedContext = paramContext.clone(nodes);\r\n // Process nodes in document order, selecting the BEST matching template for each node.\r\n // This is the XSLT 3.0 compliant behavior - only ONE template executes per node.\r\n for (let j = 0; j < modifiedContext.contextSize(); ++j) {\r\n const currentNode = modifiedContext.nodeList[j];\r\n // Handle text nodes - check for templates matching text() first (per XSLT 1.0 spec)\r\n if (currentNode.nodeType === DOM_TEXT_NODE) {\r\n // Check if this whitespace-only text node should be stripped\r\n if (!this.xsltPassText(currentNode)) {\r\n // Skip whitespace-only text nodes in apply-templates\r\n continue;\r\n }\r\n\r\n // Check if there's a template matching text() nodes\r\n const textNodeContext = paramContext.clone([currentNode], 0);\r\n textNodeContext.inApplyTemplates = true;\r\n\r\n const textSelection = selectBestTemplate(\r\n expandedTemplates,\r\n textNodeContext,\r\n this.matchResolver,\r\n this.xPath,\r\n this.warningsCallback\r\n );\r\n\r\n if (textSelection.selectedTemplate) {\r\n // Execute the matching template for this text node\r\n const metadata = this.templateSourceMap.get(textSelection.selectedTemplate);\r\n const matchPattern = xmlGetAttribute(textSelection.selectedTemplate, 'match');\r\n const modeAttr = xmlGetAttribute(textSelection.selectedTemplate, 'mode');\r\n\r\n this.currentTemplateStack.push({\r\n template: textSelection.selectedTemplate,\r\n stylesheetDepth: metadata?.importDepth ?? 0,\r\n mode: modeAttr || effectiveMode,\r\n match: matchPattern\r\n });\r\n\r\n const previousOverrideContext = this.currentOverrideContext;\r\n const overrideContext = textSelection.originalComponent || (textSelection.selectedTemplate as any).__originalComponent;\r\n if (overrideContext) {\r\n this.currentOverrideContext = overrideContext;\r\n }\r\n\r\n try {\r\n await this.xsltChildNodes(textNodeContext, textSelection.selectedTemplate, output);\r\n } finally {\r\n this.currentTemplateStack.pop();\r\n this.currentOverrideContext = previousOverrideContext;\r\n }\r\n } else {\r\n // No matching template - use built-in behavior (copy text)\r\n const oldTextNodeContext = context.clone([currentNode], 0);\r\n this.commonLogicTextNode(oldTextNodeContext, currentNode, output);\r\n }\r\n } else {\r\n // For non-text nodes, select the BEST matching template based on priority\r\n const clonedContext = modifiedContext.clone(\r\n [currentNode],\r\n 0\r\n );\r\n clonedContext.inApplyTemplates = true;\r\n\r\n // Select the best template according to XSLT conflict resolution rules\r\n const selection = selectBestTemplate(\r\n expandedTemplates,\r\n clonedContext,\r\n this.matchResolver,\r\n this.xPath,\r\n this.warningsCallback\r\n );\r\n\r\n // Emit warning if there's a conflict\r\n if (selection.hasConflict) {\r\n emitConflictWarning(selection, currentNode, this.warningsCallback);\r\n }\r\n\r\n // Execute ONLY the selected template (not all matching templates)\r\n // We directly execute the template children here, bypassing xsltTemplate's\r\n // own matching logic since we've already determined this is the best match.\r\n if (selection.selectedTemplate) {\r\n // Track the executing template for apply-imports\r\n const metadata = this.templateSourceMap.get(selection.selectedTemplate);\r\n const matchPattern = xmlGetAttribute(selection.selectedTemplate, 'match');\r\n const modeAttr = xmlGetAttribute(selection.selectedTemplate, 'mode');\r\n \r\n this.currentTemplateStack.push({\r\n template: selection.selectedTemplate,\r\n stylesheetDepth: metadata?.importDepth ?? 0,\r\n mode: modeAttr || effectiveMode,\r\n match: matchPattern\r\n });\r\n \r\n // Set override context if this is an overridden template\r\n const previousOverrideContext = this.currentOverrideContext;\r\n const overrideContext = selection.originalComponent || (selection.selectedTemplate as any).__originalComponent;\r\n if (overrideContext) {\r\n this.currentOverrideContext = overrideContext;\r\n }\r\n \r\n try {\r\n await this.xsltChildNodes(clonedContext, selection.selectedTemplate, output);\r\n } finally {\r\n this.currentTemplateStack.pop();\r\n this.currentOverrideContext = previousOverrideContext;\r\n }\r\n } else {\r\n // No matching template found - apply built-in template for elements\r\n // The built-in template for elements recursively applies templates to children\r\n if (currentNode.nodeType === DOM_ELEMENT_NODE && currentNode.childNodes && currentNode.childNodes.length > 0) {\r\n // Filter out attribute nodes and recursively apply templates\r\n const childNodes = currentNode.childNodes.filter(\r\n (n: XNode) => n.nodeType !== DOM_ATTRIBUTE_NODE\r\n );\r\n // Process children using the same logic as the main loop\r\n for (let k = 0; k < childNodes.length; ++k) {\r\n const childNode = childNodes[k];\r\n if (childNode.nodeType === DOM_TEXT_NODE) {\r\n // Check for text-matching templates first\r\n const textContext = paramContext.clone([childNode], 0);\r\n textContext.inApplyTemplates = true;\r\n const textSelection = selectBestTemplate(\r\n expandedTemplates,\r\n textContext,\r\n this.matchResolver,\r\n this.xPath,\r\n this.warningsCallback\r\n );\r\n if (textSelection.selectedTemplate) {\r\n await this.xsltChildNodes(textContext, textSelection.selectedTemplate, output);\r\n } else {\r\n // Built-in text template: copy text\r\n this.commonLogicTextNode(textContext, childNode, output);\r\n }\r\n } else {\r\n // For element nodes, recursively select best template\r\n const childContext = paramContext.clone([childNode], 0);\r\n childContext.inApplyTemplates = true;\r\n const childSelection = selectBestTemplate(\r\n expandedTemplates,\r\n childContext,\r\n this.matchResolver,\r\n this.xPath,\r\n this.warningsCallback\r\n );\r\n if (childSelection.selectedTemplate) {\r\n const childMetadata = this.templateSourceMap.get(childSelection.selectedTemplate);\r\n const childMatchPattern = xmlGetAttribute(childSelection.selectedTemplate, 'match');\r\n const childModeAttr = xmlGetAttribute(childSelection.selectedTemplate, 'mode');\r\n \r\n this.currentTemplateStack.push({\r\n template: childSelection.selectedTemplate,\r\n stylesheetDepth: childMetadata?.importDepth ?? 0,\r\n mode: childModeAttr || effectiveMode,\r\n match: childMatchPattern\r\n });\r\n \r\n try {\r\n await this.xsltChildNodes(childContext, childSelection.selectedTemplate, output);\r\n } finally {\r\n this.currentTemplateStack.pop();\r\n }\r\n } else if (childNode.nodeType === DOM_ELEMENT_NODE) {\r\n // Recursively apply built-in template to this element's children\r\n // Use a helper to avoid deep code duplication\r\n await this.applyBuiltInTemplate(childNode, expandedTemplates, effectiveMode, paramContext, output);\r\n }\r\n }\r\n }\r\n } else if (currentNode.nodeType === DOM_TEXT_NODE) {\r\n // Built-in template for text nodes: copy text content\r\n this.commonLogicTextNode(clonedContext, currentNode, output);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Helper method to apply the built-in template for elements.\r\n * The built-in template recursively applies templates to children.\r\n */\r\n private async applyBuiltInTemplate(\r\n node: XNode,\r\n expandedTemplates: TemplatePriorityInterface[],\r\n mode: string | null,\r\n paramContext: ExprContext,\r\n output?: XNode\r\n ): Promise<void> {\r\n if (!node.childNodes || node.childNodes.length === 0) {\r\n return;\r\n }\r\n \r\n const childNodes = node.childNodes.filter(\r\n (n: XNode) => n.nodeType !== DOM_ATTRIBUTE_NODE\r\n );\r\n \r\n for (const childNode of childNodes) {\r\n if (childNode.nodeType === DOM_TEXT_NODE) {\r\n // Check for text-matching templates first\r\n const textContext = paramContext.clone([childNode], 0);\r\n textContext.inApplyTemplates = true;\r\n const textSelection = selectBestTemplate(\r\n expandedTemplates,\r\n textContext,\r\n this.matchResolver,\r\n this.xPath,\r\n this.warningsCallback\r\n );\r\n if (textSelection.selectedTemplate) {\r\n const previousOverrideContext = this.currentOverrideContext;\r\n const overrideContext = textSelection.originalComponent || (textSelection.selectedTemplate as any).__originalComponent;\r\n if (overrideContext) {\r\n this.currentOverrideContext = overrideContext;\r\n }\r\n try {\r\n await this.xsltChildNodes(textContext, textSelection.selectedTemplate, output);\r\n } finally {\r\n this.currentOverrideContext = previousOverrideContext;\r\n }\r\n } else {\r\n // Built-in text template: copy text\r\n this.commonLogicTextNode(textContext, childNode, output);\r\n }\r\n } else {\r\n // For element nodes, recursively select best template\r\n const childContext = paramContext.clone([childNode], 0);\r\n childContext.inApplyTemplates = true;\r\n const childSelection = selectBestTemplate(\r\n expandedTemplates,\r\n childContext,\r\n this.matchResolver,\r\n this.xPath,\r\n this.warningsCallback\r\n );\r\n if (childSelection.selectedTemplate) {\r\n const childMetadata = this.templateSourceMap.get(childSelection.selectedTemplate);\r\n const childMatchPattern = xmlGetAttribute(childSelection.selectedTemplate, 'match');\r\n const childModeAttr = xmlGetAttribute(childSelection.selectedTemplate, 'mode');\r\n \r\n this.currentTemplateStack.push({\r\n template: childSelection.selectedTemplate,\r\n stylesheetDepth: childMetadata?.importDepth ?? 0,\r\n mode: childModeAttr || mode,\r\n match: childMatchPattern\r\n });\r\n \r\n const previousOverrideContext = this.currentOverrideContext;\r\n const overrideContext = childSelection.originalComponent || (childSelection.selectedTemplate as any).__originalComponent;\r\n if (overrideContext) {\r\n this.currentOverrideContext = overrideContext;\r\n }\r\n\r\n try {\r\n await this.xsltChildNodes(childContext, childSelection.selectedTemplate, output);\r\n } finally {\r\n this.currentTemplateStack.pop();\r\n this.currentOverrideContext = previousOverrideContext;\r\n }\r\n } else if (childNode.nodeType === DOM_ELEMENT_NODE) {\r\n // Recursively apply built-in template\r\n await this.applyBuiltInTemplate(childNode, expandedTemplates, mode, paramContext, output);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Implements `xsl:apply-imports`.\r\n * Applies templates from imported stylesheets with the same match pattern and mode.\r\n * This enables template overriding where a template in an importing stylesheet\r\n * can call the overridden template from the imported stylesheet.\r\n * @param context The Expression Context.\r\n * @param template The apply-imports template node.\r\n * @param output The output node.\r\n */\r\n protected async xsltApplyImports(context: ExprContext, template: XNode, output?: XNode) {\r\n // Check if we're within a template execution\r\n if (this.currentTemplateStack.length === 0) {\r\n throw new Error('<xsl:apply-imports> can only be used within a template');\r\n }\r\n\r\n // Get the current executing template's context\r\n const currentTemplateContext = this.currentTemplateStack[this.currentTemplateStack.length - 1];\r\n const {\r\n stylesheetDepth: currentDepth,\r\n mode: currentMode\r\n } = currentTemplateContext;\r\n\r\n // Get current node\r\n const currentNode = context.nodeList[context.position];\r\n\r\n // Collect templates from imported stylesheets (higher import depth = lower precedence)\r\n // We only want templates with importPrecedence LESS than current template (from imported stylesheets)\r\n const top = template.ownerDocument.documentElement;\r\n const stylesheetRoots: XNode[] = [];\r\n\r\n if (top) {\r\n stylesheetRoots.push(top);\r\n }\r\n\r\n this.importedStylesheets.forEach((doc) => {\r\n if (!doc) {\r\n return;\r\n }\r\n if (doc.nodeType === DOM_DOCUMENT_NODE) {\r\n const rootElement = doc.childNodes.find(\r\n (child: XNode) => child.nodeType === DOM_ELEMENT_NODE\r\n );\r\n if (rootElement) {\r\n stylesheetRoots.push(rootElement);\r\n }\r\n } else if (doc.nodeType === DOM_ELEMENT_NODE) {\r\n stylesheetRoots.push(doc);\r\n }\r\n });\r\n\r\n let allTemplates: TemplatePriorityInterface[] = [];\r\n let docOrderOffset = 0;\r\n\r\n for (const root of stylesheetRoots) {\r\n const templates = collectAndExpandTemplates(\r\n root,\r\n currentMode,\r\n this.xPath,\r\n this.templateSourceMap\r\n );\r\n for (const templateEntry of templates) {\r\n templateEntry.documentOrder += docOrderOffset;\r\n }\r\n docOrderOffset += templates.length;\r\n allTemplates = allTemplates.concat(templates);\r\n }\r\n\r\n // Filter to only templates from imported stylesheets (depth > currentDepth)\r\n const importedTemplates = allTemplates.filter((t) => {\r\n const metadata = this.templateSourceMap.get(t.template);\r\n return metadata && metadata.importDepth > currentDepth;\r\n });\r\n\r\n if (importedTemplates.length === 0) {\r\n return;\r\n }\r\n\r\n // Create a context for the current node to use with template selection\r\n const nodeContext = context.clone([currentNode], 0);\r\n\r\n // Select best matching template from imported stylesheets\r\n const selection = selectBestTemplate(\r\n importedTemplates,\r\n nodeContext,\r\n this.matchResolver,\r\n this.xPath,\r\n this.warningsCallback\r\n );\r\n\r\n if (!selection.selectedTemplate) {\r\n // No matching template in imported stylesheets\r\n return;\r\n }\r\n\r\n // Clone context and apply any with-param parameters from the apply-imports element\r\n const importedContext = context.clone();\r\n await this.xsltWithParam(importedContext, template);\r\n\r\n // Execute the imported template\r\n // Need to track this as the new current template\r\n const metadata = this.templateSourceMap.get(selection.selectedTemplate);\r\n if (metadata) {\r\n const matchPattern = xmlGetAttribute(selection.selectedTemplate, 'match');\r\n const modeAttr = xmlGetAttribute(selection.selectedTemplate, 'mode');\r\n this.currentTemplateStack.push({\r\n template: selection.selectedTemplate,\r\n stylesheetDepth: metadata.importDepth,\r\n mode: modeAttr || currentMode,\r\n match: matchPattern\r\n });\r\n\r\n const previousOverrideContext = this.currentOverrideContext;\r\n const overrideContext = selection.originalComponent || (selection.selectedTemplate as any).__originalComponent;\r\n if (overrideContext) {\r\n this.currentOverrideContext = overrideContext;\r\n }\r\n\r\n try {\r\n await this.xsltChildNodes(importedContext, selection.selectedTemplate, output);\r\n } finally {\r\n this.currentTemplateStack.pop();\r\n this.currentOverrideContext = previousOverrideContext;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Implements `xsl:attribute`.\r\n * @param context The Expression Context.\r\n * @param template The template.\r\n * @param output The output. Only used if there's no corresponding output node already defined.\r\n * @protected\r\n */\r\n protected async xsltAttribute(context: ExprContext, template: XNode, output?: XNode) {\r\n const nameExpr = xmlGetAttribute(template, 'name');\r\n const name = this.xsltAttributeValue(nameExpr, context);\r\n\r\n const documentFragment = domCreateDocumentFragment(this.outputDocument);\r\n await this.xsltChildNodes(context, template, documentFragment);\r\n const value = xmlValueLegacyBehavior(documentFragment);\r\n\r\n if (output) {\r\n domSetAttribute(output, name, value);\r\n\r\n // If the attribute name has a namespace prefix, ensure xmlns declaration exists\r\n if (name.includes(':')) {\r\n const prefix = name.split(':')[0];\r\n if (prefix !== 'xmlns') {\r\n const explicitNs = xmlGetAttribute(template, 'namespace');\r\n const nsUri = explicitNs || this.resolveNamespaceUriForPrefix(template, prefix);\r\n if (nsUri) {\r\n const nsAttr = `xmlns:${prefix}`;\r\n if (!this.isNamespaceDeclaredOnAncestor(output, nsAttr, nsUri)) {\r\n domSetAttribute(output, nsAttr, nsUri);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Implements `xsl:call-template`.\r\n * @param context The Expression Context.\r\n * @param template The template.\r\n * @param output The output, used when a fragment is passed by a previous step.\r\n */\r\n protected async xsltCallTemplate(context: ExprContext, template: XNode, output?: XNode) {\r\n const name = xmlGetAttribute(template, 'name');\r\n const top = template.ownerDocument.documentElement;\r\n\r\n const paramContext = context.clone();\r\n await this.xsltWithParam(paramContext, template);\r\n\r\n // First, check for overridden named templates from used packages\r\n let foundTemplate: XNode | null = null;\r\n if (this.currentPackage) {\r\n this.currentPackage.usedPackages.forEach((usedPkg) => {\r\n usedPkg.acceptedComponents.forEach((component) => {\r\n if (component.type === 'template' && component.name === name && component.isAccepted) {\r\n // Check for override\r\n const effectiveComponent = this.getEffectiveComponent(component);\r\n foundTemplate = effectiveComponent.node;\r\n }\r\n });\r\n });\r\n }\r\n\r\n // If found in accepted components (possibly overridden), use it\r\n if (foundTemplate) {\r\n await this.xsltChildNodes(paramContext, foundTemplate, output);\r\n return;\r\n }\r\n\r\n // Otherwise, search in the current stylesheet\r\n for (let i = 0; i < top.childNodes.length; ++i) {\r\n let childNode = top.childNodes[i];\r\n if (\r\n childNode.nodeType === DOM_ELEMENT_NODE &&\r\n this.isXsltElement(childNode, 'template') &&\r\n domGetAttributeValue(childNode, 'name') === name\r\n ) {\r\n await this.xsltChildNodes(paramContext, childNode, output);\r\n break;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Implements `xsl:choose`, its child nodes `xsl:when`, and\r\n * `xsl:otherwise`.\r\n * @param context The Expression Context.\r\n * @param template The template.\r\n * @param output The output. Only used if there's no corresponding output node already defined.\r\n */\r\n protected async xsltChoose(context: ExprContext, template: XNode, output?: XNode) {\r\n for (const childNode of template.childNodes) {\r\n if (childNode.nodeType !== DOM_ELEMENT_NODE) {\r\n continue;\r\n }\r\n\r\n if (this.isXsltElement(childNode, 'when')) {\r\n const test = xmlGetAttribute(childNode, 'test');\r\n if (this.xPath.xPathEval(test, context).booleanValue()) {\r\n await this.xsltChildNodes(context, childNode, output);\r\n break;\r\n }\r\n } else if (this.isXsltElement(childNode, 'otherwise')) {\r\n await this.xsltChildNodes(context, childNode, output);\r\n break;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Implements `xsl:copy` for all node types.\r\n * @param {XNode} destination the node being copied to, part of output document.\r\n * @param {XNode} source the node being copied, part in input document.\r\n * @returns {XNode|null} If an element node was created, the element node. Otherwise, null.\r\n */\r\n protected xsltCopy(destination: XNode, source: XNode): XNode {\r\n if (source.nodeType == DOM_ELEMENT_NODE) {\r\n let node = domCreateElement(this.outputDocument, source.nodeName);\r\n // node.transformedNodeName = source.nodeName;\r\n if (source.namespaceUri !== null && source.namespaceUri !== undefined) {\r\n const prefix = source.prefix || (source.nodeName.includes(':') ? source.nodeName.split(':')[0] : null);\r\n const nsAttr = prefix ? `xmlns:${prefix}` : 'xmlns';\r\n // Only add the namespace declaration if not already declared by an ancestor\r\n if (!this.isNamespaceDeclaredOnAncestor(destination, nsAttr, source.namespaceUri)) {\r\n domSetAttribute(node, nsAttr, source.namespaceUri);\r\n }\r\n }\r\n // Set siblingPosition to preserve insertion order during serialization\r\n node.siblingPosition = destination.childNodes.length;\r\n domAppendChild(destination, node);\r\n return node;\r\n }\r\n if (source.nodeType == DOM_TEXT_NODE) {\r\n // Check if this whitespace-only text node should be stripped\r\n if (this.shouldStripWhitespaceNode(source)) {\r\n return null;\r\n }\r\n let node = domCreateTextNode(this.outputDocument, source.nodeValue);\r\n node.siblingPosition = destination.childNodes.length;\r\n domAppendChild(destination, node);\r\n } else if (source.nodeType == DOM_CDATA_SECTION_NODE) {\r\n let node = domCreateCDATASection(this.outputDocument, source.nodeValue);\r\n node.siblingPosition = destination.childNodes.length;\r\n domAppendChild(destination, node);\r\n } else if (source.nodeType == DOM_COMMENT_NODE) {\r\n let node = domCreateComment(this.outputDocument, source.nodeValue);\r\n node.siblingPosition = destination.childNodes.length;\r\n domAppendChild(destination, node);\r\n } else if (source.nodeType == DOM_ATTRIBUTE_NODE) {\r\n domSetAttribute(destination, source.nodeName, source.nodeValue);\r\n\r\n // If the attribute has a namespace prefix, ensure xmlns declaration exists\r\n if (source.prefix && source.namespaceUri &&\r\n source.prefix !== 'xmlns' && !source.nodeName.startsWith('xmlns')) {\r\n const nsAttr = `xmlns:${source.prefix}`;\r\n if (!this.isNamespaceDeclaredOnAncestor(destination, nsAttr, source.namespaceUri)) {\r\n domSetAttribute(destination, nsAttr, source.namespaceUri);\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * Implements `xsl:comment`. \r\n * @param context The Expression Context.\r\n * @param template The template.\r\n * @param output The output. Only used if there's no corresponding output node already defined. \r\n */\r\n protected async xsltComment(context: ExprContext, template: XNode, output?: XNode) {\r\n const node = domCreateDocumentFragment(this.outputDocument);\r\n await this.xsltChildNodes(context, template, node);\r\n const commentData = xmlValue(node);\r\n const commentNode = domCreateComment(this.outputDocument, commentData);\r\n const resolvedOutput = output || this.outputDocument;\r\n resolvedOutput.appendChild(commentNode);\r\n }\r\n\r\n /**\r\n * Implements `xsl:processing-instruction`.\r\n * @param context The Expression Context.\r\n * @param template The template.\r\n * @param output The output. Only used if there's no corresponding output node already defined.\r\n */\r\n protected async xsltProcessingInstruction(context: ExprContext, template: XNode, output?: XNode) {\r\n // Get the target name (required)\r\n const nameExpr = xmlGetAttribute(template, 'name');\r\n if (!nameExpr) {\r\n throw new Error('<xsl:processing-instruction> requires a \"name\" attribute');\r\n }\r\n\r\n // Evaluate name as attribute value template\r\n const target = this.xsltAttributeValue(nameExpr, context);\r\n\r\n if (!target) {\r\n throw new Error('<xsl:processing-instruction> target name cannot be empty');\r\n }\r\n\r\n if (target.toLowerCase() === 'xml') {\r\n throw new Error('Processing instruction target cannot be \"xml\"');\r\n }\r\n\r\n // Validate target name format (no spaces, valid XML NCName for PI target)\r\n // PI targets must match: [a-zA-Z_:][a-zA-Z0-9_:.-]*\r\n if (!/^[a-zA-Z_][a-zA-Z0-9_:.-]*$/.test(target)) {\r\n throw new Error(`Invalid processing instruction target: \"${target}\"`);\r\n }\r\n\r\n // Process child nodes to get PI data content\r\n const documentFragment = domCreateDocumentFragment(this.outputDocument);\r\n await this.xsltChildNodes(context, template, documentFragment);\r\n\r\n // Extract text content from fragment\r\n const data = xmlValue(documentFragment);\r\n\r\n // Create processing instruction node\r\n const pi = domCreateProcessingInstruction(this.outputDocument, target, data);\r\n\r\n // Add to output\r\n const resolvedOutput = output || this.outputDocument;\r\n domAppendChild(resolvedOutput, pi);\r\n }\r\n\r\n /**\r\n * Implements `xsl:copy-of` for node-set values of the select\r\n * expression. Recurses down the source node tree, which is part of\r\n * the input document.\r\n * @param {XNode} destination the node being copied to, part of output document.\r\n * @param {XNode} source the node being copied, part in input document.\r\n */\r\n protected xsltCopyOf(destination: XNode, source: XNode): void {\r\n if (source.nodeType == DOM_DOCUMENT_FRAGMENT_NODE || source.nodeType == DOM_DOCUMENT_NODE) {\r\n for (let i = 0; i < source.childNodes.length; ++i) {\r\n this.xsltCopyOf(destination, source.childNodes[i]);\r\n }\r\n } else {\r\n const node = this.xsltCopy(destination, source);\r\n if (node) {\r\n for (let i = 0; i < source.childNodes.length; ++i) {\r\n this.xsltCopyOf(node, source.childNodes[i]);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Implements `xsl:decimal-format`, registering the settings in this instance\r\n * and the current context. \r\n * @param context The Expression Context.\r\n * @param template The template.\r\n */\r\n protected xsltDecimalFormat(context: ExprContext, template: XNode) {\r\n const name = xmlGetAttribute(template, 'name');\r\n const decimalSeparator = xmlGetAttribute(template, 'decimal-separator');\r\n const groupingSeparator = xmlGetAttribute(template, 'grouping-separator');\r\n const infinity = xmlGetAttribute(template, 'infinity');\r\n const minusSign = xmlGetAttribute(template, 'minus-sign');\r\n const naN = xmlGetAttribute(template, 'NaN');\r\n const percent = xmlGetAttribute(template, 'percent');\r\n const perMille = xmlGetAttribute(template, 'per-mille');\r\n const zeroDigit = xmlGetAttribute(template, 'zero-digit');\r\n const digit = xmlGetAttribute(template, 'digit');\r\n const patternSeparator = xmlGetAttribute(template, 'pattern-separator');\r\n this.decimalFormatSettings = {\r\n name: name || this.decimalFormatSettings.name,\r\n decimalSeparator: decimalSeparator || this.decimalFormatSettings.decimalSeparator,\r\n groupingSeparator: groupingSeparator || this.decimalFormatSettings.groupingSeparator,\r\n infinity: infinity || this.decimalFormatSettings.infinity,\r\n minusSign: minusSign || this.decimalFormatSettings.minusSign,\r\n naN: naN || this.decimalFormatSettings.naN,\r\n percent: percent || this.decimalFormatSettings.percent,\r\n perMille: perMille || this.decimalFormatSettings.perMille,\r\n zeroDigit: zeroDigit || this.decimalFormatSettings.zeroDigit,\r\n digit: digit || this.decimalFormatSettings.digit,\r\n patternSeparator: patternSeparator || this.decimalFormatSettings.patternSeparator\r\n };\r\n context.decimalFormatSettings = this.decimalFormatSettings;\r\n }\r\n\r\n /**\r\n * Implements `xsl:element`.\r\n * @param context The Expression Context.\r\n * @param template The template.\r\n */\r\n protected async xsltElement(context: ExprContext, template: XNode, output?: XNode) {\r\n const nameExpr = xmlGetAttribute(template, 'name');\r\n const name = this.xsltAttributeValue(nameExpr, context);\r\n const node = domCreateElement(this.outputDocument, name);\r\n\r\n // Apply attribute sets first (they can be overridden by child attributes)\r\n const useAttributeSets = xmlGetAttribute(template, 'use-attribute-sets');\r\n if (useAttributeSets) {\r\n await this.applyAttributeSets(context, node, useAttributeSets);\r\n }\r\n\r\n // node.transformedNodeName = name;\r\n\r\n // Fix for Issue 161: Set siblingPosition to preserve document order\r\n node.siblingPosition = (output || this.outputDocument).childNodes.length;\r\n\r\n domAppendChild(output || this.outputDocument, node);\r\n // The element becomes the output node of the source node.\r\n // context.nodeList[context.position].outputNode = node;\r\n const clonedContext = context.clone();\r\n await this.xsltChildNodes(clonedContext, template, node);\r\n }\r\n\r\n /**\r\n * Implements `xsl:accumulator` (XSLT 3.0).\r\n *\r\n * Accumulators are a declarative way to compute values during template processing.\r\n * They consist of rules that are applied as elements are processed.\r\n *\r\n * @param context The expression context\r\n * @param template The xsl:accumulator element\r\n */\r\n protected xsltAccumulator(context: ExprContext, template: XNode) {\r\n const name = xmlGetAttribute(template, 'name');\r\n if (!name) {\r\n throw new Error('<xsl:accumulator> requires a \"name\" attribute');\r\n }\r\n\r\n const initialValue = xmlGetAttribute(template, 'initial-value') || '()';\r\n const as = xmlGetAttribute(template, 'as') || 'xs:anyAtomicType*';\r\n const streamableStr = xmlGetAttribute(template, 'streamable') || 'no';\r\n const streamable = streamableStr === 'yes' || streamableStr === 'true' || streamableStr === '1';\r\n\r\n const rules: AccumulatorRule[] = [];\r\n\r\n // Process xsl:accumulator-rule children\r\n for (let i = 0; i < template.childNodes.length; i++) {\r\n const child = template.childNodes[i];\r\n if (child.nodeType === DOM_ELEMENT_NODE && child.nodeName === 'accumulator-rule') {\r\n const match = xmlGetAttribute(child, 'match');\r\n if (!match) {\r\n throw new Error('<xsl:accumulator-rule> requires a \"match\" attribute');\r\n }\r\n\r\n const select = xmlGetAttribute(child, 'select');\r\n if (!select) {\r\n throw new Error('<xsl:accumulator-rule> requires a \"select\" attribute');\r\n }\r\n\r\n const phase = xmlGetAttribute(child, 'phase');\r\n rules.push({\r\n match,\r\n select,\r\n phase: (phase === 'start' || phase === 'end') ? phase : undefined\r\n });\r\n }\r\n }\r\n\r\n const definition: AccumulatorDefinition = {\r\n name,\r\n initialValue,\r\n as,\r\n rules,\r\n streamable\r\n };\r\n\r\n // Register the accumulator\r\n this.accumulatorRegistry.registerAccumulator(definition);\r\n\r\n // Initialize the accumulator value with the initial value expression\r\n try {\r\n const initialResult = this.xPath.xPathEval(initialValue, context);\r\n const state: AccumulatorState = {\r\n currentValue: initialResult,\r\n valueStack: [initialResult]\r\n };\r\n this.accumulatorRegistry.setAccumulatorState(name, state);\r\n } catch (e) {\r\n // If initial-value evaluation fails, use the result as-is\r\n const state: AccumulatorState = {\r\n currentValue: null,\r\n valueStack: [null]\r\n };\r\n this.accumulatorRegistry.setAccumulatorState(name, state);\r\n }\r\n }\r\n\r\n /**\r\n * Evaluates all matching accumulator rules for a given node\r\n * and updates the accumulator state\r\n *\r\n * @param context The expression context with current node\r\n * @param node The current node being processed\r\n */\r\n protected evaluateAccumulatorRules(context: ExprContext, node: XNode): void {\r\n const allAccumulators = this.accumulatorRegistry.getAllAccumulators();\r\n\r\n for (const accumulator of allAccumulators) {\r\n const state = this.accumulatorRegistry.getAccumulatorState(accumulator.name);\r\n if (!state) continue;\r\n\r\n // Process each rule\r\n for (const rule of accumulator.rules) {\r\n // Check if the pattern matches the current node\r\n try {\r\n // Create a match context for this node\r\n const matchContext = context.clone([node], 0);\r\n const matchedNodes = this.xsltMatch(rule.match, matchContext);\r\n const matchResult = matchedNodes && matchedNodes.length > 0;\r\n\r\n if (matchResult) {\r\n // Pattern matches - evaluate the select expression\r\n // The context should include the $value variable with current accumulated value\r\n const ruleContext = context.clone([node], 0);\r\n\r\n // Set $value to current accumulated value\r\n ruleContext.setVariable('value', new StringValue(\r\n state.currentValue ? String(state.currentValue) : ''\r\n ));\r\n\r\n // Evaluate the select expression\r\n const newValue = this.xPath.xPathEval(rule.select, ruleContext);\r\n\r\n // Update the accumulator state\r\n state.currentValue = newValue;\r\n }\r\n } catch (e) {\r\n // Pattern matching or evaluation failed - skip this rule\r\n // Log warning if configured\r\n if (this.warningsCallback) {\r\n this.warningsCallback(`Error evaluating accumulator rule for ${accumulator.name}: ${e}`);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Retrieves the current value of an accumulator\r\n * Used when accessing accumulators in templates via accumulator-after() or accumulator-before()\r\n *\r\n * @param accumulatorName The name of the accumulator\r\n * @returns The current value of the accumulator, or null if not found\r\n */\r\n protected getAccumulatorValue(accumulatorName: string): any {\r\n const state = this.accumulatorRegistry.getAccumulatorState(accumulatorName);\r\n return state ? state.currentValue : null;\r\n }\r\n\r\n /**\r\n * Implements `xsl:for-each`.\r\n * @param context The Expression Context.\r\n * @param template The template.\r\n * @param output The output.\r\n */\r\n protected async xsltForEach(context: ExprContext, template: XNode, output?: XNode) {\r\n const select = xmlGetAttribute(template, 'select');\r\n const nodes = this.xPath.xPathEval(select, context).nodeSetValue();\r\n const onEmpty = this.findConditionalChild(template, 'on-empty');\r\n const onNonEmpty = this.findConditionalChild(template, 'on-non-empty');\r\n\r\n if (nodes.length === 0) {\r\n if (onEmpty) {\r\n await this.xsltChildNodes(context.clone(), onEmpty, output);\r\n }\r\n return;\r\n }\r\n\r\n if (onNonEmpty) {\r\n await this.xsltChildNodes(context.clone(), onNonEmpty, output);\r\n return;\r\n }\r\n\r\n // TODO: Why do we need this sort, really?\r\n // I have no idea why this logic is here (it was implemented\r\n // before Design Liquido taking over), so if it is proven not useful,\r\n // this entire logic must be removed.\r\n const sortContext = context.clone(nodes);\r\n this.xsltSort(sortContext, template);\r\n\r\n const nodesWithParent = sortContext.nodeList.filter((n) => n.parentNode !== null && n.parentNode !== undefined);\r\n if (nodesWithParent.length <= 0) {\r\n throw new Error('Nodes with no parents defined.');\r\n }\r\n\r\n for (let i = 0; i < sortContext.contextSize(); ++i) {\r\n await this.xsltChildNodesExcludingConditional(\r\n sortContext.clone(sortContext.nodeList, i),\r\n template,\r\n output\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Implements `xsl:for-each-group` (XSLT 2.0).\r\n *\r\n * Groups items from the select expression and processes each group.\r\n * Supports group-by and group-adjacent grouping methods.\r\n *\r\n * @param context The Expression Context.\r\n * @param template The template.\r\n * @param output The output.\r\n */\r\n protected async xsltForEachGroup(context: ExprContext, template: XNode, output?: XNode) {\r\n const select = xmlGetAttribute(template, 'select');\r\n const groupBy = xmlGetAttribute(template, 'group-by');\r\n const groupAdjacent = xmlGetAttribute(template, 'group-adjacent');\r\n const groupStartingWith = xmlGetAttribute(template, 'group-starting-with');\r\n const groupEndingWith = xmlGetAttribute(template, 'group-ending-with');\r\n const onEmpty = this.findConditionalChild(template, 'on-empty');\r\n const onNonEmpty = this.findConditionalChild(template, 'on-non-empty');\r\n\r\n if (!select) {\r\n throw new Error('<xsl:for-each-group> requires a select attribute.');\r\n }\r\n\r\n // Check that exactly one grouping method is specified\r\n const groupingMethods = [groupBy, groupAdjacent, groupStartingWith, groupEndingWith].filter(m => m);\r\n if (groupingMethods.length === 0) {\r\n throw new Error('<xsl:for-each-group> requires one of: group-by, group-adjacent, group-starting-with, or group-ending-with.');\r\n }\r\n if (groupingMethods.length > 1) {\r\n throw new Error('<xsl:for-each-group> can only have one grouping method.');\r\n }\r\n\r\n // Get the items to group\r\n const items = this.xPath.xPathEval(select, context).nodeSetValue();\r\n if (items.length === 0) {\r\n if (onEmpty) {\r\n await this.xsltChildNodes(context.clone(), onEmpty, output);\r\n }\r\n return;\r\n }\r\n\r\n // Build groups based on the grouping method\r\n let groups: { key: any; items: XNode[] }[];\r\n\r\n if (groupBy) {\r\n groups = this.groupByKey(items, groupBy, context);\r\n } else if (groupAdjacent) {\r\n groups = this.groupAdjacent(items, groupAdjacent, context);\r\n } else if (groupStartingWith) {\r\n groups = this.groupStartingWith(items, groupStartingWith, context);\r\n } else if (groupEndingWith) {\r\n groups = this.groupEndingWith(items, groupEndingWith, context);\r\n } else {\r\n return; // Should not reach here\r\n }\r\n\r\n if (onNonEmpty) {\r\n await this.xsltChildNodes(context.clone(), onNonEmpty, output);\r\n return;\r\n }\r\n\r\n // Process each group\r\n for (let i = 0; i < groups.length; i++) {\r\n const group = groups[i];\r\n // Create context with first item of group as context node\r\n const groupContext = context.clone(group.items, 0);\r\n // Set current group and grouping key for current-group() and current-grouping-key() functions\r\n groupContext.currentGroup = group.items;\r\n groupContext.currentGroupingKey = group.key;\r\n\r\n await this.xsltChildNodesExcludingConditional(groupContext, template, output);\r\n }\r\n }\r\n\r\n /**\r\n * Group items by a computed key value.\r\n * Items with the same key are placed in the same group.\r\n */\r\n private groupByKey(items: XNode[], keyExpr: string, context: ExprContext): { key: any; items: XNode[] }[] {\r\n const groupMap = new Map<string, { key: any; items: XNode[] }>();\r\n const groupOrder: string[] = []; // Maintain insertion order\r\n\r\n for (const item of items) {\r\n const itemContext = context.clone([item], 0);\r\n const keyValue = this.xPath.xPathEval(keyExpr, itemContext);\r\n const keyString = keyValue.stringValue();\r\n\r\n if (!groupMap.has(keyString)) {\r\n groupMap.set(keyString, { key: keyString, items: [] });\r\n groupOrder.push(keyString);\r\n }\r\n groupMap.get(keyString)!.items.push(item);\r\n }\r\n\r\n // Return groups in order of first occurrence\r\n return groupOrder.map(key => groupMap.get(key)!);\r\n }\r\n\r\n /**\r\n * Group adjacent items with the same key.\r\n * A new group starts when the key changes.\r\n */\r\n private groupAdjacent(items: XNode[], keyExpr: string, context: ExprContext): { key: any; items: XNode[] }[] {\r\n const groups: { key: any; items: XNode[] }[] = [];\r\n let currentKey: string | null = null;\r\n let currentGroup: XNode[] = [];\r\n\r\n for (const item of items) {\r\n const itemContext = context.clone([item], 0);\r\n const keyValue = this.xPath.xPathEval(keyExpr, itemContext);\r\n const keyString = keyValue.stringValue();\r\n\r\n if (currentKey === null || keyString !== currentKey) {\r\n // Start a new group\r\n if (currentGroup.length > 0) {\r\n groups.push({ key: currentKey, items: currentGroup });\r\n }\r\n currentKey = keyString;\r\n currentGroup = [item];\r\n } else {\r\n // Add to current group\r\n currentGroup.push(item);\r\n }\r\n }\r\n\r\n // Don't forget the last group\r\n if (currentGroup.length > 0) {\r\n groups.push({ key: currentKey, items: currentGroup });\r\n }\r\n\r\n return groups;\r\n }\r\n\r\n /**\r\n * Convert an XSLT pattern to a self:: expression for matching against the current node.\r\n * For example, \"h1\" becomes \"self::h1\", \"section[@type]\" becomes \"self::section[@type]\".\r\n */\r\n private patternToSelfExpression(pattern: string): string {\r\n // If it already uses an axis or is a complex expression, wrap it appropriately\r\n if (pattern.includes('::') || pattern.startsWith('/') || pattern.startsWith('(')) {\r\n // Already has an axis or is an absolute/complex path\r\n return pattern;\r\n }\r\n // For simple patterns like \"h1\" or \"section\", prepend self::\r\n return `self::${pattern}`;\r\n }\r\n\r\n /**\r\n * Group items starting with items that match a pattern.\r\n * A new group starts when an item matches the pattern.\r\n */\r\n private groupStartingWith(items: XNode[], pattern: string, context: ExprContext): { key: any; items: XNode[] }[] {\r\n const groups: { key: any; items: XNode[] }[] = [];\r\n let currentGroup: XNode[] = [];\r\n let groupIndex = 0;\r\n // Convert pattern to self:: expression for proper matching\r\n const selfPattern = this.patternToSelfExpression(pattern);\r\n\r\n for (const item of items) {\r\n const itemContext = context.clone([item], 0);\r\n // Check if item matches the pattern\r\n const matches = this.xPath.xPathEval(selfPattern, itemContext).booleanValue();\r\n\r\n if (matches && currentGroup.length > 0) {\r\n // Start a new group (save previous)\r\n groups.push({ key: groupIndex++, items: currentGroup });\r\n currentGroup = [item];\r\n } else if (matches && currentGroup.length === 0) {\r\n // First item starts a new group\r\n currentGroup = [item];\r\n } else {\r\n // Add to current group\r\n currentGroup.push(item);\r\n }\r\n }\r\n\r\n // Don't forget the last group\r\n if (currentGroup.length > 0) {\r\n groups.push({ key: groupIndex, items: currentGroup });\r\n }\r\n\r\n return groups;\r\n }\r\n\r\n /**\r\n * Group items ending with items that match a pattern.\r\n * A group ends when an item matches the pattern.\r\n */\r\n private groupEndingWith(items: XNode[], pattern: string, context: ExprContext): { key: any; items: XNode[] }[] {\r\n const groups: { key: any; items: XNode[] }[] = [];\r\n let currentGroup: XNode[] = [];\r\n let groupIndex = 0;\r\n // Convert pattern to self:: expression for proper matching\r\n const selfPattern = this.patternToSelfExpression(pattern);\r\n\r\n for (const item of items) {\r\n currentGroup.push(item);\r\n\r\n const itemContext = context.clone([item], 0);\r\n // Check if item matches the pattern (ends the group)\r\n const matches = this.xPath.xPathEval(selfPattern, itemContext).booleanValue();\r\n\r\n if (matches) {\r\n // End the current group\r\n groups.push({ key: groupIndex++, items: currentGroup });\r\n currentGroup = [];\r\n }\r\n }\r\n\r\n // Don't forget the last group (if it didn't end with a match)\r\n if (currentGroup.length > 0) {\r\n groups.push({ key: groupIndex, items: currentGroup });\r\n }\r\n\r\n return groups;\r\n }\r\n\r\n /**\r\n * Implements `xsl:iterate` (XSLT 3.0).\r\n *\r\n * Iterates over a sequence, maintaining accumulators that are updated across iterations.\r\n * Each iteration can output content and update accumulator values.\r\n * After all iterations complete, optional xsl:on-completion is executed.\r\n *\r\n * @param context The Expression Context.\r\n * @param template The template.\r\n * @param output The output.\r\n */\r\n protected async xsltIterate(context: ExprContext, template: XNode, output?: XNode) {\r\n const select = xmlGetAttribute(template, 'select');\r\n\r\n if (!select) {\r\n throw new Error('<xsl:iterate> requires a select attribute.');\r\n }\r\n\r\n // Evaluate the sequence to iterate over\r\n const items = this.xPath.xPathEval(select, context).nodeSetValue();\r\n if (items.length === 0) {\r\n // Process on-completion even with empty sequence\r\n const onCompletionElements = Array.from(template.childNodes || []).filter(\r\n (node) => node.nodeType === DOM_ELEMENT_NODE && \r\n this.isXsltElement(node as XNode, 'on-completion')\r\n ) as XNode[];\r\n\r\n if (onCompletionElements.length > 0) {\r\n const onCompletion = onCompletionElements[0];\r\n const completionContext = context.clone([], 0);\r\n await this.xsltChildNodes(completionContext, onCompletion, output);\r\n }\r\n return;\r\n }\r\n \r\n // Initialize accumulators from xsl:param children\r\n const accumulators: { [name: string]: any } = {};\r\n const paramElements = Array.from(template.childNodes || []).filter(\r\n (node) => node.nodeType === DOM_ELEMENT_NODE && \r\n (node as XNode).localName === 'param' &&\r\n this.isXsltElement(node as XNode)\r\n ) as XNode[];\r\n\r\n // Initialize each accumulator\r\n for (const paramNode of paramElements) {\r\n const paramName = xmlGetAttribute(paramNode, 'name');\r\n if (!paramName) {\r\n throw new Error('<xsl:param> in <xsl:iterate> requires a name attribute.');\r\n }\r\n\r\n // Get initial value from select attribute\r\n const selectValue = xmlGetAttribute(paramNode, 'select');\r\n let initialValue: any = new StringValue('');\r\n\r\n if (selectValue) {\r\n initialValue = this.xPath.xPathEval(selectValue, context);\r\n }\r\n\r\n accumulators[paramName] = initialValue;\r\n }\r\n\r\n // Iterate over items\r\n for (let i = 0; i < items.length; i++) {\r\n const item = items[i];\r\n \r\n // Create iteration context with current item as context node\r\n const iterationContext = context.clone([item], 0);\r\n \r\n // Add accumulators to the context as variables\r\n for (const accName in accumulators) {\r\n iterationContext.variables[accName] = accumulators[accName];\r\n }\r\n\r\n // Process the iteration body (excluding xsl:param, xsl:on-completion, xsl:next-iteration)\r\n const allBodyNodes = Array.from(template.childNodes || []);\r\n\r\n // Process iteration body\r\n for (const bodyNode of allBodyNodes) {\r\n if (bodyNode.nodeType === DOM_ELEMENT_NODE) {\r\n const elem = bodyNode as XNode;\r\n // Skip XSLT special elements\r\n if (this.isXsltElement(elem) && \r\n (elem.localName === 'param' ||\r\n elem.localName === 'on-completion' ||\r\n elem.localName === 'next-iteration')) {\r\n continue;\r\n }\r\n }\r\n \r\n await this.xsltProcessContext(iterationContext, bodyNode, output);\r\n }\r\n\r\n // Process xsl:next-iteration to update accumulators\r\n const nextIterationElements = Array.from(template.childNodes || []).filter(\r\n (node) => node.nodeType === DOM_ELEMENT_NODE && \r\n this.isXsltElement(node as XNode, 'next-iteration')\r\n ) as XNode[];\r\n\r\n if (nextIterationElements.length > 0) {\r\n const nextIteration = nextIterationElements[0];\r\n const withParamElements = Array.from(nextIteration.childNodes || []).filter(\r\n (node) => node.nodeType === DOM_ELEMENT_NODE && \r\n this.isXsltElement(node as XNode, 'with-param')\r\n ) as XNode[];\r\n\r\n // Update accumulators with new values from xsl:with-param\r\n for (const withParam of withParamElements) {\r\n const paramName = xmlGetAttribute(withParam, 'name');\r\n if (!paramName) {\r\n throw new Error('<xsl:with-param> requires a name attribute.');\r\n }\r\n\r\n const selectValue = xmlGetAttribute(withParam, 'select');\r\n if (selectValue) {\r\n const newValue = this.xPath.xPathEval(selectValue, iterationContext);\r\n accumulators[paramName] = newValue;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // After iteration, process xsl:on-completion if present\r\n const onCompletionElements = Array.from(template.childNodes || []).filter(\r\n (node) => node.nodeType === DOM_ELEMENT_NODE && \r\n this.isXsltElement(node as XNode, 'on-completion')\r\n ) as XNode[];\r\n\r\n if (onCompletionElements.length > 0) {\r\n const onCompletion = onCompletionElements[0];\r\n \r\n // Create completion context - use empty nodelist but preserve variables\r\n const completionContext = context.clone([], 0);\r\n \r\n // Add final accumulators to context\r\n for (const accName in accumulators) {\r\n completionContext.variables[accName] = accumulators[accName];\r\n }\r\n\r\n // Process on-completion body\r\n await this.xsltChildNodes(completionContext, onCompletion, output);\r\n }\r\n }\r\n\r\n /**\r\n * Implements `xsl:try`.\r\n * @param context The Expression Context.\r\n * @param template The template.\r\n * @param output The output.\r\n */\r\n protected async xsltTry(context: ExprContext, template: XNode, output?: XNode) {\r\n const tryBodyNodes = Array.from(template.childNodes || []).filter(\r\n (node) => node.nodeType === DOM_ELEMENT_NODE && \r\n !this.isXsltElement(node as XNode, 'catch')\r\n ) as XNode[];\r\n\r\n const catchElements = Array.from(template.childNodes || []).filter(\r\n (node) => node.nodeType === DOM_ELEMENT_NODE && \r\n this.isXsltElement(node as XNode, 'catch')\r\n ) as XNode[];\r\n\r\n try {\r\n // Execute try body\r\n for (const bodyNode of tryBodyNodes) {\r\n await this.xsltProcessContext(context, bodyNode, output);\r\n }\r\n } catch (error: any) {\r\n // Extract error code from error object or use a generic error code\r\n let errorCode = 'err:UNKNOWN';\r\n if (error && typeof error === 'object') {\r\n if (error.code) {\r\n errorCode = error.code;\r\n } else if (error.message) {\r\n // Try to detect specific error types from error message\r\n if (error.message.includes('division by zero') || error.message.includes('div 0')) {\r\n errorCode = 'err:FOAR0001'; // Division by zero\r\n } else if (error.message.includes('undefined')) {\r\n errorCode = 'err:XPDY0002'; // Dynamic error\r\n }\r\n }\r\n }\r\n\r\n // Try to match against catch blocks\r\n let caught = false;\r\n for (const catchElement of catchElements) {\r\n const errorsAttr = xmlGetAttribute(catchElement, 'errors');\r\n \r\n // If no errors attribute, catch all errors\r\n if (!errorsAttr) {\r\n caught = true;\r\n } else {\r\n // Check if error code matches the pattern\r\n const errorPatterns = errorsAttr.split('|').map(p => p.trim());\r\n for (const pattern of errorPatterns) {\r\n if (pattern === '*' || pattern === errorCode) {\r\n caught = true;\r\n break;\r\n }\r\n // Support namespace-prefixed patterns like \"err:*\"\r\n if (pattern.endsWith('*')) {\r\n const prefix = pattern.slice(0, -1);\r\n if (errorCode.startsWith(prefix)) {\r\n caught = true;\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (caught) {\r\n // Execute catch block body (but not the catch element itself)\r\n await this.xsltChildNodes(context, catchElement, output);\r\n return; // Successfully caught, stop processing further catch blocks\r\n }\r\n }\r\n\r\n // If no catch block matched, re-throw the error\r\n if (!caught && catchElements.length > 0) {\r\n throw error;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Implements `xsl:evaluate` (XSLT 3.0).\r\n * Dynamically evaluates an XPath expression constructed as a string.\r\n * @param context The Expression Context.\r\n * @param template The template.\r\n * @param output The output.\r\n */\r\n protected async xsltEvaluate(context: ExprContext, template: XNode, output?: XNode) {\r\n const xpathAttr = xmlGetAttribute(template, 'xpath');\r\n if (!xpathAttr) {\r\n throw new Error('<xsl:evaluate> requires an xpath attribute.');\r\n }\r\n\r\n // Evaluate the xpath attribute itself (it may contain variables)\r\n // to get the actual XPath expression to evaluate\r\n const xpathExpr = this.xPath.xPathEval(xpathAttr, context).stringValue();\r\n\r\n // Get optional context-item attribute\r\n let contextItem = null;\r\n const contextItemAttr = xmlGetAttribute(template, 'context-item');\r\n if (contextItemAttr) {\r\n const contextItemResult = this.xPath.xPathEval(contextItemAttr, context);\r\n const items = contextItemResult.nodeSetValue();\r\n if (items.length > 0) {\r\n contextItem = items[0];\r\n }\r\n }\r\n\r\n // Create evaluation context\r\n // Use context-item if specified, otherwise use current context\r\n let evalContext: ExprContext;\r\n if (contextItem) {\r\n evalContext = context.clone([contextItem], 0);\r\n } else {\r\n evalContext = context.clone();\r\n }\r\n\r\n try {\r\n // Evaluate the dynamic XPath expression\r\n const result = this.xPath.xPathEval(xpathExpr, evalContext);\r\n\r\n // Output the result based on its type\r\n const destinationNode = output || this.outputDocument;\r\n\r\n if (result.type === 'node-set') {\r\n // For node-sets, copy each node\r\n const nodes = result.nodeSetValue();\r\n for (const node of nodes) {\r\n this.xsltCopyOf(destinationNode, node);\r\n }\r\n } else if (result.type === 'array' && (result as any).arrayValue) {\r\n // For arrays, serialize to text\r\n const arrayItems = (result as any).arrayValue();\r\n for (const item of arrayItems) {\r\n let textNode = domCreateTextNode(this.outputDocument, item.stringValue());\r\n textNode.siblingPosition = destinationNode.childNodes.length;\r\n domAppendChild(destinationNode, textNode);\r\n }\r\n } else {\r\n // For other types, output as text\r\n let textNode = domCreateTextNode(this.outputDocument, result.stringValue());\r\n textNode.siblingPosition = destinationNode.childNodes.length;\r\n domAppendChild(destinationNode, textNode);\r\n }\r\n } catch (error: any) {\r\n // Wrap XPath errors as XSLT dynamic errors\r\n throw new Error(`Dynamic XPath evaluation error in xsl:evaluate: ${error.message}`);\r\n }\r\n }\r\n\r\n /**\r\n * Implements `xsl:if`.\r\n * @param context The Expression Context.\r\n * @param template The template.\r\n * @param output The output.\r\n */\r\n protected async xsltIf(context: ExprContext, template: XNode, output?: XNode) {\r\n const test = xmlGetAttribute(template, 'test');\r\n if (this.xPath.xPathEval(test, context).booleanValue()) {\r\n await this.xsltChildNodes(context, template, output);\r\n }\r\n }\r\n\r\n /**\r\n * Common implementation for `<xsl:import>` and `<xsl:include>`.\r\n * @param context The Expression Context.\r\n * @param template The template.\r\n * @param output The output.\r\n * @param isImport Whether this is an import (true) or include (false).\r\n */\r\n protected async xsltImportOrInclude(context: ExprContext, template: XNode, output: XNode | undefined, isImport: boolean) {\r\n const elementName = isImport ? 'xsl:import' : 'xsl:include';\r\n\r\n const hrefAttributeFind = template.childNodes.filter(n => n.nodeName === 'href');\r\n if (hrefAttributeFind.length <= 0) {\r\n throw new Error(`<${elementName}> with no href attribute defined.`);\r\n }\r\n\r\n const hrefAttribute = hrefAttributeFind[0];\r\n const href = hrefAttribute.nodeValue;\r\n\r\n // Check if we've already imported this stylesheet\r\n if (this.importedStylesheets.has(href)) {\r\n // Already imported, skip to avoid duplicate processing\r\n return;\r\n }\r\n\r\n const fetchResponse = await this.fetchFunction(href);\r\n const includedXslt = this.xmlParser.xmlParse(fetchResponse);\r\n \r\n // Track stylesheet metadata for apply-imports\r\n const currentDepth = this.styleSheetStack.length > 0 \r\n ? this.styleSheetStack[this.styleSheetStack.length - 1].importDepth \r\n : 0;\r\n \r\n const metadata: StylesheetMetadata = {\r\n importDepth: isImport ? currentDepth + 1 : currentDepth, // Includes are same depth, imports are deeper\r\n href: href,\r\n order: this.importedStylesheets.size\r\n };\r\n \r\n this.styleSheetStack.push(metadata);\r\n this.importedStylesheets.set(href, includedXslt);\r\n \r\n // Map all templates in this stylesheet to their metadata\r\n const stylesheetRoot = includedXslt.childNodes[0];\r\n if (stylesheetRoot) {\r\n this.mapTemplatesFromStylesheet(stylesheetRoot, metadata);\r\n }\r\n \r\n await this.xsltChildNodes(context, stylesheetRoot, output);\r\n \r\n this.styleSheetStack.pop();\r\n }\r\n\r\n /**\r\n * Implements `<xsl:import>`. For now the code is nearly identical to `<xsl:include>`, but there's\r\n * no precedence evaluation implemented yet.\r\n * @param context The Expression Context.\r\n * @param template The template.\r\n * @param output The output.\r\n */\r\n protected async xsltImport(context: ExprContext, template: XNode, output?: XNode) {\r\n await this.xsltImportOrInclude(context, template, output, true);\r\n }\r\n\r\n /**\r\n * Implements `xsl:include`.\r\n * @param context The Expression Context.\r\n * @param template The template.\r\n * @param output The output.\r\n */\r\n protected async xsltInclude(context: ExprContext, template: XNode, output?: XNode) {\r\n await this.xsltImportOrInclude(context, template, output, false);\r\n }\r\n\r\n /**\r\n * Implements `<xsl:package>` (XSLT 3.0 Section 3.6).\r\n * Defines a package of XSLT components with controlled visibility.\r\n * @param context The Expression Context.\r\n * @param template The xsl:package element.\r\n * @param output The output node.\r\n */\r\n protected async xsltPackage(context: ExprContext, template: XNode, output?: XNode) {\r\n // Check XSLT version\r\n const version = xmlGetAttribute(template, 'version') || this.version;\r\n if (!version || parseFloat(version) < 3.0) {\r\n throw new Error('<xsl:package> is only supported in XSLT 3.0 or later.');\r\n }\r\n\r\n // Get package attributes\r\n const name = xmlGetAttribute(template, 'name');\r\n const packageVersion = xmlGetAttribute(template, 'package-version');\r\n const declaredModes = (xmlGetAttribute(template, 'declared-modes') || 'yes') as 'yes' | 'no';\r\n const inputTypeAnnotations = (xmlGetAttribute(template, 'input-type-annotations') || 'unspecified') as 'preserve' | 'strip' | 'unspecified';\r\n\r\n if (!name) {\r\n throw new Error('<xsl:package> requires a \"name\" attribute.');\r\n }\r\n\r\n // Mark as loading for circular dependency detection (if not already marked by loadAndRegisterPackage)\r\n const packageKey = packageVersion ? `${name}@${packageVersion}` : name;\r\n const wasAlreadyLoading = this.packageRegistry.isLoading(packageKey);\r\n if (!wasAlreadyLoading) {\r\n this.packageRegistry.beginLoading(packageKey);\r\n }\r\n\r\n // Create package structure\r\n const pkg: XsltPackageInterface = {\r\n name,\r\n version: packageVersion,\r\n root: template,\r\n components: new Map(),\r\n usedPackages: new Map(),\r\n isTopLevel: this.currentPackage === null,\r\n overrides: new Map(),\r\n modes: new Map(),\r\n declaredModes,\r\n inputTypeAnnotations\r\n };\r\n\r\n // Save previous package context\r\n const previousPackage = this.currentPackage;\r\n this.currentPackage = pkg;\r\n\r\n try {\r\n // Register the package\r\n this.packageRegistry.register(pkg);\r\n\r\n // Process package like a stylesheet (templates, variables, keys, etc.)\r\n await this.xsltTransformOrStylesheet(context, template, output);\r\n } finally {\r\n // Only end loading if we started it (not if loadAndRegisterPackage did)\r\n if (!wasAlreadyLoading) {\r\n this.packageRegistry.endLoading(packageKey);\r\n }\r\n // Restore previous package context\r\n this.currentPackage = previousPackage;\r\n }\r\n }\r\n\r\n /**\r\n * Loads and registers an external package.\r\n * Creates a temporary context and processes the package document.\r\n * \r\n * @param name The package name/URI.\r\n * @param packageDoc The parsed package document.\r\n * @param version Optional semantic version string.\r\n */\r\n protected async loadAndRegisterPackage(name: string, packageDoc: XNode, version?: string): Promise<void> {\r\n // Detect circular dependencies\r\n const packageKey = version ? `${name}@${version}` : name;\r\n \r\n if (!this.packageRegistry.beginLoading(packageKey)) {\r\n throw new Error(`Circular package dependency detected: \"${packageKey}\".`);\r\n }\r\n\r\n try {\r\n // Find the xsl:package root element\r\n let packageRoot = packageDoc;\r\n if (packageDoc.nodeType === DOM_DOCUMENT_NODE) {\r\n for (const child of packageDoc.childNodes) {\r\n if (child.nodeType === DOM_ELEMENT_NODE && this.isXsltElement(child, 'package')) {\r\n packageRoot = child;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n // Process as package\r\n if (packageRoot && this.isXsltElement(packageRoot, 'package')) {\r\n // Override the name and version if provided\r\n if (name && !xmlGetAttribute(packageRoot, 'name')) {\r\n domSetAttribute(packageRoot, 'name', name);\r\n }\r\n if (version && !xmlGetAttribute(packageRoot, 'package-version')) {\r\n domSetAttribute(packageRoot, 'package-version', version);\r\n }\r\n \r\n // Create a temporary context for processing\r\n const tempContext = new ExprContext([packageRoot]);\r\n \r\n // We don't need output for package registration, just to process the package definition\r\n await this.xsltPackage(tempContext, packageRoot);\r\n } else {\r\n throw new Error('Package document does not contain an xsl:package root element.');\r\n }\r\n } finally {\r\n this.packageRegistry.endLoading(packageKey);\r\n }\r\n }\r\n\r\n /**\r\n * Implements `<xsl:use-package>` (XSLT 3.0 Section 3.7).\r\n * Imports another package and makes its public components available.\r\n * @param context The Expression Context.\r\n * @param template The xsl:use-package element.\r\n * @param output The output node.\r\n */\r\n protected async xsltUsePackage(context: ExprContext, template: XNode, output?: XNode) {\r\n if (!this.currentPackage) {\r\n throw new Error('<xsl:use-package> can only appear as a child of <xsl:package>.');\r\n }\r\n\r\n // Get package reference\r\n const name = xmlGetAttribute(template, 'name');\r\n const packageVersion = xmlGetAttribute(template, 'package-version');\r\n\r\n if (!name) {\r\n throw new Error('<xsl:use-package> requires a \"name\" attribute.');\r\n }\r\n\r\n // Check for circular dependency - if the package is currently being loaded, it's a circular reference\r\n const packageKey = packageVersion ? `${name}@${packageVersion}` : name;\r\n if (this.packageRegistry.isLoading(packageKey)) {\r\n throw new Error(`Circular package dependency detected: \"${packageKey}\".`);\r\n }\r\n\r\n // Try to load the package from registry first\r\n let usedPackage = this.packageRegistry.get(name, packageVersion);\r\n \r\n // If not found and loader exists, try loading\r\n if (!usedPackage && this.packageLoader) {\r\n try {\r\n const packageDoc = await this.packageLoader(name, packageVersion);\r\n if (packageDoc) {\r\n // Parse and register the package\r\n await this.loadAndRegisterPackage(name, packageDoc, packageVersion);\r\n usedPackage = this.packageRegistry.get(name, packageVersion);\r\n }\r\n } catch (error) {\r\n // If this is a circular dependency error, rethrow it\r\n if (error instanceof Error && error.message.includes('Circular package dependency')) {\r\n throw error;\r\n }\r\n // Otherwise, continue to error message below\r\n }\r\n }\r\n \r\n if (!usedPackage) {\r\n throw new Error(\r\n `Package \"${name}\"${packageVersion ? `@${packageVersion}` : ''} not found. ` +\r\n (this.packageLoader ? 'Package loader failed to load the package.' : 'Packages must be loaded before they can be used.')\r\n );\r\n }\r\n\r\n // Create used package entry\r\n const usedPkg: UsedPackageInterface = {\r\n package: usedPackage,\r\n acceptedComponents: new Map()\r\n };\r\n\r\n // Store in current package\r\n const key = packageVersion ? `${name}@${packageVersion}` : name;\r\n this.currentPackage.usedPackages.set(key, usedPkg);\r\n\r\n // Process xsl:accept and xsl:override children\r\n for (const child of template.childNodes) {\r\n if (this.isXsltElement(child, 'accept')) {\r\n this.xsltAccept(context, child);\r\n } else if (this.isXsltElement(child, 'override')) {\r\n await this.xsltOverride(context, child, output);\r\n }\r\n }\r\n\r\n // Register accepted variables in the context\r\n await this.registerAcceptedVariables(context);\r\n\r\n // Refresh function registry so accepted/overridden functions are available\r\n this.registerUserDefinedFunctionsInContext(context);\r\n\r\n // Validate that all abstract components have been overridden (Phase 4.5)\r\n usedPackage.components.forEach((component, key) => {\r\n if (component.visibility === 'abstract') {\r\n const hasOverride = this.currentPackage!.overrides.has(key);\r\n if (!hasOverride) {\r\n throw new Error(\r\n `Abstract component \"${component.name || component.match || key}\" from package \"${name}\" must be overridden.`\r\n );\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Implements `<xsl:expose>` (XSLT 3.0 Section 3.8).\r\n * Marks a component as visible outside the package.\r\n * @param context The Expression Context.\r\n * @param template The xsl:expose element.\r\n */\r\n protected xsltExpose(context: ExprContext, template: XNode) {\r\n if (!this.currentPackage) {\r\n throw new Error('<xsl:expose> can only appear as a child of <xsl:package>.');\r\n }\r\n\r\n // Get exposure attributes\r\n const componentType = xmlGetAttribute(template, 'component') as ComponentType;\r\n const names = xmlGetAttribute(template, 'names');\r\n const visibility = (xmlGetAttribute(template, 'visibility') || 'public') as ComponentVisibility;\r\n\r\n if (!componentType) {\r\n throw new Error('<xsl:expose> requires a \"component\" attribute (template, function, variable, attribute-set, mode).');\r\n }\r\n\r\n // Parse names (can be space-separated list or wildcard '*')\r\n const nameList = names === '*' ? ['*'] : (names ? names.split(/\\s+/) : []);\r\n\r\n if (nameList.length === 0) {\r\n throw new Error('<xsl:expose> requires a \"names\" attribute.');\r\n }\r\n\r\n // Mark components as exposed\r\n // For xsl:expose, we need to find the actual component definitions in the package\r\n // and register them with their actual nodes\r\n for (const name of nameList) {\r\n // Find the actual component in the package root\r\n const actualComponent = this.findComponentInPackageRoot(\r\n this.currentPackage.root,\r\n componentType,\r\n name === '*' ? null : name\r\n );\r\n\r\n if (actualComponent) {\r\n const component: PackageComponentInterface = {\r\n type: componentType,\r\n name: actualComponent.name || (name !== '*' ? name : undefined),\r\n match: actualComponent.match,\r\n mode: actualComponent.mode,\r\n visibility,\r\n overridable: visibility !== 'final',\r\n node: actualComponent.node,\r\n priority: actualComponent.priority\r\n };\r\n\r\n const key = makeComponentKey(component);\r\n this.currentPackage.components.set(key, component);\r\n } else if (name !== '*') {\r\n // Only warn for specific names, not wildcards\r\n // Wildcard might not match anything yet\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Find a component definition in the package root.\r\n * @param packageRoot The package root element\r\n * @param type The component type to find\r\n * @param name The component name (null for all matching type)\r\n * @returns Component information or null if not found\r\n */\r\n private findComponentInPackageRoot(\r\n packageRoot: XNode,\r\n type: ComponentType,\r\n name: string | null\r\n ): { node: XNode; name?: string; match?: string; mode?: string | null; priority?: number } | null {\r\n for (const child of packageRoot.childNodes) {\r\n if (child.nodeType !== DOM_ELEMENT_NODE) {\r\n continue;\r\n }\r\n\r\n // Match by component type\r\n if (type === 'template' && this.isXsltElement(child, 'template')) {\r\n const templateName = xmlGetAttribute(child, 'name');\r\n const match = xmlGetAttribute(child, 'match');\r\n const mode = xmlGetAttribute(child, 'mode');\r\n \r\n // If name is specified, match by name\r\n if (name) {\r\n if (templateName === name) {\r\n return { node: child, name: templateName, match, mode };\r\n }\r\n } else {\r\n // Return first template for wildcard\r\n return { node: child, name: templateName, match, mode };\r\n }\r\n } else if (type === 'function' && this.isXsltElement(child, 'function')) {\r\n const functionName = xmlGetAttribute(child, 'name');\r\n if (!name || functionName === name) {\r\n return { node: child, name: functionName };\r\n }\r\n } else if (type === 'variable' && this.isXsltElement(child, 'variable')) {\r\n const varName = xmlGetAttribute(child, 'name');\r\n if (!name || varName === name) {\r\n return { node: child, name: varName };\r\n }\r\n } else if (type === 'attribute-set' && this.isXsltElement(child, 'attribute-set')) {\r\n const setName = xmlGetAttribute(child, 'name');\r\n if (!name || setName === name) {\r\n return { node: child, name: setName };\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * Implements `<xsl:accept>` (XSLT 3.0 Section 3.9).\r\n * Accepts and optionally overrides a component from a used package.\r\n * @param context The Expression Context.\r\n * @param template The xsl:accept element.\r\n */\r\n protected xsltAccept(context: ExprContext, template: XNode) {\r\n if (!this.currentPackage) {\r\n throw new Error('<xsl:accept> can only appear as a child of <xsl:use-package>.');\r\n }\r\n\r\n // Get accept attributes\r\n const componentType = xmlGetAttribute(template, 'component') as ComponentType;\r\n const names = xmlGetAttribute(template, 'names');\r\n const visibilityOverride = xmlGetAttribute(template, 'visibility') as ComponentVisibility | undefined;\r\n\r\n if (!componentType) {\r\n throw new Error('<xsl:accept> requires a \"component\" attribute.');\r\n }\r\n\r\n if (!names) {\r\n throw new Error('<xsl:accept> requires a \"names\" attribute.');\r\n }\r\n\r\n // Parse names\r\n const nameList = names === '*' ? ['*'] : names.split(/\\s+/);\r\n\r\n // Find the parent xsl:use-package to determine which package we're accepting from\r\n const parentUsePackage = template.parentNode;\r\n if (!parentUsePackage || !this.isXsltElement(parentUsePackage, 'use-package')) {\r\n throw new Error('<xsl:accept> must be a child of <xsl:use-package>.');\r\n }\r\n\r\n const packageName = xmlGetAttribute(parentUsePackage, 'name');\r\n const packageVersion = xmlGetAttribute(parentUsePackage, 'package-version');\r\n const key = packageVersion ? `${packageName}@${packageVersion}` : packageName;\r\n\r\n const usedPkg = this.currentPackage.usedPackages.get(key);\r\n if (!usedPkg) {\r\n throw new Error(`Internal error: used package \"${key}\" not found.`);\r\n }\r\n\r\n // Look up and accept components from the used package\r\n const componentsToAccept = this.findComponentsInPackage(\r\n usedPkg.package,\r\n componentType,\r\n nameList\r\n );\r\n\r\n // Validate and accept each component\r\n for (const component of componentsToAccept) {\r\n // Check if component is visible (not from the same package, so fromPackage = false)\r\n if (!isComponentVisible(component, false)) {\r\n const componentName = component.name || component.match || 'unnamed';\r\n throw new Error(\r\n `Cannot accept private component \"${componentName}\" of type \"${componentType}\" ` +\r\n `from package \"${usedPkg.package.name}\".`\r\n );\r\n }\r\n\r\n // Create accepted component with tracking information\r\n const acceptedComponent: PackageComponentInterface = {\r\n ...component,\r\n sourcePackage: usedPkg.package.name,\r\n isAccepted: true,\r\n effectiveVisibility: visibilityOverride || component.visibility\r\n };\r\n\r\n const componentKey = makeComponentKey(acceptedComponent);\r\n usedPkg.acceptedComponents.set(componentKey, acceptedComponent);\r\n }\r\n }\r\n\r\n /**\r\n * Implements <xsl:override> (XSLT 3.0 Section 3.7.2).\r\n * Overrides components from a used package.\r\n */\r\n protected async xsltOverride(context: ExprContext, template: XNode, output?: XNode) {\r\n if (!this.currentPackage) {\r\n throw new Error('<xsl:override> can only appear as a child of <xsl:use-package>.');\r\n }\r\n\r\n // Validate parent is xsl:use-package\r\n const parentUsePackage = template.parentNode;\r\n if (!parentUsePackage || !this.isXsltElement(parentUsePackage, 'use-package')) {\r\n throw new Error('<xsl:override> must be a child of <xsl:use-package>.');\r\n }\r\n\r\n const packageName = xmlGetAttribute(parentUsePackage, 'name');\r\n const packageVersion = xmlGetAttribute(parentUsePackage, 'package-version');\r\n const key = packageVersion ? `${packageName}@${packageVersion}` : packageName;\r\n\r\n const usedPkg = this.currentPackage.usedPackages.get(key);\r\n if (!usedPkg) {\r\n throw new Error(`Internal error: used package \"${key}\" not found.`);\r\n }\r\n\r\n // Process each child element as an override\r\n for (let i = 0; i < template.childNodes.length; i++) {\r\n const child = template.childNodes[i];\r\n if (child.nodeType !== DOM_ELEMENT_NODE) {\r\n continue;\r\n }\r\n\r\n const localName = child.localName;\r\n \r\n // Determine component type from element name\r\n let componentType: ComponentType | null = null;\r\n let componentName: string | null = null;\r\n let componentMatch: string | null = null;\r\n \r\n switch (localName) {\r\n case 'template':\r\n componentType = 'template';\r\n componentName = xmlGetAttribute(child, 'name');\r\n componentMatch = xmlGetAttribute(child, 'match');\r\n break;\r\n case 'function':\r\n componentType = 'function';\r\n componentName = xmlGetAttribute(child, 'name');\r\n break;\r\n case 'variable':\r\n componentType = 'variable';\r\n componentName = xmlGetAttribute(child, 'name');\r\n break;\r\n case 'attribute-set':\r\n componentType = 'attribute-set';\r\n componentName = xmlGetAttribute(child, 'name');\r\n break;\r\n default:\r\n throw new Error(`<xsl:override> does not support <xsl:${localName}> elements.`);\r\n }\r\n\r\n if (!componentType) {\r\n continue;\r\n }\r\n\r\n // Find the original component in the used package\r\n // Check both accepted components and the package's own components\r\n let originalComponent: PackageComponentInterface | undefined;\r\n \r\n \r\n // First check accepted components (which we explicitly accepted)\r\n usedPkg.acceptedComponents.forEach((component) => {\r\n if (component.type !== componentType) {\r\n return;\r\n }\r\n \r\n // Match by name or match pattern\r\n if (componentName && component.name === componentName) {\r\n originalComponent = component;\r\n } else if (componentMatch && component.match === componentMatch) {\r\n originalComponent = component;\r\n }\r\n });\r\n \r\n // If not found in accepted, check the package components directly\r\n if (!originalComponent) {\r\n usedPkg.package.components.forEach((component) => {\r\n if (component.type !== componentType) {\r\n return;\r\n }\r\n \r\n // Match by name or match pattern\r\n if (componentName && component.name === componentName) {\r\n originalComponent = component;\r\n } else if (componentMatch && component.match === componentMatch) {\r\n originalComponent = component;\r\n }\r\n });\r\n }\r\n\r\n if (!originalComponent) {\r\n const identifier = componentName || componentMatch || 'unnamed';\r\n throw new Error(\r\n `Cannot override component \"${identifier}\" of type \"${componentType}\": ` +\r\n `component not found in package \"${usedPkg.package.name}\".`\r\n );\r\n }\r\n\r\n // Verify it's overridable (not final)\r\n if (!canOverrideComponent(originalComponent)) {\r\n const identifier = componentName || componentMatch || 'unnamed';\r\n throw new Error(\r\n `Cannot override component \"${identifier}\" of type \"${componentType}\": ` +\r\n `component is marked as \"final\" in package \"${usedPkg.package.name}\".`\r\n );\r\n }\r\n\r\n // Create the overriding component\r\n const overridingComponent: PackageComponentInterface = {\r\n type: componentType,\r\n name: componentName || undefined,\r\n match: componentMatch || undefined,\r\n mode: xmlGetAttribute(child, 'mode') || undefined,\r\n visibility: originalComponent.visibility, // Inherit visibility from original\r\n overridable: false, // Overrides cannot themselves be overridden (unless explicitly marked)\r\n node: child,\r\n sourcePackage: this.currentPackage.name,\r\n isAccepted: false,\r\n effectiveVisibility: originalComponent.visibility\r\n };\r\n\r\n // Store reference to original component in the overriding component\r\n // This allows xsl:original to find and call the original\r\n (overridingComponent as any).originalComponent = originalComponent;\r\n (overridingComponent.node as any).__originalComponent = originalComponent;\r\n\r\n // Register the override\r\n const componentKey = makeComponentKey(originalComponent);\r\n this.currentPackage.overrides.set(componentKey, overridingComponent);\r\n\r\n // Register overriding function definitions so they are available to XPath\r\n if (componentType === 'function') {\r\n this.xsltFunction(context, child);\r\n }\r\n\r\n // Do not execute the overriding component during registration.\r\n // It will be selected/executed during transformation when matched.\r\n }\r\n }\r\n\r\n /**\r\n * Find components in a package matching the given criteria.\r\n * Used by xsl:accept to locate components from used packages.\r\n * \r\n * @param pkg The package to search in\r\n * @param componentType The type of component to find\r\n * @param namePatterns Array of name patterns ('*' for all, or specific names)\r\n * @returns Array of matching components\r\n */\r\n private findComponentsInPackage(\r\n pkg: XsltPackageInterface,\r\n componentType: ComponentType,\r\n namePatterns: string[]\r\n ): PackageComponentInterface[] {\r\n const results: PackageComponentInterface[] = [];\r\n const isWildcard = namePatterns.includes('*');\r\n\r\n pkg.components.forEach((component, key) => {\r\n // Filter by component type\r\n if (component.type !== componentType) {\r\n return;\r\n }\r\n\r\n // If wildcard, accept all components of this type\r\n if (isWildcard) {\r\n results.push(component);\r\n return;\r\n }\r\n\r\n // Otherwise, match by name\r\n const componentName = this.getComponentNameForMatching(component);\r\n if (componentName && namePatterns.includes(componentName)) {\r\n results.push(component);\r\n }\r\n });\r\n\r\n return results;\r\n }\r\n\r\n /**\r\n * Get the name to use when matching components.\r\n * For named components (functions, variables, attribute-sets), returns the name.\r\n * For templates, returns the name if present, otherwise returns null (match-based templates).\r\n * \r\n * @param component The component to get the name from\r\n * @returns The component name for matching, or null if unnamed\r\n */\r\n private getComponentNameForMatching(component: PackageComponentInterface): string | null {\r\n switch (component.type) {\r\n case 'function':\r\n case 'variable':\r\n case 'attribute-set':\r\n case 'mode':\r\n return component.name || null;\r\n case 'template':\r\n // Only named templates can be matched by name in xsl:accept\r\n return component.name || null;\r\n default:\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Implements <xsl:original> (XSLT 3.0 Section 3.7.2).\r\n * Calls the original component from within an override.\r\n */\r\n protected async xsltOriginal(context: ExprContext, template: XNode, output?: XNode) {\r\n // Check if we're within an override context\r\n if (!this.currentOverrideContext && this.currentTemplateStack.length > 0) {\r\n const currentTemplate = this.currentTemplateStack[this.currentTemplateStack.length - 1].template;\r\n const templateOverrideContext = (currentTemplate as any).__originalComponent as PackageComponentInterface | undefined;\r\n if (templateOverrideContext) {\r\n this.currentOverrideContext = templateOverrideContext;\r\n }\r\n }\r\n if (!this.currentOverrideContext) {\r\n throw new Error('<xsl:original> can only be used within an overriding component.');\r\n }\r\n\r\n const originalComponent = this.currentOverrideContext;\r\n const originalNode = originalComponent.node;\r\n\r\n // Execute the original component based on its type\r\n switch (originalComponent.type) {\r\n case 'template':\r\n // Execute the original template's children\r\n await this.xsltChildNodes(context, originalNode, output);\r\n break;\r\n \r\n case 'function':\r\n // For functions, xsl:original would be called from within the override function body\r\n // The actual function execution is handled by the function call mechanism\r\n throw new Error('<xsl:original> for functions should be called as a function, not as an element.');\r\n \r\n case 'variable':\r\n // For variables, execute the original variable definition\r\n await this.xsltVariable(context, originalNode, true);\r\n break;\r\n \r\n case 'attribute-set':\r\n // For attribute-sets, apply the original attribute set\r\n if (originalComponent.name && output) {\r\n await this.applyAttributeSets(context, output, originalComponent.name);\r\n }\r\n break;\r\n \r\n default:\r\n throw new Error(`<xsl:original> does not support component type \"${originalComponent.type}\".`);\r\n }\r\n }\r\n\r\n /**\r\n * Implements `<xsl:mode>` (XSLT 3.0 Section 3.5).\r\n * Declares a mode with visibility and other properties.\r\n * Only valid within an xsl:package.\r\n */\r\n protected xsltMode(context: ExprContext, template: XNode): void {\r\n if (!this.currentPackage) {\r\n throw new Error('<xsl:mode> can only appear as a child of <xsl:package>.');\r\n }\r\n\r\n const name = xmlGetAttribute(template, 'name');\r\n if (!name) {\r\n throw new Error('<xsl:mode> requires a \"name\" attribute.');\r\n }\r\n\r\n // Get mode properties\r\n const visibility = (xmlGetAttribute(template, 'visibility') || 'public') as ComponentVisibility;\r\n const streamableAttr = xmlGetAttribute(template, 'streamable');\r\n const onNoMatch = xmlGetAttribute(template, 'on-no-match');\r\n const onMultipleMatch = xmlGetAttribute(template, 'on-multiple-match');\r\n\r\n const streamable = streamableAttr === 'yes';\r\n\r\n // Initialize modes map if not already done\r\n if (!this.currentPackage.modes) {\r\n this.currentPackage.modes = new Map();\r\n }\r\n\r\n // Register the mode with its properties\r\n const modeProperties: ModeProperties = {\r\n name,\r\n visibility,\r\n streamable,\r\n onNoMatch,\r\n onMultipleMatch\r\n };\r\n\r\n this.currentPackage.modes.set(name, modeProperties);\r\n\r\n // Also register as a component for tracking\r\n const componentKey = makeComponentKey({ type: 'mode', name, visibility } as any);\r\n if (!this.currentPackage.components.has(componentKey)) {\r\n this.currentPackage.components.set(componentKey, {\r\n type: 'mode',\r\n name,\r\n visibility,\r\n overridable: false,\r\n node: template\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Get the effective component, checking for overrides first.\r\n * If the component has been overridden in the current package, returns the override.\r\n * Otherwise, returns the original component.\r\n * @param component The original component\r\n * @returns The effective component (override or original)\r\n */\r\n private getEffectiveComponent(component: PackageComponentInterface): PackageComponentInterface {\r\n if (!this.currentPackage) {\r\n return component;\r\n }\r\n\r\n const componentKey = makeComponentKey(component);\r\n const override = this.currentPackage.overrides.get(componentKey);\r\n return override || component;\r\n }\r\n\r\n /**\r\n * Collect templates from accepted components in used packages.\r\n * @param mode The mode to match (null for default mode)\r\n * @returns Array of template priority interfaces\r\n */\r\n private collectAcceptedTemplates(mode: string | null): TemplatePriorityInterface[] {\r\n const templates: TemplatePriorityInterface[] = [];\r\n \r\n if (!this.currentPackage) {\r\n return templates;\r\n }\r\n\r\n // Iterate through all used packages\r\n this.currentPackage.usedPackages.forEach((usedPkg, packageKey) => {\r\n // Look at accepted components\r\n usedPkg.acceptedComponents.forEach((component, componentKey) => {\r\n if (component.type === 'template' && component.isAccepted) {\r\n // Check for overrides - use the effective component\r\n const effectiveComponent = this.getEffectiveComponent(component);\r\n const templateNode = effectiveComponent.node;\r\n \r\n // If this is an override, store the original for xsl:original\r\n const isOverride = effectiveComponent !== component;\r\n const originalForContext = isOverride ? component : undefined;\r\n \r\n // Check if this template matches the requested mode\r\n const templateMode = xmlGetAttribute(templateNode, 'mode') || null;\r\n const effectiveMode = mode || null;\r\n if (effectiveMode !== templateMode) {\r\n return;\r\n }\r\n \r\n // Only include templates with match patterns\r\n const match = xmlGetAttribute(templateNode, 'match');\r\n if (!match) {\r\n return;\r\n }\r\n \r\n // Get priority\r\n const priorityAttr = xmlGetAttribute(templateNode, 'priority');\r\n const explicitPriority = priorityAttr ? parseFloat(priorityAttr) : null;\r\n \r\n // Calculate default priority - use 0 as a safe default for accepted templates\r\n const defaultPriority = component.priority || 0;\r\n const effectivePriority = explicitPriority !== null && !isNaN(explicitPriority)\r\n ? explicitPriority\r\n : defaultPriority;\r\n \r\n templates.push({\r\n template: templateNode,\r\n explicitPriority: explicitPriority !== null && !isNaN(explicitPriority) ? explicitPriority : null,\r\n defaultPriority,\r\n effectivePriority,\r\n importPrecedence: 0, // Accepted templates have neutral precedence\r\n documentOrder: 0,\r\n matchPattern: match,\r\n originalComponent: originalForContext // Store original for xsl:original support\r\n });\r\n }\r\n });\r\n });\r\n\r\n return templates;\r\n }\r\n\r\n /**\r\n * Implements `<xsl:stream>` (XSLT 3.0 Section 16).\r\n * Enables streaming processing of large documents.\r\n * @param context The Expression Context.\r\n * @param template The xsl:stream element.\r\n * @param output The output node.\r\n */\r\n protected async xsltStream(context: ExprContext, template: XNode, output?: XNode) {\r\n // Update streaming processor with current version\r\n this.streamingProcessor.setVersion(this.version);\r\n \r\n // Create child processor callback\r\n const childProcessor: StreamingChildProcessor = {\r\n processChildren: (ctx, tmpl, out) => this.xsltChildNodes(ctx, tmpl, out),\r\n isXsltElement: (node, name) => this.isXsltElement(node, name)\r\n };\r\n \r\n await this.streamingProcessor.processStream(context, template, output, childProcessor);\r\n }\r\n\r\n /**\r\n * Implements `<xsl:fork>` (XSLT 3.0 Section 17).\r\n * Creates multiple independent output branches from the input stream.\r\n * @param context The Expression Context.\r\n * @param template The xsl:fork element.\r\n * @param output The output node.\r\n */\r\n protected async xsltFork(context: ExprContext, template: XNode, output?: XNode) {\r\n // Create child processor callback\r\n const childProcessor: StreamingChildProcessor = {\r\n processChildren: (ctx, tmpl, out) => this.xsltChildNodes(ctx, tmpl, out),\r\n isXsltElement: (node, name) => this.isXsltElement(node, name)\r\n };\r\n \r\n await this.streamingProcessor.processFork(context, template, output, childProcessor);\r\n }\r\n\r\n /**\r\n * Implements `<xsl:merge>` (XSLT 3.0 Section 15).\r\n * Merges multiple sorted input sequences.\r\n * @param context The Expression Context.\r\n * @param template The xsl:merge element.\r\n * @param output The output node.\r\n */\r\n protected async xsltMerge(context: ExprContext, template: XNode, output?: XNode) {\r\n // Update streaming processor with current version\r\n this.streamingProcessor.setVersion(this.version);\r\n \r\n // Create child processor callback\r\n const childProcessor: StreamingChildProcessor = {\r\n processChildren: (ctx, tmpl, out) => this.xsltChildNodes(ctx, tmpl, out),\r\n isXsltElement: (node, name) => this.isXsltElement(node, name)\r\n };\r\n \r\n await this.streamingProcessor.processMerge(context, template, output, childProcessor);\r\n }\r\n\r\n /**\r\n * Implements `xsl:key`.\r\n * @param context The Expression Context.\r\n * @param template The template.\r\n */\r\n protected xsltKey(context: ExprContext, template: XNode) {\r\n // `name`, `match`, and `use` are required.\r\n const name: string = xmlGetAttribute(template, 'name');\r\n const match: string = xmlGetAttribute(template, 'match');\r\n const use: string = xmlGetAttribute(template, 'use');\r\n\r\n if (!name || !match || !use) {\r\n let errorMessage = '<xsl:key> missing required parameters: ';\r\n if (!name) {\r\n errorMessage += 'name, ';\r\n }\r\n\r\n if (!match) {\r\n errorMessage += 'match, ';\r\n }\r\n\r\n if (!use) {\r\n errorMessage += 'use, ';\r\n }\r\n\r\n errorMessage = errorMessage.slice(0, -2);\r\n throw new Error(errorMessage);\r\n }\r\n\r\n let keyContext: ExprContext;\r\n if (context.nodeList[context.position].nodeName === '#document') {\r\n keyContext = context.clone(context.nodeList[context.position].childNodes);\r\n } else {\r\n keyContext = context;\r\n }\r\n\r\n const nodes = this.xsltMatch(match, keyContext);\r\n if (!(name in context.keys)) {\r\n context.keys[name] = {};\r\n }\r\n\r\n for (const node of nodes) {\r\n const nodeContext = context.clone([node]);\r\n const attribute = this.xPath.xPathEval(use, nodeContext);\r\n const attributeValue = attribute.stringValue();\r\n context.keys[name][attributeValue] = new NodeSetValue([node]);\r\n }\r\n }\r\n\r\n /**\r\n * Implements `xsl:message`.\r\n * Outputs a message to the console. If terminate=\"yes\", throws an error to stop processing.\r\n * @param context The Expression Context.\r\n * @param template The `<xsl:message>` node.\r\n */\r\n protected async xsltMessage(context: ExprContext, template: XNode) {\r\n // Build the message content by processing child nodes\r\n const documentFragment = domCreateDocumentFragment(this.outputDocument);\r\n await this.xsltChildNodes(context, template, documentFragment);\r\n const messageText = xmlValue(documentFragment);\r\n\r\n // Check the terminate attribute\r\n const terminate = xmlGetAttribute(template, 'terminate') || 'no';\r\n\r\n // Output the message to console\r\n console.log(`[xsl:message] ${messageText}`);\r\n\r\n // If terminate=\"yes\", stop processing by throwing an error\r\n if (terminate === 'yes') {\r\n throw new Error(`xsl:message terminated: ${messageText}`);\r\n }\r\n }\r\n\r\n /**\r\n * Implements `xsl:namespace-alias`.\r\n * Declares that a namespace URI in the stylesheet should be replaced by a different\r\n * namespace URI in the output.\r\n * @param template The `<xsl:namespace-alias>` node.\r\n */\r\n protected xsltNamespaceAlias(template: XNode) {\r\n const stylesheetPrefix = xmlGetAttribute(template, 'stylesheet-prefix');\r\n const resultPrefix = xmlGetAttribute(template, 'result-prefix');\r\n\r\n if (!stylesheetPrefix || !resultPrefix) {\r\n throw new Error('<xsl:namespace-alias> requires both stylesheet-prefix and result-prefix attributes.');\r\n }\r\n\r\n // Store the alias mapping\r\n // \"#default\" represents the default namespace (no prefix)\r\n this.namespaceAliases.set(stylesheetPrefix, resultPrefix);\r\n }\r\n\r\n /**\r\n * Implements `xsl:number`.\r\n * Inserts a formatted number into the result tree.\r\n * @param context The Expression Context.\r\n * @param template The `<xsl:number>` node.\r\n * @param output The output node.\r\n */\r\n protected xsltNumber(context: ExprContext, template: XNode, output?: XNode) {\r\n const value = xmlGetAttribute(template, 'value');\r\n const level = xmlGetAttribute(template, 'level') || 'single';\r\n const count = xmlGetAttribute(template, 'count');\r\n const from = xmlGetAttribute(template, 'from');\r\n const format = xmlGetAttribute(template, 'format') || '1';\r\n const lang = xmlGetAttribute(template, 'lang');\r\n const letterValue = xmlGetAttribute(template, 'letter-value');\r\n const groupingSeparator = xmlGetAttribute(template, 'grouping-separator');\r\n const groupingSize = xmlGetAttribute(template, 'grouping-size');\r\n\r\n let numbers: number[];\r\n\r\n if (value) {\r\n // If value attribute is present, evaluate it as an XPath expression\r\n const result = this.xPath.xPathEval(value, context);\r\n numbers = [Math.round(result.numberValue())];\r\n } else {\r\n // Otherwise, count nodes based on level, count, and from attributes\r\n numbers = this.xsltNumberCount(context, level, count, from);\r\n }\r\n\r\n // Format the numbers (handles both single and multiple levels)\r\n const formattedNumber = this.xsltFormatNumbers(numbers, format, groupingSeparator, groupingSize);\r\n\r\n // Create text node with the formatted number\r\n const textNode = domCreateTextNode(this.outputDocument, formattedNumber);\r\n const targetOutput = output || this.outputDocument;\r\n textNode.siblingPosition = targetOutput.childNodes.length;\r\n domAppendChild(targetOutput, textNode);\r\n }\r\n\r\n /**\r\n * Counts nodes for xsl:number based on level, count, and from attributes.\r\n * @param context The Expression Context.\r\n * @param level The counting level: 'single', 'multiple', or 'any'.\r\n * @param count Pattern to match nodes to count.\r\n * @param from Pattern to define counting boundary.\r\n * @returns Array of count values (single element for 'single'/'any', multiple for 'multiple').\r\n */\r\n protected xsltNumberCount(context: ExprContext, level: string, count: string | null, from: string | null): number[] {\r\n const currentNode = context.nodeList[context.position];\r\n\r\n // Default count pattern matches nodes with the same name and type as current node\r\n const countPattern = count || currentNode.nodeName;\r\n\r\n switch (level) {\r\n case 'single': {\r\n // Find the first ancestor-or-self that matches count pattern\r\n // If from is specified, stop at the from boundary\r\n let node: XNode | null = currentNode;\r\n while (node) {\r\n if (this.nodeMatchesPattern(node, countPattern)) {\r\n // Count preceding siblings (plus 1 for self) that match\r\n let num = 1;\r\n let sibling = node.previousSibling;\r\n while (sibling) {\r\n if (this.nodeMatchesPattern(sibling, countPattern)) {\r\n num++;\r\n }\r\n sibling = sibling.previousSibling;\r\n }\r\n return [num];\r\n }\r\n // Check if we've hit the from boundary\r\n if (from && this.nodeMatchesPattern(node, from)) {\r\n break;\r\n }\r\n node = node.parentNode;\r\n }\r\n return [0];\r\n }\r\n case 'multiple': {\r\n // Build hierarchical number by walking up ancestor chain\r\n // Each level counts position among siblings matching count pattern\r\n const numbers: number[] = [];\r\n let node: XNode | null = currentNode;\r\n\r\n // First, collect all ancestors matching count pattern (up to from boundary)\r\n const matchingAncestors: XNode[] = [];\r\n while (node) {\r\n if (this.nodeMatchesPattern(node, countPattern)) {\r\n matchingAncestors.push(node);\r\n }\r\n // Check if we've hit the from boundary\r\n if (from && this.nodeMatchesPattern(node, from)) {\r\n break;\r\n }\r\n node = node.parentNode;\r\n }\r\n\r\n // Process from outermost to innermost (reverse order)\r\n for (let i = matchingAncestors.length - 1; i >= 0; i--) {\r\n const ancestor = matchingAncestors[i];\r\n let num = 1;\r\n let sibling = ancestor.previousSibling;\r\n while (sibling) {\r\n if (this.nodeMatchesPattern(sibling, countPattern)) {\r\n num++;\r\n }\r\n sibling = sibling.previousSibling;\r\n }\r\n numbers.push(num);\r\n }\r\n\r\n return numbers.length > 0 ? numbers : [0];\r\n }\r\n case 'any': {\r\n // Count all preceding nodes in document order that match\r\n // If from is specified, only count nodes after the from boundary\r\n let num = 0;\r\n const allNodes = this.getAllPrecedingNodes(currentNode, from);\r\n\r\n // Count self if it matches\r\n if (this.nodeMatchesPattern(currentNode, countPattern)) {\r\n num = 1;\r\n }\r\n\r\n for (const node of allNodes) {\r\n if (this.nodeMatchesPattern(node, countPattern)) {\r\n num++;\r\n }\r\n }\r\n return [num];\r\n }\r\n default:\r\n return [1];\r\n }\r\n }\r\n\r\n /**\r\n * Checks if a node matches a pattern (supports simple names and union patterns).\r\n * @param node The node to check.\r\n * @param pattern The pattern (node name, wildcard, or union like \"a|b|c\").\r\n * @returns True if the node matches.\r\n */\r\n protected nodeMatchesPattern(node: XNode, pattern: string): boolean {\r\n // Handle union patterns (e.g., \"chapter|section|para\")\r\n if (pattern.includes('|')) {\r\n const alternatives = pattern.split('|').map(p => p.trim());\r\n return alternatives.some(alt => this.nodeMatchesSinglePattern(node, alt));\r\n }\r\n return this.nodeMatchesSinglePattern(node, pattern);\r\n }\r\n\r\n /**\r\n * Checks if a node matches a single (non-union) pattern.\r\n * @param node The node to check.\r\n * @param pattern The pattern (node name or wildcard).\r\n * @returns True if the node matches.\r\n */\r\n protected nodeMatchesSinglePattern(node: XNode, pattern: string): boolean {\r\n if (pattern === '*') {\r\n return node.nodeType === DOM_ELEMENT_NODE;\r\n }\r\n if (pattern === 'node()') {\r\n return true;\r\n }\r\n if (pattern === 'text()') {\r\n return node.nodeType === DOM_TEXT_NODE;\r\n }\r\n if (pattern === 'comment()') {\r\n return node.nodeType === DOM_COMMENT_NODE;\r\n }\r\n if (pattern.startsWith('processing-instruction')) {\r\n return node.nodeType === DOM_PROCESSING_INSTRUCTION_NODE;\r\n }\r\n return node.nodeName === pattern || node.localName === pattern;\r\n }\r\n\r\n /**\r\n * Gets all nodes preceding the given node in document order.\r\n * @param node The reference node.\r\n * @param fromPattern Optional pattern to define counting boundary.\r\n * @returns Array of preceding nodes.\r\n */\r\n protected getAllPrecedingNodes(node: XNode, fromPattern: string | null = null): XNode[] {\r\n const result: XNode[] = [];\r\n\r\n // Get preceding siblings\r\n let sibling = node.previousSibling;\r\n while (sibling) {\r\n // Check if we've hit the from boundary\r\n if (fromPattern && this.nodeMatchesPattern(sibling, fromPattern)) {\r\n // Include descendants after the from boundary element\r\n this.collectDescendants(sibling, result);\r\n return result;\r\n }\r\n result.push(sibling);\r\n // Add descendants of preceding siblings\r\n this.collectDescendants(sibling, result);\r\n sibling = sibling.previousSibling;\r\n }\r\n\r\n // Get ancestors' preceding siblings\r\n let parent = node.parentNode;\r\n while (parent) {\r\n // Check if parent matches from pattern (stop here)\r\n if (fromPattern && this.nodeMatchesPattern(parent, fromPattern)) {\r\n return result;\r\n }\r\n\r\n let parentSibling = parent.previousSibling;\r\n while (parentSibling) {\r\n // Check if we've hit the from boundary\r\n if (fromPattern && this.nodeMatchesPattern(parentSibling, fromPattern)) {\r\n this.collectDescendants(parentSibling, result);\r\n return result;\r\n }\r\n result.push(parentSibling);\r\n this.collectDescendants(parentSibling, result);\r\n parentSibling = parentSibling.previousSibling;\r\n }\r\n parent = parent.parentNode;\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Collects all descendant nodes of a given node.\r\n * @param node The parent node.\r\n * @param result The array to collect into.\r\n */\r\n protected collectDescendants(node: XNode, result: XNode[]): void {\r\n for (const child of node.childNodes) {\r\n if (child.nodeType === DOM_ELEMENT_NODE) {\r\n result.push(child);\r\n this.collectDescendants(child, result);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Formats an array of numbers according to the format string.\r\n * For level=\"multiple\", numbers like [1, 2, 3] with format \"1.1.1\" produce \"1.2.3\".\r\n * @param numbers The numbers to format.\r\n * @param format The format string (e.g., \"1\", \"1.1\", \"1.a.i\").\r\n * @param groupingSeparator Optional grouping separator.\r\n * @param groupingSize Optional grouping size.\r\n * @returns The formatted number string.\r\n */\r\n protected xsltFormatNumbers(\r\n numbers: number[],\r\n format: string,\r\n groupingSeparator: string | null,\r\n groupingSize: string | null\r\n ): string {\r\n if (numbers.length === 0) return '0';\r\n\r\n // Parse the format string to extract format tokens and separators\r\n // Format like \"1.a.i\" has tokens [\"1\", \"a\", \"i\"] with separator \".\"\r\n const { tokens, separators } = this.parseFormatString(format);\r\n\r\n const formattedParts: string[] = [];\r\n for (let i = 0; i < numbers.length; i++) {\r\n // Use corresponding token, or last token if we run out\r\n const tokenIndex = Math.min(i, tokens.length - 1);\r\n const token = tokens[tokenIndex] || '1';\r\n const formatted = this.xsltFormatNumber(numbers[i], token, groupingSeparator, groupingSize);\r\n formattedParts.push(formatted);\r\n }\r\n\r\n // Join with separators\r\n if (formattedParts.length === 1) {\r\n return formattedParts[0];\r\n }\r\n\r\n let result = formattedParts[0];\r\n for (let i = 1; i < formattedParts.length; i++) {\r\n // Use corresponding separator, or last separator if we run out\r\n const sepIndex = Math.min(i - 1, separators.length - 1);\r\n const sep = separators.length > 0 ? separators[sepIndex] : '.';\r\n result += sep + formattedParts[i];\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Parses a format string into tokens and separators.\r\n * E.g., \"1.a.i\" -> tokens: [\"1\", \"a\", \"i\"], separators: [\".\", \".\"]\r\n * @param format The format string.\r\n * @returns Object with tokens and separators arrays.\r\n */\r\n protected parseFormatString(format: string): { tokens: string[]; separators: string[] } {\r\n const tokens: string[] = [];\r\n const separators: string[] = [];\r\n\r\n // Format tokens are: 1, 01, 001, a, A, i, I, or sequences like 0001\r\n // Everything else is a separator\r\n const tokenRegex = /^(0*1|[aAiI])/;\r\n let remaining = format;\r\n let lastWasToken = false;\r\n\r\n while (remaining.length > 0) {\r\n const match = remaining.match(tokenRegex);\r\n if (match) {\r\n tokens.push(match[1]);\r\n remaining = remaining.substring(match[1].length);\r\n lastWasToken = true;\r\n } else {\r\n // This character is a separator\r\n if (lastWasToken && tokens.length > 0) {\r\n // Find separator until next token or end\r\n let sepEnd = 1;\r\n while (sepEnd < remaining.length && !remaining.substring(sepEnd).match(tokenRegex)) {\r\n sepEnd++;\r\n }\r\n separators.push(remaining.substring(0, sepEnd));\r\n remaining = remaining.substring(sepEnd);\r\n } else {\r\n // Leading separator or continuation - skip one char\r\n remaining = remaining.substring(1);\r\n }\r\n lastWasToken = false;\r\n }\r\n }\r\n\r\n // Default to \"1\" if no tokens found\r\n if (tokens.length === 0) {\r\n tokens.push('1');\r\n }\r\n\r\n // Default separator is \".\"\r\n if (separators.length === 0 && tokens.length > 1) {\r\n for (let i = 1; i < tokens.length; i++) {\r\n separators.push('.');\r\n }\r\n }\r\n\r\n return { tokens, separators };\r\n }\r\n\r\n /**\r\n * Formats a number according to the format string.\r\n * @param number The number to format.\r\n * @param format The format string (e.g., \"1\", \"01\", \"a\", \"A\", \"i\", \"I\").\r\n * @param groupingSeparator Optional grouping separator.\r\n * @param groupingSize Optional grouping size.\r\n * @returns The formatted number string.\r\n */\r\n protected xsltFormatNumber(\r\n number: number,\r\n format: string,\r\n groupingSeparator: string | null,\r\n groupingSize: string | null\r\n ): string {\r\n if (format.match(/^0+1$/)) {\r\n const width = format.length;\r\n let result = number.toString().padStart(width, '0');\r\n if (groupingSeparator && groupingSize) {\r\n const size = parseInt(groupingSize, 10);\r\n if (size > 0 && !isNaN(size)) {\r\n result = this.applyGrouping(result, groupingSeparator, size);\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n // Handle different format tokens\r\n const formatChar = format.charAt(0);\r\n\r\n let result: string;\r\n\r\n switch (formatChar) {\r\n case '1':\r\n result = number.toString();\r\n // Handle zero-padding (e.g., \"01\" -> \"01\", \"02\", etc.)\r\n if (format.length > 1 && format.match(/^0+1$/)) {\r\n const width = format.length;\r\n result = number.toString().padStart(width, '0');\r\n }\r\n break;\r\n case 'a':\r\n // Lowercase alphabetic: a, b, c, ..., z, aa, ab, ...\r\n result = this.numberToAlpha(number, false);\r\n break;\r\n case 'A':\r\n // Uppercase alphabetic: A, B, C, ..., Z, AA, AB, ...\r\n result = this.numberToAlpha(number, true);\r\n break;\r\n case 'i':\r\n // Lowercase Roman numerals\r\n result = this.numberToRoman(number).toLowerCase();\r\n break;\r\n case 'I':\r\n // Uppercase Roman numerals\r\n result = this.numberToRoman(number);\r\n break;\r\n default:\r\n result = number.toString();\r\n }\r\n\r\n // Apply grouping if specified\r\n if (groupingSeparator && groupingSize) {\r\n const size = parseInt(groupingSize, 10);\r\n if (size > 0 && !isNaN(size)) {\r\n result = this.applyGrouping(result, groupingSeparator, size);\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Converts a number to alphabetic representation.\r\n * @param number The number to convert.\r\n * @param uppercase Whether to use uppercase letters.\r\n * @returns The alphabetic representation.\r\n */\r\n protected numberToAlpha(number: number, uppercase: boolean): string {\r\n if (number <= 0) return '';\r\n\r\n let result = '';\r\n while (number > 0) {\r\n number--;\r\n result = String.fromCharCode((number % 26) + (uppercase ? 65 : 97)) + result;\r\n number = Math.floor(number / 26);\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Converts a number to Roman numeral representation.\r\n * @param number The number to convert.\r\n * @returns The Roman numeral string.\r\n */\r\n protected numberToRoman(number: number): string {\r\n if (number <= 0 || number > 3999) return number.toString();\r\n\r\n const romanNumerals: [number, string][] = [\r\n [1000, 'M'], [900, 'CM'], [500, 'D'], [400, 'CD'],\r\n [100, 'C'], [90, 'XC'], [50, 'L'], [40, 'XL'],\r\n [10, 'X'], [9, 'IX'], [5, 'V'], [4, 'IV'], [1, 'I']\r\n ];\r\n\r\n let result = '';\r\n for (const [value, numeral] of romanNumerals) {\r\n while (number >= value) {\r\n result += numeral;\r\n number -= value;\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Applies grouping separators to a numeric string.\r\n * @param numStr The numeric string.\r\n * @param separator The grouping separator.\r\n * @param size The grouping size.\r\n * @returns The grouped string.\r\n */\r\n protected applyGrouping(numStr: string, separator: string, size: number): string {\r\n // Only apply to the integer part\r\n const parts = numStr.split('.');\r\n let intPart = parts[0];\r\n const decPart = parts[1];\r\n\r\n // Apply grouping from right to left\r\n let result = '';\r\n let count = 0;\r\n for (let i = intPart.length - 1; i >= 0; i--) {\r\n if (count > 0 && count % size === 0) {\r\n result = separator + result;\r\n }\r\n result = intPart[i] + result;\r\n count++;\r\n }\r\n\r\n return decPart ? result + '.' + decPart : result;\r\n }\r\n\r\n /**\r\n * Orders the current node list in the input context according to the\r\n * sort order specified by xsl:sort child nodes of the current\r\n * template node. This happens before the operation specified by the\r\n * current template node is executed.\r\n * @param context The expression context.\r\n * @param template The template node.\r\n * @todo case-order is not implemented.\r\n */\r\n protected xsltSort(context: ExprContext, template: XNode) {\r\n const sort: any[] = [];\r\n\r\n for (const childNode of template.childNodes) {\r\n if (childNode.nodeType == DOM_ELEMENT_NODE && this.isXsltElement(childNode, 'sort')) {\r\n const select = xmlGetAttribute(childNode, 'select');\r\n const expression = this.xPath.xPathParse(select);\r\n const type = xmlGetAttribute(childNode, 'data-type') || 'text';\r\n const order = xmlGetAttribute(childNode, 'order') || 'ascending';\r\n sort.push({\r\n expr: expression,\r\n type,\r\n order\r\n });\r\n }\r\n }\r\n\r\n this.xPath.xPathSort(context, sort);\r\n }\r\n\r\n private resolveNamespaceUriForPrefix(node: XNode, prefix: string | null): string | null {\r\n const attrName = prefix ? `xmlns:${prefix}` : 'xmlns';\r\n let current: XNode | null = node;\r\n\r\n while (current) {\r\n const attributes = current.childNodes.filter(\r\n (child) => child.nodeType === DOM_ATTRIBUTE_NODE\r\n );\r\n for (const attribute of attributes) {\r\n if (attribute.nodeName === attrName) {\r\n return attribute.nodeValue;\r\n }\r\n\r\n if (prefix && attribute.prefix === 'xmlns' && attribute.localName === prefix) {\r\n return attribute.nodeValue;\r\n }\r\n\r\n if (!prefix && attribute.nodeName === 'xmlns') {\r\n return attribute.nodeValue;\r\n }\r\n }\r\n current = current.parentNode;\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private isNamespaceDeclaredOnAncestor(node: XNode, nsAttr: string, nsUri: string): boolean {\r\n let current: XNode | null = node;\r\n while (current) {\r\n const value = domGetAttributeValue(current, nsAttr);\r\n if (value === nsUri) {\r\n return true;\r\n }\r\n current = current.parentNode;\r\n }\r\n return false;\r\n }\r\n\r\n private parseWhitespacePattern(pattern: string, template: XNode): WhitespacePattern {\r\n if (pattern === '*') {\r\n return { namespaceUri: null, localName: '*', isWildcard: true };\r\n }\r\n\r\n if (pattern.includes(':')) {\r\n const [prefix, localPart] = pattern.split(':');\r\n const namespaceUri = this.resolveNamespaceUriForPrefix(template, prefix);\r\n return {\r\n namespaceUri: namespaceUri ?? null,\r\n localName: localPart || '*',\r\n isWildcard: localPart === '*'\r\n };\r\n }\r\n\r\n return { namespaceUri: null, localName: pattern, isWildcard: false };\r\n }\r\n\r\n /**\r\n * Implements `xsl:strip-space`.\r\n * Collects element name patterns for which whitespace-only text nodes should be stripped.\r\n * @param template The `<xsl:strip-space>` node.\r\n */\r\n protected xsltStripSpace(template: XNode) {\r\n const elements = xmlGetAttribute(template, 'elements');\r\n if (elements) {\r\n // Split on whitespace to get individual patterns (e.g., \"* book\" becomes [\"*\", \"book\"])\r\n const patterns = elements.trim().split(/\\s+/);\r\n for (const pattern of patterns) {\r\n this.stripSpacePatterns.push(this.parseWhitespacePattern(pattern, template));\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Implements `xsl:preserve-space`.\r\n * Collects element name patterns for which whitespace-only text nodes should be preserved.\r\n * preserve-space takes precedence over strip-space for matching elements.\r\n * @param template The `<xsl:preserve-space>` node.\r\n */\r\n protected xsltPreserveSpace(template: XNode) {\r\n const elements = xmlGetAttribute(template, 'elements');\r\n if (elements) {\r\n // Split on whitespace to get individual patterns (e.g., \"pre code\" becomes [\"pre\", \"code\"])\r\n const patterns = elements.trim().split(/\\s+/);\r\n for (const pattern of patterns) {\r\n this.preserveSpacePatterns.push(this.parseWhitespacePattern(pattern, template));\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Determines if a text node from the input document should be stripped.\r\n * This applies xsl:strip-space and xsl:preserve-space rules to whitespace-only text nodes.\r\n * @param textNode The text node to check.\r\n * @returns True if the text node should be stripped (not included in output).\r\n */\r\n protected shouldStripWhitespaceNode(textNode: XNode): boolean {\r\n // Only strip whitespace-only text nodes\r\n if (!textNode.nodeValue || !textNode.nodeValue.match(/^\\s*$/)) {\r\n return false;\r\n }\r\n\r\n // If no strip-space patterns are defined, don't strip\r\n if (this.stripSpacePatterns.length === 0) {\r\n return false;\r\n }\r\n\r\n const parentElement = textNode.parentNode;\r\n if (!parentElement || parentElement.nodeType !== DOM_ELEMENT_NODE) {\r\n return false;\r\n }\r\n\r\n // Check for xml:space=\"preserve\" on parent or ancestors (highest precedence)\r\n let ancestor = parentElement;\r\n while (ancestor && ancestor.nodeType === DOM_ELEMENT_NODE) {\r\n const xmlspace = domGetAttributeValue(ancestor, 'xml:space');\r\n if (xmlspace === 'preserve') {\r\n return false;\r\n }\r\n if (xmlspace === 'default') {\r\n break; // Continue to check strip-space/preserve-space rules\r\n }\r\n ancestor = ancestor.parentNode;\r\n }\r\n\r\n const parentName = parentElement.localName || parentElement.nodeName;\r\n\r\n // Check preserve-space patterns first (they take precedence over strip-space)\r\n for (const pattern of this.preserveSpacePatterns) {\r\n if (this.matchesNamePattern(parentName, pattern, parentElement)) {\r\n return false;\r\n }\r\n }\r\n\r\n // Check strip-space patterns\r\n for (const pattern of this.stripSpacePatterns) {\r\n if (this.matchesNamePattern(parentName, pattern, parentElement)) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Matches an element name against a strip-space/preserve-space pattern.\r\n * Supports:\r\n * - \"*\" matches any element\r\n * - \"prefix:*\" matches any element in a namespace\r\n * - \"name\" matches elements with that local name\r\n * - \"prefix:name\" matches elements with that QName\r\n * @param elementName The local name of the element.\r\n * @param pattern The pattern to match against.\r\n * @param element The element node (for namespace checking).\r\n * @returns True if the element matches the pattern.\r\n */\r\n protected matchesNamePattern(\r\n elementName: string,\r\n pattern: WhitespacePattern,\r\n element: XNode\r\n ): boolean {\r\n const elementNamespace =\r\n element.namespaceUri ?? this.resolveNamespaceUriForPrefix(element, element.prefix || null);\r\n\r\n if (pattern.namespaceUri !== null) {\r\n if (elementNamespace !== pattern.namespaceUri) {\r\n return false;\r\n }\r\n } else if (!pattern.isWildcard && elementNamespace) {\r\n return false;\r\n }\r\n\r\n if (pattern.isWildcard) {\r\n return true;\r\n }\r\n\r\n return elementName === pattern.localName;\r\n }\r\n\r\n /**\r\n * Implements `xsl:template`.\r\n * @param context The Expression Context.\r\n * @param template The `<xsl:template>` node.\r\n * @param output The output. In general, a fragment that will be used by \r\n * the caller.\r\n */\r\n protected async xsltTemplate(context: ExprContext, template: XNode, output?: XNode) {\r\n // If `<xsl:template>` is executed outside `<xsl:apply-templates>`,\r\n // only one match is accepted per level (or per context here).\r\n if (!context.inApplyTemplates && context.baseTemplateMatched) {\r\n return;\r\n }\r\n\r\n const match = xmlGetAttribute(template, 'match');\r\n if (!match) return;\r\n\r\n // XPath doesn't have an axis to select \"self and siblings\", and\r\n // the default axis is \"child\", so to select the correct children\r\n // in relative path, we force a 'self-and-siblings' axis.\r\n const nodes = this.xsltMatch(match, context, 'self-and-siblings');\r\n if (nodes.length > 0) {\r\n this.firstTemplateRan = true;\r\n if (!context.inApplyTemplates) {\r\n context.baseTemplateMatched = true;\r\n }\r\n\r\n const templateContext = context.clone(nodes, 0);\r\n await this.xsltChildNodes(templateContext, template, output);\r\n }\r\n }\r\n\r\n protected xsltText(context: ExprContext, template: XNode, output?: XNode) {\r\n const text = xmlValue(template);\r\n const node = domCreateTextNode(this.outputDocument, text);\r\n // Mark this node as coming from xsl:text so it won't be trimmed during serialization\r\n node.fromXslText = true;\r\n const disableOutputEscaping = template.childNodes.filter(\r\n (a) => a.nodeType === DOM_ATTRIBUTE_NODE && a.nodeName === 'disable-output-escaping'\r\n );\r\n if (disableOutputEscaping.length > 0 && disableOutputEscaping[0].nodeValue === 'yes') {\r\n node.escape = false;\r\n }\r\n const destinationTextNode = output || this.outputDocument;\r\n // Set siblingPosition to preserve insertion order during serialization\r\n node.siblingPosition = destinationTextNode.childNodes.length;\r\n destinationTextNode.appendChild(node);\r\n }\r\n\r\n /**\r\n * Validates XSLT stylesheet/transform attributes.\r\n * According to XSLT specification, validates:\r\n * - Required version attribute\r\n * - Valid version values (1.0, 2.0, 3.0)\r\n * - Valid namespace declarations\r\n * - Valid values for optional attributes (extension-element-prefixes, exclude-result-prefixes)\r\n * @param stylesheetElement The `<xsl:stylesheet>` or `<xsl:transform>` element to validate.\r\n * @param context The Expression Context for namespace access.\r\n */\r\n protected validateStylesheetAttributes(stylesheetElement: XNode, context: ExprContext): void {\r\n const attributes = stylesheetElement.childNodes.filter((n) => n.nodeType === DOM_ATTRIBUTE_NODE);\r\n const validAttributes = ['version', 'id', 'extension-element-prefixes', 'exclude-result-prefixes', 'default-collation'];\r\n const validNamespaceAttributes = ['xmlns']; // xmlns and xmlns:* attributes\r\n \r\n let versionFound = false;\r\n\r\n for (let attribute of attributes) {\r\n const nodeName = attribute.nodeName;\r\n const nodeValue = attribute.nodeValue;\r\n\r\n // Check if it's a namespace declaration\r\n if (attribute.prefix === 'xmlns') {\r\n // xmlns:prefix namespace declarations are valid\r\n context.knownNamespaces[attribute.localName] = nodeValue;\r\n continue;\r\n }\r\n\r\n // Check if it's the default namespace declaration\r\n if (nodeName === 'xmlns') {\r\n context.knownNamespaces[''] = nodeValue;\r\n continue;\r\n }\r\n\r\n // Handle version attribute (XSLT 1.0 Section 2.5)\r\n if (nodeName === 'version') {\r\n versionFound = true;\r\n\r\n // Parse version as a number for comparison\r\n const versionNum = parseFloat(nodeValue);\r\n\r\n if (isNaN(versionNum) || versionNum <= 0) {\r\n throw new Error(\r\n `XSLT version not defined or invalid. Actual resolved version: ${nodeValue || '(none)'}.`\r\n );\r\n }\r\n\r\n // XSLT 1.0 Section 2.5: Forwards-Compatible Processing\r\n // If the version is greater than what we support (1.0), enter forwards-compatible mode\r\n // This allows stylesheets written for future versions to be processed with graceful fallback\r\n if (versionNum > 1.0 && !['2.0', '3.0'].includes(nodeValue)) {\r\n this.forwardsCompatible = true;\r\n // Treat as 1.0 for processing but remember original version\r\n this.version = nodeValue;\r\n context.xsltVersion = '1.0';\r\n this.warningsCallback(\r\n `XSLT Warning: Stylesheet version \"${nodeValue}\" is not directly supported. ` +\r\n `Entering forwards-compatible processing mode (XSLT 1.0 Section 2.5).`\r\n );\r\n } else {\r\n this.version = nodeValue;\r\n context.xsltVersion = nodeValue as any;\r\n }\r\n continue;\r\n }\r\n\r\n // Validate extension-element-prefixes attribute\r\n if (nodeName === 'extension-element-prefixes') {\r\n // Should be a whitespace-separated list of namespace prefixes\r\n // Validate that prefixes are valid NCNames (basic check)\r\n const prefixes = nodeValue.split(/\\s+/);\r\n for (const prefix of prefixes) {\r\n if (prefix && !/^[a-zA-Z_:][\\w:.-]*$/.test(prefix)) {\r\n throw new Error(`Invalid prefix in extension-element-prefixes: \"${prefix}\". Prefixes must be valid QNames.`);\r\n }\r\n }\r\n continue;\r\n }\r\n\r\n // Validate exclude-result-prefixes attribute\r\n if (nodeName === 'exclude-result-prefixes') {\r\n // Should be a whitespace-separated list of namespace prefixes\r\n // Special value \"#all\" is allowed\r\n if (nodeValue !== '#all') {\r\n const prefixes = nodeValue.split(/\\s+/);\r\n for (const prefix of prefixes) {\r\n if (prefix && !/^[a-zA-Z_:][\\w:.-]*$/.test(prefix)) {\r\n throw new Error(`Invalid prefix in exclude-result-prefixes: \"${prefix}\". Prefixes must be valid QNames or \"#all\".`);\r\n }\r\n }\r\n }\r\n continue;\r\n }\r\n\r\n // Validate default-collation attribute (XSLT 2.0+)\r\n if (nodeName === 'default-collation') {\r\n // Should be a URI, basic validation\r\n if (!nodeValue || nodeValue.trim().length === 0) {\r\n throw new Error('The default-collation attribute must contain a URI.');\r\n }\r\n continue;\r\n }\r\n\r\n // Validate id attribute\r\n if (nodeName === 'id') {\r\n // id must be an XML NCName\r\n if (!/^[a-zA-Z_:][\\w:.-]*$/.test(nodeValue)) {\r\n throw new Error(`Invalid id attribute value: \"${nodeValue}\". IDs must be valid NCNames.`);\r\n }\r\n continue;\r\n }\r\n\r\n // If attribute is not a known XSLT attribute and not a namespace declaration, it might be valid\r\n // (like an attribute with a non-XSLT namespace), so we don't throw an error for unknown attributes\r\n }\r\n\r\n // Note: version attribute is optional in XSLT if a default version is defined in the system\r\n // However, it's strongly recommended, and we already validate it if provided\r\n }\r\n\r\n /**\r\n * Implements `<xsl:stylesheet>` and `<xsl:transform>`, and its corresponding\r\n * validations.\r\n * @param context The Expression Context.\r\n * @param template The `<xsl:stylesheet>` or `<xsl:transform>` node.\r\n * @param output The output. In general, a fragment that will be used by\r\n * the caller.\r\n */\r\n protected async xsltTransformOrStylesheet(context: ExprContext, template: XNode, output?: XNode): Promise<void> {\r\n // Map templates from the main stylesheet (depth 0)\r\n const mainStylesheetMetadata: StylesheetMetadata = {\r\n importDepth: 0,\r\n href: '(main stylesheet)',\r\n order: 0\r\n };\r\n this.mapTemplatesFromStylesheet(template, mainStylesheetMetadata);\r\n \r\n // Collect attribute sets from stylesheet at the beginning\r\n this.collectAttributeSets(template);\r\n\r\n // Collect user-defined functions from stylesheet\r\n this.collectUserDefinedFunctions(template, context);\r\n\r\n // Register user-defined functions in context so they're available to XPath\r\n this.registerUserDefinedFunctionsInContext(context);\r\n\r\n // Validate stylesheet attributes\r\n this.validateStylesheetAttributes(template, context);\r\n\r\n // Validate that xsl:import elements are the first children (before any other elements)\r\n let importsDone = false;\r\n for (const child of template.childNodes) {\r\n if (child.nodeType === DOM_ELEMENT_NODE) {\r\n if (this.isXsltElement(child, 'import')) {\r\n if (importsDone) {\r\n throw new Error('<xsl:import> should be the first child node of <xsl:stylesheet> or <xsl:transform>.');\r\n }\r\n } else {\r\n importsDone = true;\r\n }\r\n }\r\n }\r\n\r\n // Separate templates from other stylesheet children (output, variable, key, etc.)\r\n const nonTemplates: XNode[] = [];\r\n const templates: XNode[] = [];\r\n\r\n for (const child of template.childNodes) {\r\n if (child.nodeType === DOM_ELEMENT_NODE && this.isXsltElement(child, 'template')) {\r\n templates.push(child);\r\n } else {\r\n nonTemplates.push(child);\r\n }\r\n }\r\n\r\n // Process non-template children first (declarations like output, variable, key, etc.)\r\n const contextClone = context.clone();\r\n for (const child of nonTemplates) {\r\n await this.xsltProcessContext(contextClone, child, output);\r\n }\r\n\r\n // Now select and execute the best matching template using priority rules\r\n if (templates.length > 0) {\r\n const expandedTemplates = collectAndExpandTemplates(template, null, this.xPath, this.templateSourceMap);\r\n\r\n // Find all (template, matchedNodes) pairs by testing each template's pattern\r\n const matchCandidates: { priority: TemplatePriorityInterface; matchedNodes: XNode[] }[] = [];\r\n\r\n for (const t of expandedTemplates) {\r\n try {\r\n // For initial template selection, evaluate patterns from document root\r\n // without axis override to ensure consistent matching for all patterns\r\n const matchedNodes = this.xsltMatch(t.matchPattern, contextClone);\r\n if (matchedNodes.length > 0) {\r\n matchCandidates.push({ priority: t, matchedNodes });\r\n }\r\n } catch (e) {\r\n // If pattern parsing fails, skip this template\r\n this.warningsCallback(`Failed to match pattern \"${t.matchPattern}\":`, e);\r\n }\r\n }\r\n\r\n if (matchCandidates.length > 0) {\r\n // First, check if \"/\" pattern matches - it's the document entry point and should be preferred\r\n const rootPatternMatch = matchCandidates.find(c => c.priority.matchPattern === '/');\r\n let winner: { priority: TemplatePriorityInterface; matchedNodes: XNode[] };\r\n \r\n if (rootPatternMatch) {\r\n // Use the root template as entry point\r\n winner = rootPatternMatch;\r\n } else {\r\n // Sort by: importPrecedence DESC, effectivePriority DESC, documentOrder DESC\r\n matchCandidates.sort((a, b) => {\r\n if (a.priority.importPrecedence !== b.priority.importPrecedence) {\r\n return b.priority.importPrecedence - a.priority.importPrecedence;\r\n }\r\n if (a.priority.effectivePriority !== b.priority.effectivePriority) {\r\n return b.priority.effectivePriority - a.priority.effectivePriority;\r\n }\r\n return b.priority.documentOrder - a.priority.documentOrder;\r\n });\r\n winner = matchCandidates[0];\r\n }\r\n\r\n // Detect conflicts\r\n const conflicts = matchCandidates.filter(t =>\r\n t.priority.importPrecedence === winner.priority.importPrecedence &&\r\n t.priority.effectivePriority === winner.priority.effectivePriority\r\n );\r\n\r\n if (conflicts.length > 1) {\r\n const patterns = conflicts\r\n .map(t => `\"${t.priority.matchPattern}\" (priority: ${t.priority.effectivePriority})`)\r\n .join(', ');\r\n this.warningsCallback(\r\n `XSLT Warning: Ambiguous template match. ` +\r\n `Multiple templates match with equal priority: ${patterns}. ` +\r\n `Using the last one in document order.`\r\n );\r\n }\r\n\r\n // Execute ONLY the selected template\r\n this.firstTemplateRan = true;\r\n contextClone.baseTemplateMatched = true;\r\n const templateContext = contextClone.clone(winner.matchedNodes, 0);\r\n \r\n // Track this template execution for apply-imports\r\n const metadata = this.templateSourceMap.get(winner.priority.template);\r\n const matchPattern = xmlGetAttribute(winner.priority.template, 'match');\r\n const modeAttr = xmlGetAttribute(winner.priority.template, 'mode');\r\n \r\n this.currentTemplateStack.push({\r\n template: winner.priority.template,\r\n stylesheetDepth: metadata?.importDepth ?? 0,\r\n mode: modeAttr || null,\r\n match: matchPattern\r\n });\r\n \r\n await this.xsltChildNodes(templateContext, winner.priority.template, output);\r\n \r\n this.currentTemplateStack.pop();\r\n } else {\r\n // No template matched the root element.\r\n // Apply the default XSLT behavior: process child nodes\r\n const rootNode = context.nodeList[context.position];\r\n if (rootNode && rootNode.childNodes && rootNode.childNodes.length > 0) {\r\n // Filter out DTD sections and apply templates to remaining children\r\n const childNodes = rootNode.childNodes.filter((n: XNode) => n.nodeName !== '#dtd-section');\r\n if (childNodes.length > 0) {\r\n const childContext = context.clone(childNodes);\r\n // Process each child node using xsltApplyTemplates logic\r\n for (let j = 0; j < childContext.contextSize(); ++j) {\r\n const currentNode = childContext.nodeList[j];\r\n\r\n if (currentNode.nodeType === DOM_TEXT_NODE) {\r\n const textNodeContext = context.clone([currentNode], 0);\r\n this.commonLogicTextNode(textNodeContext, currentNode, output);\r\n } else {\r\n const clonedContext = childContext.clone([currentNode], 0);\r\n const selection = selectBestTemplate(\r\n expandedTemplates,\r\n clonedContext,\r\n this.matchResolver,\r\n this.xPath,\r\n this.warningsCallback\r\n );\r\n\r\n if (selection.selectedTemplate) {\r\n const templateContext = clonedContext.clone([currentNode], 0);\r\n templateContext.inApplyTemplates = true;\r\n \r\n // Track this template execution for apply-imports\r\n const metadata = this.templateSourceMap.get(selection.selectedTemplate);\r\n const matchPattern = xmlGetAttribute(selection.selectedTemplate, 'match');\r\n const modeAttr = xmlGetAttribute(selection.selectedTemplate, 'mode');\r\n \r\n this.currentTemplateStack.push({\r\n template: selection.selectedTemplate,\r\n stylesheetDepth: metadata?.importDepth ?? 0,\r\n mode: modeAttr || null,\r\n match: matchPattern\r\n });\r\n \r\n await this.xsltChildNodes(templateContext, selection.selectedTemplate, output);\r\n \r\n this.currentTemplateStack.pop();\r\n } else {\r\n // If no template matches this child, recursively process its children\r\n if (currentNode.childNodes && currentNode.childNodes.length > 0) {\r\n const grandchildNodes = currentNode.childNodes.filter((n: XNode) => n.nodeName !== '#dtd-section');\r\n if (grandchildNodes.length > 0) {\r\n const grandchildContext = context.clone(grandchildNodes);\r\n // Recursively process grandchildren\r\n for (let k = 0; k < grandchildContext.contextSize(); ++k) {\r\n const grandchildNode = grandchildContext.nodeList[k];\r\n if (grandchildNode.nodeType === DOM_TEXT_NODE) {\r\n const textNodeContext = context.clone([grandchildNode], 0);\r\n this.commonLogicTextNode(textNodeContext, grandchildNode, output);\r\n } else {\r\n const grandchildClonedContext = grandchildContext.clone([grandchildNode], 0);\r\n const grandchildSelection = selectBestTemplate(\r\n expandedTemplates,\r\n grandchildClonedContext,\r\n this.matchResolver,\r\n this.xPath,\r\n this.warningsCallback\r\n );\r\n if (grandchildSelection.selectedTemplate) {\r\n const grandchildTemplateContext = grandchildClonedContext.clone([grandchildNode], 0);\r\n grandchildTemplateContext.inApplyTemplates = true;\r\n \r\n // Track this template execution for apply-imports\r\n const metadata = this.templateSourceMap.get(grandchildSelection.selectedTemplate);\r\n const matchPattern = xmlGetAttribute(grandchildSelection.selectedTemplate, 'match');\r\n const modeAttr = xmlGetAttribute(grandchildSelection.selectedTemplate, 'mode');\r\n \r\n this.currentTemplateStack.push({\r\n template: grandchildSelection.selectedTemplate,\r\n stylesheetDepth: metadata?.importDepth ?? 0,\r\n mode: modeAttr || null,\r\n match: matchPattern\r\n });\r\n \r\n await this.xsltChildNodes(grandchildTemplateContext, grandchildSelection.selectedTemplate, output);\r\n \r\n this.currentTemplateStack.pop();\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n protected xsltValueOf(context: ExprContext, template: XNode, output?: XNode) {\r\n const select = xmlGetAttribute(template, 'select');\r\n const current = context.nodeList[context.position];\r\n\r\n // First try evaluating in the current context. If that returns an\r\n // empty result and the current node is the document node, try again\r\n // evaluating against the document element (fallback), which helps\r\n // with some templates written to expect either form.\r\n let attribute = this.xPath.xPathEval(select, context);\r\n if (\r\n current &&\r\n current.nodeName === '#document' &&\r\n (attribute.stringValue() === '' || (attribute instanceof NodeSetValue && attribute.nodeSetValue().length === 0))\r\n ) {\r\n const docChild = current.childNodes.find((c: XNode) => c.nodeName !== '#dtd-section');\r\n if (docChild) {\r\n const fallbackContext = context.clone([docChild], 0);\r\n attribute = this.xPath.xPathEval(select, fallbackContext);\r\n }\r\n }\r\n\r\n const value = attribute.stringValue();\r\n const node = domCreateTextNode(this.outputDocument, value);\r\n // Set siblingPosition to preserve insertion order during serialization\r\n const targetOutput = output || this.outputDocument;\r\n node.siblingPosition = targetOutput.childNodes.length;\r\n targetOutput.appendChild(node);\r\n }\r\n\r\n /**\r\n * Implements `xsl:sequence` (XSLT 2.0).\r\n *\r\n * Constructs a sequence by evaluating the select expression or processing\r\n * child content. Unlike xsl:copy-of, xsl:sequence returns nodes by reference\r\n * and can return atomic values.\r\n *\r\n * @param context The expression context.\r\n * @param template The xsl:sequence element.\r\n * @param output The output node.\r\n */\r\n protected async xsltSequence(context: ExprContext, template: XNode, output?: XNode): Promise<void> {\r\n const select = xmlGetAttribute(template, 'select');\r\n const destinationNode = output || this.outputDocument;\r\n\r\n if (select) {\r\n // Evaluate the select expression\r\n const result: any = this.xPath.xPathEval(select, context);\r\n\r\n if (result.type === 'node-set') {\r\n // For node sequences, output each node\r\n const nodes = result.nodeSetValue();\r\n for (const node of nodes) {\r\n this.xsltCopyOf(destinationNode, node);\r\n }\r\n } else {\r\n // For atomic values (string, number, boolean), output as text\r\n const textNode = domCreateTextNode(this.outputDocument, result.stringValue());\r\n textNode.siblingPosition = destinationNode.childNodes.length;\r\n domAppendChild(destinationNode, textNode);\r\n }\r\n } else {\r\n // No select attribute - process child content\r\n await this.xsltChildNodes(context, template, output);\r\n }\r\n }\r\n\r\n /**\r\n * Implements `xsl:analyze-string` (XSLT 2.0).\r\n *\r\n * Processes a string using a regular expression, with separate handling\r\n * for matching and non-matching substrings.\r\n *\r\n * @param context The expression context.\r\n * @param template The xsl:analyze-string element.\r\n * @param output The output node.\r\n */\r\n protected async xsltAnalyzeString(context: ExprContext, template: XNode, output?: XNode): Promise<void> {\r\n const selectAttr = xmlGetAttribute(template, 'select');\r\n const regexAttr = xmlGetAttribute(template, 'regex');\r\n const flagsAttr = xmlGetAttribute(template, 'flags') || '';\r\n\r\n if (!selectAttr) {\r\n throw new Error('<xsl:analyze-string> requires a select attribute.');\r\n }\r\n if (!regexAttr) {\r\n throw new Error('<xsl:analyze-string> requires a regex attribute.');\r\n }\r\n\r\n // Evaluate the select expression to get the string to analyze\r\n const inputValue = this.xPath.xPathEval(selectAttr, context);\r\n const inputString = inputValue.stringValue();\r\n\r\n // Find xsl:matching-substring and xsl:non-matching-substring children\r\n let matchingSubstring: XNode | null = null;\r\n let nonMatchingSubstring: XNode | null = null;\r\n\r\n for (const child of template.childNodes) {\r\n if (child.nodeType === DOM_ELEMENT_NODE && this.isXsltElement(child)) {\r\n if (child.localName === 'matching-substring') {\r\n matchingSubstring = child;\r\n } else if (child.localName === 'non-matching-substring') {\r\n nonMatchingSubstring = child;\r\n } else if (child.localName === 'fallback') {\r\n // xsl:fallback is allowed but ignored in XSLT 2.0 processors\r\n continue;\r\n }\r\n }\r\n }\r\n\r\n // Build the regex with flags\r\n let jsFlags = 'g'; // Always use global for analyze-string\r\n for (const flag of flagsAttr) {\r\n switch (flag) {\r\n case 'i': jsFlags += 'i'; break;\r\n case 'm': jsFlags += 'm'; break;\r\n case 's': jsFlags += 's'; break;\r\n // 'x' (extended) would need special handling - skip for now\r\n }\r\n }\r\n\r\n let regex: RegExp;\r\n try {\r\n regex = new RegExp(regexAttr, jsFlags);\r\n } catch (e) {\r\n throw new Error(`Invalid regular expression in xsl:analyze-string: ${regexAttr}`);\r\n }\r\n\r\n // Process the string, alternating between matches and non-matches\r\n let lastIndex = 0;\r\n let match: RegExpExecArray | null;\r\n\r\n while ((match = regex.exec(inputString)) !== null) {\r\n const matchStart = match.index;\r\n const matchEnd = matchStart + match[0].length;\r\n\r\n // Process non-matching substring before this match\r\n if (matchStart > lastIndex && nonMatchingSubstring) {\r\n const nonMatchText = inputString.substring(lastIndex, matchStart);\r\n await this.processAnalyzeStringContent(context, nonMatchingSubstring, output, nonMatchText, null);\r\n }\r\n\r\n // Process matching substring\r\n if (matchingSubstring) {\r\n // match array: [fullMatch, group1, group2, ...]\r\n const groups = match.slice(0); // Copy the match array\r\n await this.processAnalyzeStringContent(context, matchingSubstring, output, match[0], groups);\r\n }\r\n\r\n lastIndex = matchEnd;\r\n\r\n // Prevent infinite loop on zero-length matches\r\n if (match[0].length === 0) {\r\n regex.lastIndex++;\r\n }\r\n }\r\n\r\n // Process any remaining non-matching substring after the last match\r\n if (lastIndex < inputString.length && nonMatchingSubstring) {\r\n const nonMatchText = inputString.substring(lastIndex);\r\n await this.processAnalyzeStringContent(context, nonMatchingSubstring, output, nonMatchText, null);\r\n }\r\n }\r\n\r\n /**\r\n * Helper method to process xsl:matching-substring or xsl:non-matching-substring content.\r\n * Sets up the context with the current text and regex groups.\r\n */\r\n private async processAnalyzeStringContent(\r\n context: ExprContext,\r\n template: XNode,\r\n output: XNode | undefined,\r\n currentText: string,\r\n regexGroups: string[] | null\r\n ): Promise<void> {\r\n // Create a text node to represent the current string being processed\r\n const textNode = domCreateTextNode(this.outputDocument, currentText);\r\n\r\n // Clone context with the text node as the context node\r\n const childContext = context.clone([textNode], 0);\r\n\r\n // Set regex groups on the context for regex-group() function\r\n if (regexGroups) {\r\n childContext.regexGroups = regexGroups;\r\n }\r\n\r\n // Process the child content of matching-substring or non-matching-substring\r\n await this.xsltChildNodes(childContext, template, output);\r\n }\r\n\r\n /**\r\n * Implements `xsl:function` (XSLT 2.0).\r\n * \r\n * Declares a stylesheet function that can be called from XPath expressions.\r\n * Functions are collected during stylesheet initialization and made available\r\n * to the XPath evaluator.\r\n *\r\n * @param context The expression context.\r\n * @param template The xsl:function element.\r\n */\r\n protected xsltFunction(context: ExprContext, template: XNode): void {\r\n const name = xmlGetAttribute(template, 'name');\r\n const asAttr = xmlGetAttribute(template, 'as'); // Return type (optional)\r\n const overrideAttr = xmlGetAttribute(template, 'override'); // Override imported functions\r\n\r\n if (!name) {\r\n throw new Error('<xsl:function> requires a \"name\" attribute.');\r\n }\r\n\r\n // Function name must be in a non-null namespace (prefixed)\r\n if (!name.includes(':')) {\r\n throw new Error(`<xsl:function> name \"${name}\" must be in a namespace (use a prefixed name like \"my:functionName\").`);\r\n }\r\n\r\n // Check if this function already exists\r\n const override = overrideAttr === 'yes' || overrideAttr === 'true';\r\n if (this.userDefinedFunctions.has(name) && !override) {\r\n // Function already defined, only override if explicitly allowed\r\n return;\r\n }\r\n\r\n // Store the function definition\r\n this.userDefinedFunctions.set(name, template);\r\n }\r\n\r\n /**\r\n * Coerce a NodeValue to a specific type based on the 'as' attribute.\r\n * \r\n * @param value The value to coerce.\r\n * @param type The target type (e.g., \"xs:integer\", \"xs:string\", \"xs:boolean\").\r\n * @returns The coerced value.\r\n */\r\n protected coerceToType(value: NodeValue, type: string): NodeValue {\r\n const normalizedType = type.replace(/^xs:/, '').toLowerCase();\r\n \r\n switch (normalizedType) {\r\n case 'integer':\r\n case 'int':\r\n case 'double':\r\n case 'decimal':\r\n case 'number':\r\n // Convert to number\r\n return new NumberValue(value.numberValue());\r\n \r\n case 'string':\r\n // Convert to string\r\n return new StringValue(value.stringValue());\r\n \r\n case 'boolean':\r\n // Convert to boolean\r\n return new BooleanValue(value.booleanValue());\r\n \r\n default:\r\n // For unknown types or node-set types, return as-is\r\n return value;\r\n }\r\n }\r\n\r\n /**\r\n * Converts a raw JavaScript value to the appropriate NodeValue type.\r\n * Detects NodeValue instances, DOM nodes, arrays, numbers, booleans,\r\n * and falls back to StringValue.\r\n *\r\n * @param value The raw value to convert.\r\n * @returns The wrapped NodeValue.\r\n */\r\n protected toNodeValue(value: any): NodeValue {\r\n if (value && typeof value === 'object' && 'stringValue' in value) {\r\n return value as NodeValue;\r\n } else if (value && typeof value === 'object' && 'nodeType' in value) {\r\n return new NodeSetValue([value as XNode]);\r\n } else if (Array.isArray(value)) {\r\n return new NodeSetValue(value);\r\n } else if (typeof value === 'number') {\r\n return new NumberValue(value);\r\n } else if (typeof value === 'boolean') {\r\n return new BooleanValue(value);\r\n } else {\r\n return new StringValue(String(value ?? ''));\r\n }\r\n }\r\n\r\n /**\r\n * Execute a user-defined xsl:function.\r\n * Called when a function from userDefinedFunctions is invoked from XPath.\r\n *\r\n * @param context The expression context.\r\n * @param functionDef The xsl:function node.\r\n * @param args The evaluated arguments passed to the function.\r\n * @returns The result of the function execution.\r\n */\r\n protected async executeUserDefinedFunction(\r\n context: ExprContext,\r\n functionDef: XNode,\r\n args: any[]\r\n ): Promise<any> {\r\n return this.executeUserDefinedFunctionSync(context, functionDef, args);\r\n }\r\n\r\n /**\r\n * Synchronously execute a user-defined xsl:function.\r\n * This is used when functions are called from XPath expressions.\r\n * Limited to functions that don't require async operations in their body.\r\n *\r\n * @param context The expression context.\r\n * @param functionDef The xsl:function node.\r\n * @param args The evaluated arguments passed to the function.\r\n * @returns The result of the function execution.\r\n */\r\n executeUserDefinedFunctionSync(\r\n context: ExprContext,\r\n functionDef: XNode,\r\n args: any[]\r\n ): any {\r\n // Create a new context for function execution with its own variable scope\r\n const functionContext = context.clone();\r\n // Create a new variables object to avoid modifying parent scope\r\n functionContext.variables = { ...context.variables };\r\n\r\n // Get xsl:param children to bind arguments\r\n const params: XNode[] = [];\r\n for (const child of functionDef.childNodes) {\r\n if (child.nodeType === DOM_ELEMENT_NODE && this.isXsltElement(child, 'param')) {\r\n params.push(child);\r\n }\r\n }\r\n\r\n // Bind arguments to parameters\r\n for (let i = 0; i < params.length; i++) {\r\n const paramName = xmlGetAttribute(params[i], 'name');\r\n if (paramName) {\r\n if (i < args.length) {\r\n // Use provided argument\r\n const paramType = xmlGetAttribute(params[i], 'as');\r\n let paramValue = this.toNodeValue(args[i]);\r\n if (paramType) {\r\n paramValue = this.coerceToType(paramValue, paramType);\r\n }\r\n \r\n functionContext.setVariable(paramName, paramValue);\r\n } else {\r\n // Use default value from parameter definition if available\r\n const selectExpr = xmlGetAttribute(params[i], 'select');\r\n if (selectExpr) {\r\n const defaultValue = this.xPath.xPathEval(selectExpr, functionContext);\r\n functionContext.setVariable(paramName, defaultValue);\r\n } else {\r\n functionContext.setVariable(paramName, new StringValue(''));\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Process function body - look for xsl:sequence with select\r\n // This is the common pattern for XSLT 2.0 functions\r\n for (const child of functionDef.childNodes) {\r\n if (child.nodeType === DOM_ELEMENT_NODE) {\r\n if (this.isXsltElement(child, 'sequence')) {\r\n const select = xmlGetAttribute(child, 'select');\r\n if (select) {\r\n // Evaluate the select expression and return\r\n const result = this.xPath.xPathEval(select, functionContext);\r\n // Return as the appropriate type\r\n if (result.type === 'number') {\r\n return result.numberValue();\r\n } else if (result.type === 'boolean') {\r\n return result.booleanValue();\r\n } else if (result.type === 'node-set') {\r\n return result.nodeSetValue();\r\n } else {\r\n return result.stringValue();\r\n }\r\n }\r\n } else if (this.isXsltElement(child, 'value-of')) {\r\n const select = xmlGetAttribute(child, 'select');\r\n if (select) {\r\n return this.xPath.xPathEval(select, functionContext).stringValue();\r\n }\r\n }\r\n // Skip param elements\r\n }\r\n }\r\n\r\n // If no result found, return empty string\r\n return '';\r\n }\r\n\r\n /**\r\n * Implements `xsl:result-document` (XSLT 2.0).\r\n *\r\n * Creates a secondary output document. The output is stored in the\r\n * resultDocuments map, accessible via getResultDocuments().\r\n *\r\n * @param context The expression context.\r\n * @param template The xsl:result-document element.\r\n */\r\n protected async xsltResultDocument(context: ExprContext, template: XNode): Promise<void> {\r\n const hrefExpr = xmlGetAttribute(template, 'href') || '';\r\n const methodAttr = xmlGetAttribute(template, 'method') || this.outputMethod || 'xml';\r\n const omitXmlDeclaration = xmlGetAttribute(template, 'omit-xml-declaration') || this.outputOmitXmlDeclaration;\r\n\r\n // Evaluate href as attribute value template\r\n const href = this.xsltAttributeValue(hrefExpr, context);\r\n\r\n if (!href) {\r\n throw new Error('<xsl:result-document> requires a non-empty \"href\" attribute.');\r\n }\r\n\r\n // Check for duplicate result documents\r\n if (this.resultDocuments.has(href)) {\r\n throw new Error(`<xsl:result-document>: A document has already been created with href=\"${href}\".`);\r\n }\r\n\r\n // Create a new output document for this result\r\n const resultDocument = new XDocument();\r\n\r\n // Process children into the new document\r\n await this.xsltChildNodes(context, template, resultDocument);\r\n\r\n // Serialize the result document\r\n const serialized = xmlTransformedText(resultDocument, {\r\n cData: this.options.cData,\r\n escape: this.options.escape,\r\n selfClosingTags: this.options.selfClosingTags,\r\n outputMethod: methodAttr as 'xml' | 'html' | 'text' | 'xhtml',\r\n outputVersion: this.outputVersion,\r\n itemSeparator: this.itemSeparator\r\n });\r\n\r\n // Store in result documents map\r\n this.resultDocuments.set(href, serialized);\r\n }\r\n\r\n /**\r\n * Get all result documents created by xsl:result-document.\r\n * @returns A map of href URIs to serialized output strings.\r\n */\r\n getResultDocuments(): Map<string, string> {\r\n return this.resultDocuments;\r\n }\r\n\r\n /**\r\n * Sets the package loader callback.\r\n * The callback is called when a package is referenced via xsl:use-package\r\n * but is not found in the registry.\r\n * \r\n * @param loader A function that loads package documents by URI and optional version.\r\n * Returns the parsed package document, or null if not found.\r\n */\r\n setPackageLoader(loader: (uri: string, version?: string) => Promise<XNode | null>): void {\r\n this.packageLoader = loader;\r\n }\r\n\r\n /**\r\n * Pre-registers a package for use in transformations.\r\n * The package is parsed and stored in the internal registry.\r\n * \r\n * @param name The package name/URI.\r\n * @param packageDoc The parsed package document.\r\n * @param version Optional semantic version string.\r\n */\r\n async registerPackage(name: string, packageDoc: XNode, version?: string): Promise<void> {\r\n await this.loadAndRegisterPackage(name, packageDoc, version);\r\n }\r\n\r\n /**\r\n * Implements `xsl:perform-sort` (XSLT 2.0).\r\n *\r\n * Sorts a sequence of items without iteration. The sorted sequence\r\n * is available via xsl:sequence or other sequence-consuming instructions.\r\n *\r\n * @param context The expression context.\r\n * @param template The xsl:perform-sort element.\r\n * @param output The output node.\r\n */\r\n protected async xsltPerformSort(context: ExprContext, template: XNode, output?: XNode): Promise<void> {\r\n const select = xmlGetAttribute(template, 'select');\r\n\r\n // Get items to sort\r\n let items: XNode[];\r\n if (select) {\r\n items = this.xPath.xPathEval(select, context).nodeSetValue();\r\n } else {\r\n // If no select, look for xsl:sequence children to provide items\r\n const sequenceChildren: XNode[] = [];\r\n for (const child of template.childNodes) {\r\n if (child.nodeType === DOM_ELEMENT_NODE && !this.isXsltElement(child, 'sort')) {\r\n sequenceChildren.push(child);\r\n }\r\n }\r\n // Evaluate sequence children\r\n const fragment = domCreateDocumentFragment(this.outputDocument);\r\n for (const child of sequenceChildren) {\r\n await this.xsltProcessContext(context, child, fragment);\r\n }\r\n items = Array.from(fragment.childNodes);\r\n }\r\n\r\n if (items.length === 0) {\r\n return;\r\n }\r\n\r\n // Create sort context and apply sorting\r\n const sortContext = context.clone(items);\r\n this.xsltSort(sortContext, template);\r\n\r\n // Output the sorted items\r\n const destinationNode = output || this.outputDocument;\r\n for (const node of sortContext.nodeList) {\r\n this.xsltCopyOf(destinationNode, node);\r\n }\r\n }\r\n\r\n /**\r\n * Implements `xsl:namespace` (XSLT 2.0).\r\n *\r\n * Creates a namespace node in the result tree.\r\n *\r\n * @param context The expression context.\r\n * @param template The xsl:namespace element.\r\n * @param output The output node.\r\n */\r\n protected async xsltNamespace(context: ExprContext, template: XNode, output?: XNode): Promise<void> {\r\n const nameExpr = xmlGetAttribute(template, 'name');\r\n const selectExpr = xmlGetAttribute(template, 'select');\r\n\r\n if (!nameExpr && nameExpr !== '') {\r\n throw new Error('<xsl:namespace> requires a \"name\" attribute.');\r\n }\r\n\r\n // Evaluate name as attribute value template\r\n const prefix = this.xsltAttributeValue(nameExpr, context);\r\n\r\n // Get the namespace URI\r\n let namespaceUri: string;\r\n if (selectExpr) {\r\n namespaceUri = this.xPath.xPathEval(selectExpr, context).stringValue();\r\n } else {\r\n // Get value from child content\r\n const fragment = domCreateDocumentFragment(this.outputDocument);\r\n await this.xsltChildNodes(context, template, fragment);\r\n namespaceUri = xmlValue(fragment);\r\n }\r\n\r\n // Validate namespace URI\r\n if (!namespaceUri) {\r\n throw new Error('<xsl:namespace> requires a non-empty namespace URI.');\r\n }\r\n\r\n // Create the namespace declaration on the output element\r\n const destinationNode = output || this.outputDocument;\r\n if (destinationNode.nodeType === DOM_ELEMENT_NODE) {\r\n if (prefix) {\r\n domSetAttribute(destinationNode, `xmlns:${prefix}`, namespaceUri);\r\n } else {\r\n domSetAttribute(destinationNode, 'xmlns', namespaceUri);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Evaluates a variable or parameter and set it in the current input\r\n * context. Implements `xsl:variable`, `xsl:param`, and `xsl:with-param`.\r\n *\r\n * @param context The expression context.\r\n * @param template The template node.\r\n * @param override flag that defines if the value computed here\r\n * overrides the one already in the input context if that is the\r\n * case. I.e. decides if this is a default value or a local\r\n * value. `xsl:variable` and `xsl:with-param` override; `xsl:param` doesn't.\r\n */\r\n protected async xsltVariable(context: ExprContext, template: XNode, override: boolean) {\r\n const name = xmlGetAttribute(template, 'name');\r\n const select = xmlGetAttribute(template, 'select');\r\n\r\n let value: NodeValue;\r\n\r\n const nonAttributeChildren = template.childNodes.filter((n) => n.nodeType !== DOM_ATTRIBUTE_NODE);\r\n if (nonAttributeChildren.length > 0) {\r\n const fragment = domCreateDocumentFragment(template.ownerDocument);\r\n await this.xsltChildNodes(context, template, fragment);\r\n value = new NodeSetValue([fragment]);\r\n } else if (select) {\r\n value = this.xPath.xPathEval(select, context);\r\n } else {\r\n const filteredParameter = this.options.parameters.filter((p) => p.name === name);\r\n if (filteredParameter.length > 0) {\r\n value = this.toNodeValue(filteredParameter[0].value);\r\n } else {\r\n value = new StringValue('');\r\n }\r\n }\r\n\r\n if (override || !context.getVariable(name)) {\r\n context.setVariable(name, value);\r\n }\r\n }\r\n\r\n /**\r\n * Register accepted variables from used packages into the context.\r\n * Called after processing package use-package declarations.\r\n * @param context The expression context.\r\n */\r\n private async registerAcceptedVariables(context: ExprContext) {\r\n if (!this.currentPackage) {\r\n return;\r\n }\r\n\r\n // Iterate through all used packages\r\n this.currentPackage.usedPackages.forEach((usedPkg, packageKey) => {\r\n // Look at accepted components\r\n usedPkg.acceptedComponents.forEach((component, componentKey) => {\r\n if (component.type === 'variable' && component.name && component.isAccepted) {\r\n // Process this variable node to get its value\r\n this.xsltVariable(context, component.node, false);\r\n }\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Traverses the template node tree. Calls the main processing\r\n * function with the current input context for every child node of the\r\n * current template node.\r\n * @param context Normally the Expression Context.\r\n * @param template The XSL-T definition.\r\n * @param output If set, the output where the transformation should occur.\r\n */\r\n protected async xsltChildNodes(context: ExprContext, template: XNode, output?: XNode) {\r\n // Clone input context to keep variables declared here local to the\r\n // siblings of the children.\r\n const contextClone = context.clone();\r\n for (let i = 0; i < template.childNodes.length; ++i) {\r\n const child = template.childNodes[i];\r\n // Skip attribute nodes - they are stored in childNodes but should not be\r\n // processed as template content. Attributes belong to the element itself.\r\n if (child.nodeType === DOM_ATTRIBUTE_NODE) {\r\n continue;\r\n }\r\n await this.xsltProcessContext(contextClone, child, output);\r\n }\r\n }\r\n\r\n /**\r\n * Processes child nodes while skipping xsl:on-empty and xsl:on-non-empty.\r\n * Used by instructions that handle these conditionals explicitly.\r\n */\r\n protected async xsltChildNodesExcludingConditional(context: ExprContext, template: XNode, output?: XNode) {\r\n const contextClone = context.clone();\r\n for (let i = 0; i < template.childNodes.length; ++i) {\r\n const child = template.childNodes[i];\r\n if (child.nodeType === DOM_ATTRIBUTE_NODE) {\r\n continue;\r\n }\r\n if (\r\n child.nodeType === DOM_ELEMENT_NODE &&\r\n this.isXsltElement(child) &&\r\n (child.localName === 'on-empty' || child.localName === 'on-non-empty')\r\n ) {\r\n continue;\r\n }\r\n await this.xsltProcessContext(contextClone, child, output);\r\n }\r\n }\r\n\r\n private findConditionalChild(template: XNode, localName: 'on-empty' | 'on-non-empty'): XNode | null {\r\n for (const child of template.childNodes) {\r\n if (child.nodeType === DOM_ELEMENT_NODE && this.isXsltElement(child, localName)) {\r\n return child;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * This logic is used in two different places:\r\n * - `xsltPassThrough`, if the template asks this library to write a text node;\r\n * - `xsltProcessContext`, `apply-templates` operation, when the current node is text.\r\n * \r\n * Text nodes always require a parent, and they never have children.\r\n * @param context The Expression Context.\r\n * @param template The template, that contains the node value to be written.\r\n * @param output The output.\r\n */\r\n private commonLogicTextNode(context: ExprContext, template: XNode, output: XNode) {\r\n if (output) {\r\n // Check if this whitespace-only text node should be stripped based on\r\n // xsl:strip-space and xsl:preserve-space declarations\r\n if (this.shouldStripWhitespaceNode(template)) {\r\n return;\r\n }\r\n\r\n // Apply Text Value Templates for XSLT 3.0+\r\n let textValue = template.nodeValue;\r\n if (this.version && parseFloat(this.version) >= 3.0) {\r\n textValue = this.xsltTextValueTemplate(textValue, context);\r\n }\r\n\r\n let node = domCreateTextNode(this.outputDocument, textValue);\r\n // Set siblingPosition to preserve insertion order during serialization\r\n node.siblingPosition = output.childNodes.length;\r\n domAppendChild(output, node);\r\n }\r\n }\r\n\r\n /**\r\n * Passes template text to the output. The current template node does\r\n * not specify an XSL-T operation and therefore is appended to the\r\n * output with all its attributes. Then continues traversing the\r\n * template node tree.\r\n * @param context The Expression Context.\r\n * @param template The XSLT stylesheet or transformation.\r\n * @param output The output.\r\n */\r\n protected async xsltPassThrough(context: ExprContext, template: XNode, output: XNode) {\r\n switch (template.nodeType) {\r\n case DOM_TEXT_NODE:\r\n if (this.xsltPassText(template)) {\r\n this.commonLogicTextNode(context, template, output);\r\n }\r\n\r\n break;\r\n case DOM_ELEMENT_NODE:\r\n let node: XNode;\r\n let elementContext = context;\r\n // Don't change context based on input document structure\r\n // The context should remain as provided, unless explicitly changed by XSLT instructions\r\n node = context.nodeList[context.position];\r\n\r\n let newNode: XNode;\r\n let qualifiedName = template.nodeName;\r\n let namespaceUri = template.namespaceUri;\r\n const templatePrefix = template.prefix || '';\r\n const aliasPrefix = this.namespaceAliases.get(templatePrefix);\r\n if (aliasPrefix) {\r\n const localName = template.localName || template.nodeName;\r\n if (aliasPrefix === '#default') {\r\n qualifiedName = localName;\r\n namespaceUri = this.resolveNamespaceUriForPrefix(template, null);\r\n } else {\r\n qualifiedName = `${aliasPrefix}:${localName}`;\r\n namespaceUri = this.resolveNamespaceUriForPrefix(template, aliasPrefix);\r\n }\r\n }\r\n\r\n newNode = domCreateElement(this.outputDocument, qualifiedName);\r\n \r\n // Set position based on current number of children in output\r\n // This preserves document order for literal elements in templates\r\n // (Issue #158: text nodes before block elements should stay before them)\r\n // We don't copy siblingPosition from input node because it's from a different document\r\n newNode.siblingPosition = (output || this.outputDocument).childNodes.length;\r\n\r\n domAppendChild(output || this.outputDocument, newNode);\r\n\r\n if (aliasPrefix) {\r\n if (aliasPrefix === '#default') {\r\n if (namespaceUri) {\r\n domSetAttribute(newNode, 'xmlns', namespaceUri);\r\n }\r\n } else if (namespaceUri) {\r\n domSetAttribute(newNode, `xmlns:${aliasPrefix}`, namespaceUri);\r\n }\r\n } else if (namespaceUri) {\r\n const prefix = templatePrefix || (qualifiedName.includes(':') ? qualifiedName.split(':')[0] : null);\r\n const nsAttr = prefix ? `xmlns:${prefix}` : 'xmlns';\r\n if (!this.isNamespaceDeclaredOnAncestor(output, nsAttr, namespaceUri)) {\r\n domSetAttribute(newNode, nsAttr, namespaceUri);\r\n }\r\n }\r\n\r\n // Apply attribute sets from use-attribute-sets attribute on literal elements\r\n const useAttributeSetsAttr = template.childNodes.find(\r\n (a: XNode) =>\r\n a?.nodeType === DOM_ATTRIBUTE_NODE && a.nodeName === 'use-attribute-sets'\r\n );\r\n if (useAttributeSetsAttr) {\r\n await this.applyAttributeSets(elementContext, newNode, useAttributeSetsAttr.nodeValue);\r\n }\r\n\r\n await this.xsltChildNodes(elementContext, template, newNode);\r\n\r\n const templateAttributes = template.childNodes.filter(\r\n (a: XNode) =>\r\n a?.nodeType === DOM_ATTRIBUTE_NODE && a.nodeName !== 'use-attribute-sets'\r\n );\r\n for (const attribute of templateAttributes) {\r\n const name = attribute.nodeName;\r\n const value = this.xsltAttributeValue(attribute.nodeValue, elementContext);\r\n domSetAttribute(newNode, name, value);\r\n\r\n // If the attribute has a namespace prefix, ensure the xmlns declaration exists\r\n if (attribute.prefix && attribute.namespaceUri &&\r\n attribute.prefix !== 'xmlns' && !attribute.nodeName.startsWith('xmlns')) {\r\n const nsAttr = `xmlns:${attribute.prefix}`;\r\n if (!this.isNamespaceDeclaredOnAncestor(newNode, nsAttr, attribute.namespaceUri)) {\r\n domSetAttribute(newNode, nsAttr, attribute.namespaceUri);\r\n }\r\n }\r\n }\r\n\r\n break;\r\n default:\r\n // This applies also to the DOCUMENT_NODE of the XSL stylesheet,\r\n // so we don't have to treat it specially.\r\n await this.xsltChildNodes(context, template, output);\r\n }\r\n }\r\n\r\n /**\r\n * Determines if a text node in the XSLT template document is to be\r\n * stripped according to XSLT whitespace stripping rules.\r\n * @see [XSLT], section 3.4.\r\n * @param template The XSLT template.\r\n * @returns TODO\r\n * @todo Whitespace stripping on the input document is\r\n * currently not implemented.\r\n */\r\n protected xsltPassText(template: XNode) {\r\n if (!template.nodeValue.match(/^\\s*$/)) {\r\n return true;\r\n }\r\n\r\n let element = template.parentNode;\r\n if (this.isXsltElement(element, 'text')) {\r\n return true;\r\n }\r\n\r\n while (element && element.nodeType == DOM_ELEMENT_NODE) {\r\n const xmlspace = domGetAttributeValue(element, 'xml:space');\r\n if (xmlspace) {\r\n if (xmlspace == 'default') {\r\n return false;\r\n }\r\n\r\n if (xmlspace == 'preserve') {\r\n return true;\r\n }\r\n }\r\n\r\n element = element.parentNode;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n protected findAttributeInContext(attributeName: string, context: ExprContext): XNode {\r\n return context.nodeList[context.position].childNodes.find(\r\n (a: XNode) => a.nodeType === DOM_ATTRIBUTE_NODE && a.nodeName === attributeName\r\n );\r\n }\r\n\r\n /**\r\n * Evaluates an XSL-T attribute value template. Attribute value\r\n * templates are attributes on XSL-T elements that contain XPath\r\n * expressions in braces {}. The XSL-T expressions are evaluated in\r\n * the current input context.\r\n * @param value TODO\r\n * @param context TODO\r\n * @returns TODO\r\n */\r\n protected xsltAttributeValue(value: any, context: ExprContext) {\r\n const parts = value.split('{');\r\n if (parts.length === 1) {\r\n return value;\r\n }\r\n\r\n let ret = '';\r\n for (let i = 0; i < parts.length; ++i) {\r\n const rp = parts[i].split('}');\r\n if (rp.length != 2) {\r\n // first literal part of the value\r\n ret += parts[i];\r\n continue;\r\n }\r\n\r\n const val = this.xPath.xPathEval(rp[0], context).stringValue();\r\n ret += val + rp[1];\r\n }\r\n\r\n return ret;\r\n }\r\n\r\n /**\r\n * Evaluates text value templates in XSLT 3.0. Text value templates\r\n * allow XPath expressions in braces {} within text nodes.\r\n * The expressions are evaluated in the current input context.\r\n * To include a literal brace, use {{ or }}.\r\n * @param value The text node value to process\r\n * @param context The expression context\r\n * @returns The processed text with expressions evaluated\r\n */\r\n protected xsltTextValueTemplate(value: string, context: ExprContext): string {\r\n if (!value) {\r\n return value;\r\n }\r\n\r\n let result = '';\r\n let i = 0;\r\n \r\n while (i < value.length) {\r\n const char = value[i];\r\n \r\n if (char === '{') {\r\n // Check for escaped {{\r\n if (i + 1 < value.length && value[i + 1] === '{') {\r\n result += '{';\r\n i += 2;\r\n continue;\r\n }\r\n \r\n // Find matching closing brace\r\n let depth = 1;\r\n let j = i + 1;\r\n let expr = '';\r\n \r\n while (j < value.length && depth > 0) {\r\n if (value[j] === '{') {\r\n depth++;\r\n } else if (value[j] === '}') {\r\n depth--;\r\n if (depth === 0) {\r\n break;\r\n }\r\n }\r\n expr += value[j];\r\n j++;\r\n }\r\n \r\n if (depth === 0) {\r\n // Evaluate the XPath expression\r\n try {\r\n const val = this.xPath.xPathEval(expr, context).stringValue();\r\n result += val;\r\n } catch (e) {\r\n throw new Error(`Error evaluating text value template expression \"${expr}\": ${e.message}`);\r\n }\r\n i = j + 1;\r\n } else {\r\n // Unmatched opening brace - treat as literal\r\n result += char;\r\n i++;\r\n }\r\n } else if (char === '}') {\r\n // Check for escaped }}\r\n if (i + 1 < value.length && value[i + 1] === '}') {\r\n result += '}';\r\n i += 2;\r\n continue;\r\n }\r\n \r\n // Unmatched closing brace - treat as literal\r\n result += char;\r\n i++;\r\n } else {\r\n result += char;\r\n i++;\r\n }\r\n }\r\n \r\n return result;\r\n }\r\n\r\n /**\r\n * Evaluates an XPath expression in the current input context as a\r\n * match.\r\n * @see [XSLT] section 5.2, paragraph 1\r\n * @param match TODO\r\n * @param context The Expression Context.\r\n * @param axis The XPath axis. Used when the match does not start with the parent.\r\n * @returns {XNode[]} A list of the found nodes.\r\n */\r\n protected xsltMatch(match: string, context: ExprContext, axis?: string): XNode[] {\r\n const expression = this.xPath.xPathParse(match, axis);\r\n return this.matchResolver.expressionMatch(expression, context);\r\n }\r\n\r\n /**\r\n * Sets parameters defined by xsl:with-param child nodes of the\r\n * current template node, in the current input context. This happens\r\n * before the operation specified by the current template node is\r\n * executed.\r\n * @param context The Expression Context.\r\n * @param template The template node.\r\n */\r\n protected async xsltWithParam(context: ExprContext, template: XNode) {\r\n for (const childNode of template.childNodes) {\r\n if (childNode.nodeType === DOM_ELEMENT_NODE && this.isXsltElement(childNode, 'with-param')) {\r\n await this.xsltVariable(context, childNode, true);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Recursively map all template nodes in a stylesheet to their metadata.\r\n * Used to track which stylesheet each template comes from for apply-imports.\r\n * @param stylesheetElement The stylesheet or transform element (or any parent element).\r\n * @param metadata The metadata for this stylesheet.\r\n */\r\n private mapTemplatesFromStylesheet(stylesheetElement: XNode, metadata: StylesheetMetadata) {\r\n for (const child of stylesheetElement.childNodes) {\r\n if (child.nodeType === DOM_ELEMENT_NODE) {\r\n if (this.isXsltElement(child, 'template')) {\r\n // Map this template to its stylesheet metadata\r\n this.templateSourceMap.set(child, metadata);\r\n } else if (this.isXsltElement(child, 'stylesheet') || this.isXsltElement(child, 'transform') || this.isXsltElement(child, 'package')) {\r\n // Recursively process nested stylesheets and packages\r\n this.mapTemplatesFromStylesheet(child, metadata);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Collect all attribute set definitions from the stylesheet.\r\n * Called at stylesheet initialization time.\r\n * @param stylesheetElement The stylesheet or transform element.\r\n */\r\n private collectAttributeSets(stylesheetElement: XNode) {\r\n for (const child of stylesheetElement.childNodes) {\r\n if (\r\n child.nodeType === DOM_ELEMENT_NODE &&\r\n this.isXsltElement(child, 'attribute-set')\r\n ) {\r\n const name = xmlGetAttribute(child, 'name');\r\n const attributes = child.childNodes.filter(\r\n (n: XNode) =>\r\n n.nodeType === DOM_ELEMENT_NODE && this.isXsltElement(n, 'attribute')\r\n );\r\n\r\n if (name) {\r\n const existing = this.attributeSets.get(name);\r\n if (existing && existing.length) {\r\n // Merge attributes from multiple xsl:attribute-set declarations with the same name.\r\n this.attributeSets.set(name, [...existing, ...attributes]);\r\n } else {\r\n this.attributeSets.set(name, attributes);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Collect all user-defined function definitions from the stylesheet.\r\n * Called at stylesheet initialization time.\r\n * @param stylesheetElement The stylesheet or transform element.\r\n * @param context The expression context.\r\n */\r\n private collectUserDefinedFunctions(stylesheetElement: XNode, context: ExprContext) {\r\n for (const child of stylesheetElement.childNodes) {\r\n if (\r\n child.nodeType === DOM_ELEMENT_NODE &&\r\n this.isXsltElement(child, 'function')\r\n ) {\r\n this.xsltFunction(context, child);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Register user-defined functions in the expression context.\r\n * This makes them available to XPath expressions.\r\n * @param context The expression context.\r\n */\r\n private registerUserDefinedFunctionsInContext(context: ExprContext) {\r\n if (this.userDefinedFunctions.size === 0 && !this.hasAcceptedFunctions()) {\r\n return;\r\n }\r\n\r\n const functionsMap = new Map<string, {\r\n functionDef: XNode;\r\n executor: (ctx: ExprContext, functionDef: XNode, args: any[]) => any;\r\n }>();\r\n\r\n // Register user-defined functions from the current stylesheet\r\n this.userDefinedFunctions.forEach((functionDef, name) => {\r\n functionsMap.set(name, {\r\n functionDef,\r\n executor: (ctx: ExprContext, funcDef: XNode, args: any[]) => {\r\n return this.executeUserDefinedFunctionSync(ctx, funcDef, args);\r\n }\r\n });\r\n });\r\n\r\n // Register functions from accepted components in used packages\r\n this.registerAcceptedFunctions(functionsMap);\r\n\r\n context.userDefinedFunctions = functionsMap;\r\n }\r\n\r\n /**\r\n * Check if there are any accepted functions in used packages.\r\n */\r\n private hasAcceptedFunctions(): boolean {\r\n if (!this.currentPackage) {\r\n return false;\r\n }\r\n\r\n let hasAccepted = false;\r\n this.currentPackage.usedPackages.forEach((usedPkg) => {\r\n usedPkg.acceptedComponents.forEach((component) => {\r\n if (component.type === 'function' && component.isAccepted) {\r\n hasAccepted = true;\r\n }\r\n });\r\n });\r\n return hasAccepted;\r\n }\r\n\r\n /**\r\n * Register accepted functions from used packages.\r\n * @param functionsMap The map to register functions into.\r\n */\r\n private registerAcceptedFunctions(\r\n functionsMap: Map<string, {\r\n functionDef: XNode;\r\n executor: (ctx: ExprContext, functionDef: XNode, args: any[]) => any;\r\n }>\r\n ) {\r\n if (!this.currentPackage) {\r\n return;\r\n }\r\n\r\n // Iterate through all used packages\r\n this.currentPackage.usedPackages.forEach((usedPkg, packageKey) => {\r\n // Look at accepted components\r\n usedPkg.acceptedComponents.forEach((component, componentKey) => {\r\n if (component.type === 'function' && component.name && component.isAccepted) {\r\n // Check for overrides - use the effective component\r\n const effectiveComponent = this.getEffectiveComponent(component);\r\n // Register this function\r\n functionsMap.set(component.name, {\r\n functionDef: effectiveComponent.node,\r\n executor: (ctx: ExprContext, funcDef: XNode, args: any[]) => {\r\n return this.executeUserDefinedFunctionSync(ctx, funcDef, args);\r\n }\r\n });\r\n }\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Apply one or more attribute sets to an element.\r\n * Parses space-separated attribute set names and applies them.\r\n * @param context The Expression Context.\r\n * @param element The element to apply attributes to.\r\n * @param setNames Space-separated attribute set names.\r\n */\r\n protected async applyAttributeSets(\r\n context: ExprContext,\r\n element: XNode,\r\n setNames: string\r\n ) {\r\n if (!setNames || !setNames.trim()) {\r\n return;\r\n }\r\n\r\n // Parse space-separated set names\r\n const names = setNames.trim().split(/\\s+/);\r\n const processedSets = new Set<string>();\r\n\r\n for (const name of names) {\r\n await this.applyAttributeSet(context, element, name, processedSets);\r\n }\r\n }\r\n\r\n /**\r\n * Apply a single attribute set to an element.\r\n * Handles recursive attribute sets with cycle detection.\r\n * @param context The Expression Context.\r\n * @param element The element to apply attributes to.\r\n * @param setName The name of the attribute set to apply.\r\n * @param processedSets Set of already-processed attribute set names (for cycle detection).\r\n */\r\n private async applyAttributeSet(\r\n context: ExprContext,\r\n element: XNode,\r\n setName: string,\r\n processedSets: Set<string>\r\n ) {\r\n // Prevent infinite recursion\r\n if (processedSets.has(setName)) {\r\n return;\r\n }\r\n processedSets.add(setName);\r\n\r\n const attributeNodes = this.attributeSets.get(setName);\r\n if (!attributeNodes) {\r\n // Silently ignore missing attribute set (spec allows)\r\n return;\r\n }\r\n\r\n // Apply attributes from this set\r\n for (const attrNode of attributeNodes) {\r\n // First, apply any nested attribute sets referenced by the owning attribute-set\r\n let nestedSets: string | null = null;\r\n const ownerNode = (attrNode as any).parentNode as XNode | null;\r\n if (ownerNode) {\r\n nestedSets = xmlGetAttribute(ownerNode, 'use-attribute-sets');\r\n }\r\n if (nestedSets) {\r\n // XSLT allows a whitespace-separated list of attribute-set names\r\n for (const nestedName of nestedSets.trim().split(/\\s+/)) {\r\n if (nestedName) {\r\n await this.applyAttributeSet(context, element, nestedName, processedSets);\r\n }\r\n }\r\n }\r\n\r\n // Now apply the attribute itself\r\n const nameExpr = xmlGetAttribute(attrNode, 'name');\r\n const name = this.xsltAttributeValue(nameExpr, context);\r\n\r\n // Evaluate the attribute value by processing child nodes\r\n const documentFragment = domCreateDocumentFragment(this.outputDocument);\r\n await this.xsltChildNodes(context, attrNode, documentFragment);\r\n const value = xmlValueLegacyBehavior(documentFragment);\r\n\r\n domSetAttribute(element, name, value);\r\n }\r\n }\r\n\r\n /**\r\n * Test if an element is a supported extension.\r\n * Returns false for unrecognized elements in non-XSLT namespaces.\r\n * @param node The element to test.\r\n * @returns True if the element is supported, false if it's an unrecognized extension.\r\n */\r\n protected isExtensionElementSupported(node: XNode): boolean {\r\n if (node.nodeType !== DOM_ELEMENT_NODE) {\r\n // Only elements can be extension elements; everything else is always supported.\r\n return true;\r\n }\r\n\r\n const namespaceUri = node.namespaceUri;\r\n\r\n if (!namespaceUri) {\r\n // Unqualified elements (no namespace) are treated as literal result elements.\r\n return true;\r\n }\r\n\r\n // Elements in the XSLT namespace are XSLT instructions, not extension elements.\r\n if (this.isXsltElement(node)) {\r\n return true;\r\n }\r\n\r\n // Namespaced, non-XSLT elements are considered extension elements. If the\r\n // namespace is not in the supported set, mark as unsupported so fallback can run.\r\n if (!this.supportedExtensions.has(namespaceUri)) {\r\n return false;\r\n }\r\n\r\n // The element is in a supported extension namespace.\r\n return true;\r\n }\r\n\r\n /**\r\n * Get the fallback element from an extension element if it exists.\r\n * Searches for the first direct xsl:fallback child.\r\n * @param node The extension element.\r\n * @returns The fallback element, or null if not found.\r\n */\r\n protected getFallbackElement(node: XNode): XNode | null {\r\n for (const child of node.childNodes) {\r\n if (\r\n child.nodeType === DOM_ELEMENT_NODE &&\r\n this.isXsltElement(child, 'fallback')\r\n ) {\r\n return child;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Process an extension element with fallback support.\r\n * If a fallback is defined, executes it; otherwise treats element as literal.\r\n * @param context The Expression Context.\r\n * @param element The extension element.\r\n * @param output The output node.\r\n */\r\n protected async xsltExtensionElement(\r\n context: ExprContext,\r\n element: XNode,\r\n output?: XNode\r\n ) {\r\n // Check if there's a fallback\r\n const fallback = this.getFallbackElement(element);\r\n\r\n if (fallback) {\r\n // Execute fallback content\r\n await this.xsltChildNodes(context, fallback, output);\r\n } else {\r\n // No fallback: treat as literal result element\r\n // (Copy the element and its content to output)\r\n await this.xsltPassThrough(context, element, output);\r\n }\r\n }\r\n\r\n /**\r\n * Test if the given element is an XSLT element, optionally the one with the given name.\r\n * @param {XNode} element The element.\r\n * @param {string} opt_wantedName The name for comparison.\r\n * @returns True, if element is an XSL node. False otherwise.\r\n */\r\n protected isXsltElement(element: XNode, opt_wantedName?: string) {\r\n if (opt_wantedName && element.localName != opt_wantedName) return false;\r\n if (element.namespaceUri) return element.namespaceUri === 'http://www.w3.org/1999/XSL/Transform';\r\n return element.prefix === 'xsl'; // backwards compatibility with earlier versions of xslt-processor\r\n }\r\n}\r\n"],"mappings":"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","names":["XPathExpression","init_expression","__esmMin","XPathStringLiteral","XPathNumberLiteral","init_literal_expression","__esmMin","init_expression","XPathExpression","value","_context","NodeType","XS_NAMESPACE","XPATH_ERROR_NAMESPACE","DEFAULT_FUNCTION_NAMESPACE","DEFAULT_COLLATION","RESERVED_FUNCTION_NAMES","init_constants","__esmMin","grammarViolation","message","XPathStaticError","unresolvedNameReference","name","type","unsupportedAxis","axis","functionSignatureMismatch","functionName","expectedArgs","actualArgs","typeMismatch","expected","actual","context","msg","XPathTypeError","invalidCastArgument","value","targetType","XPathDynamicError","XPathError","init_errors","__esmMin","init_constants","_XPathError","code","isStatic","isDynamic","XPATH_ERROR_NAMESPACE","_XPathStaticError","_XPathDynamicError","_XPathTypeError","XPathVariableReference","init_variable_reference_expression","__esmMin","init_expression","init_errors","XPathExpression","name","context","unresolvedNameReference","XPathStep","init_step_expression","__esmMin","init_expression","XPathExpression","axis","nodeTest","predicates","context","node","item","candidates","n","itemContext","__spreadProps","__spreadValues","predicate","result","includeSelf","walk","child","current","sibling","ancestor","descendants","_a","_b","namespaces","attrs","attr","name","value","prefix","uri","test","nodeType","matchesQName","testName","allowedNodeTypes","nsUri","colonIndex","localName","nodeLocalName","nodeNsUri","root","nodes","filtered","size","i","predicateContext","predicateResult","qname","XPathLocationPath","init_location_path_expression","__esmMin","init_expression","XPathExpression","steps","absolute","context","nodes","root","step","nextNodes","node","stepContext","__spreadProps","__spreadValues","result","seen","XPathFilterExpression","FilteredPathExpression","init_filter_expression","__esmMin","init_expression","XPathExpression","expression","predicates","context","result","predicateExpr","items","i","item","itemContext","__spreadProps","__spreadValues","value","filterExpr","pathExpr","pathResult","XPathUnaryExpression","init_unary_expression","__esmMin","init_expression","XPathExpression","operator","operand","context","value","atomic","num","trimmed","XPathBinaryExpression","init_binary_expression","__esmMin","init_expression","XPathExpression","left","right","operator","context","leftValue","rightValue","leftIsNodeSet","rightIsNodeSet","leftNode","leftStr","rightNode","rightStr","nodeSet","value","node","nodeValue","text","child","XPathArithmeticExpression","init_arithmetic_expression","__esmMin","init_expression","XPathExpression","left","right","operator","context","leftValue","rightValue","leftAtomic","rightAtomic","leftNum","rightNum","value","trimmed","XPathLogicalExpression","init_logical_expression","__esmMin","init_expression","XPathExpression","left","right","operator","value","context","leftValue","XPathConditionalExpression","init_conditional_expression","__esmMin","init_expression","XPathExpression","test","thenExpr","elseExpr","value","context","XPathForExpression","init_for_expression","__esmMin","init_expression","XPathExpression","bindings","returnExpr","context","initialVariables","__spreadValues","initialContext","__spreadProps","results","index","currentContext","_a","value","binding","sequence","size","i","item","variables","iterationContext","XPathQuantifiedExpression","init_quantified_expression","__esmMin","init_expression","XPathExpression","quantifier","bindings","satisfiesExpr","context","initialVariables","__spreadValues","initialContext","__spreadProps","index","currentContext","_a","binding","sequence","i","item","variables","iterationContext","value","AtomicTypeImpl","init_base","__esmMin","init_constants","name","namespace","XS_NAMESPACE","baseType","primitive","sequence_type_exports","__export","ITEM_TYPE","OccurrenceIndicator","SequenceType","createAtomicSequenceType","createEmptySequenceType","createItemSequenceType","itemType","occurrence","atomicType","value","e","init_sequence_type","__esmMin","typeName","indicator","other","otherMin","otherMax","thisMin","thisMax","thisItemType","otherItemType","KindTestImpl","NodeKindTest","ElementTest","AttributeTest","DocumentNodeTest","TextTest","CommentTest","ProcessingInstructionTest","KIND_TESTS","init_kind_tests","__esmMin","name","nodeKind","nodeName","nodeType","isWildcardName","value","elementName","elementType","attributeName","attributeType","elementTest","target","union_type_exports","__export","UnionItemType","createUnionType","isUnionType","memberTypes","itemType","init_union_type","__esmMin","_UnionItemType","value","memberType","typeName","flattenedTypes","nested","uniqueTypes","type","index","self","t","atomicTypes","matchesItemType","value","itemType","isUnionType","hasMapTest","hasArrayTest","hasFunctionTest","matchesSequenceType","values","sequenceType","sequence","v","typedItemType","unmatched","item","unmatchedItem","itemDesc","e","occurrence","itemCount","init_sequence_type_matcher","__esmMin","init_sequence_type","isNode","value","hasElementOnlyContent","node","child","getNodeTypedValue","atomicType","getAtomicType","textContent","getNodeStringValue","e","result","atomize","strict","results","resultType","hasError","errorCode","item","atomizedValue","type","init_atomization","__esmMin","init_types","isXPathMap","value","XPathMapConstructorExpression","init_map_constructor_expression","__esmMin","init_atomization","init_errors","entries","context","result","entry","keyResult","atomicKeys","atomize","typeMismatch","key","keyString","map","isXPathArray","value","createXPathArray","members","getArraySize","arr","getArrayMember","position","XPathSquareBracketArrayConstructor","XPathCurlyBraceArrayConstructor","init_array_constructor_expression","__esmMin","items","context","item","i","expr","result","typed_collection_types_exports","__export","createTypedArrayTest","createTypedMapTest","isTypedArrayTest","isTypedMapTest","keyType","valueType","isWildcardMapTest","formatMapTypeName","value","isXPathMap","entries","key","val","matchesSequenceType","memberType","isWildcardArrayTest","formatArrayTypeName","isXPathArray","members","member","keyStr","valueStr","itemType","init_typed_collection_types","__esmMin","init_map_constructor_expression","init_array_constructor_expression","init_sequence_type_matcher","init_type_promotion","__esmMin","init_types","AnyAtomicTypeImpl","UntypedAtomicImpl","StringTypeImpl","BooleanTypeImpl","init_simple_types","__esmMin","init_base","AtomicTypeImpl","XS_NAMESPACE","value","baseType","trimmed","DecimalTypeImpl","FloatTypeImpl","DoubleTypeImpl","IntegerTypeImpl","init_numeric_types","__esmMin","init_base","AtomicTypeImpl","baseType","XS_NAMESPACE","value","num","primitive","intVal","parseDuration","value","match","component","isNegative","sign","parseTime","hours","minutes","seconds","timezone","DurationTypeImpl","DateTimeTypeImpl","DateTypeImpl","TimeTypeImpl","init_datetime_types","__esmMin","init_base","AtomicTypeImpl","baseType","XS_NAMESPACE","date","primitive","dateTime","GYearMonthTypeImpl","GYearTypeImpl","GMonthDayTypeImpl","GDayTypeImpl","GMonthTypeImpl","init_gregorian_types","__esmMin","init_base","AtomicTypeImpl","baseType","XS_NAMESPACE","value","match","year","month","day","HexBinaryTypeImpl","Base64BinaryTypeImpl","init_binary_types","__esmMin","init_base","AtomicTypeImpl","baseType","XS_NAMESPACE","value","b","chars","result","i","len","a","hasB","hasC","c","bitmap","AnyURITypeImpl","QNameTypeImpl","init_uri_qname_types","__esmMin","init_base","AtomicTypeImpl","baseType","XS_NAMESPACE","value","parts","IntegerDerivedTypeImpl","init_integer_derived_types","__esmMin","init_base","AtomicTypeImpl","name","baseType","primitive","min","max","XS_NAMESPACE","value","num","function_type_exports","__export","ARRAY_NAMESPACE","FN_NAMESPACE","MAP_NAMESPACE","MATH_NAMESPACE","createFunctionItem","createFunctionTest","createFunctionType","describeFunctionType","isFunctionItem","implementation","arity","name","namespace","type","parameterTypes","returnType","opts","_a","_b","isWildcard","paramCount","p","value","isFunctionItemLike","isTypedMap","isTypedArray","observedArity","init_function_type","__esmMin","init_psvi","__esmMin","init_schema_aware_types","__esmMin","init_psvi","getAtomicType","name","ATOMIC_TYPES","castAs","value","typeName","type","anyAtomicType","untypedAtomic","stringType","booleanType","decimalType","floatType","doubleType","durationType","dateTimeType","dateType","timeType","anyURIType","qnameType","gYearMonthType","gYearType","gMonthDayType","gDayType","gMonthType","hexBinaryType","base64BinaryType","integerType","longType","intType","shortType","byteType","nonPositiveIntegerType","negativeIntegerType","nonNegativeIntegerType","positiveIntegerType","unsignedLongType","unsignedIntType","unsignedShortType","unsignedByteType","init_types","__esmMin","init_base","init_sequence_type","init_kind_tests","init_sequence_type_matcher","init_typed_collection_types","init_union_type","init_type_promotion","init_atomization","init_simple_types","init_numeric_types","init_datetime_types","init_gregorian_types","init_binary_types","init_uri_qname_types","init_integer_derived_types","init_function_type","init_schema_aware_types","AnyAtomicTypeImpl","UntypedAtomicImpl","StringTypeImpl","BooleanTypeImpl","DecimalTypeImpl","FloatTypeImpl","DoubleTypeImpl","DurationTypeImpl","DateTimeTypeImpl","DateTypeImpl","TimeTypeImpl","AnyURITypeImpl","QNameTypeImpl","GYearMonthTypeImpl","GYearTypeImpl","GMonthDayTypeImpl","GDayTypeImpl","GMonthTypeImpl","HexBinaryTypeImpl","Base64BinaryTypeImpl","IntegerTypeImpl","IntegerDerivedTypeImpl","XPathInstanceOfExpression","init_instance_of_expression","__esmMin","init_types","init_expression","XPathExpression","expression","sequenceType","context","value","matchesSequenceType","XPathCastableExpression","init_castable_expression","__esmMin","init_types","init_sequence_type","init_expression","XPathExpression","expression","sequenceType","context","value","sequence","item","itemType","castAs","e","XPathTreatExpression","init_treat_expression","__esmMin","init_expression","init_sequence_type_matcher","XPathExpression","expression","sequenceType","context","_a","value","result","matchesSequenceType","reason","XPathUnionExpression","init_union_expression","__esmMin","init_expression","XPathExpression","left","right","context","leftResult","rightResult","leftNodes","rightNodes","seen","result","node","nodes","a","b","position","createSequence","value","items","flattenSequence","concatenateSequences","sequences","result","seq","isXPathNode","getNodeId","node","CommaExpression","RangeExpression","EmptySequenceExpression","ParenthesizedExpression","init_sequence_construction","__esmMin","init_expression","XPathExpression","operands","context","operand","op","startExpr","endExpr","startValue","endValue","start","end","startItem","endItem","e","i","num","XPathPredicate","init_predicate_expression","__esmMin","init_expression","XPathExpression","expression","context","result","value","ValueComparisonExpression","init_value_comparison","__esmMin","init_expression","XPathExpression","left","operator","right","context","leftValue","rightValue","leftAtom","rightAtom","value","promotedLeft","promotedRight","num","node","GeneralComparisonExpression","init_general_comparison","__esmMin","init_expression","XPathExpression","left","operator","right","context","leftValue","rightValue","leftItems","rightItems","value","result","item","leftVal","rightVal","promotedLeft","promotedRight","num","node","NodeComparisonExpression","init_node_comparison","__esmMin","init_expression","XPathExpression","left","operator","right","context","leftValue","rightValue","leftNode","rightNode","value","leftPos","rightPos","node","leftAncestors","rightAncestors","i","leftChild","rightChild","leftPosition","rightPosition","ancestors","current","children","JsonToXmlConverter","init_json_to_xml_converter","__esmMin","init_constants","jsonText","options","trimmedText","jsonValue","error","fallbackValue","fallbackError","value","rootElement","documentNode","NodeType","elementName","parent","element","childNodes","seenKeys","key","sanitizedKey","childElement","item","index","textNode","textValue","name","sanitized","lenient","e","forEach","context","seq","action","isFunctionItem","funcItem","items","results","item","result","filter","predicate","foldLeft","zero","f","accumulator","foldRight","i","forEachPair","seq1","seq2","items1","items2","minLength","apply","func","array","args","functionName","functionArity","init_higher_order_functions","__esmMin","init_function_type","pi","context","exp","arg","value","toNumber","exp10","log","log10","pow","x","y","base","exponent","sqrt","sin","cos","tan","asin","acos","atan","atan2","yValue","xValue","init_math_functions","__esmMin","head","arg","tail","unordered","sourceSeq","toSequence","zeroOrOne","seq","typeMismatch","oneOrMore","exactlyOne","value","init_sequence_functions","__esmMin","init_errors","innermost","context","nodes","nodeList","node","isNode","otherNode","isAncestor","outermost","sort","input","collation","keyFn","items","indexed","item","index","a","b","keyA","keyB","compareValues","x","value","potential","current","depth","MAX_DEPTH","visited","aStr","bStr","init_sequence_functions_30","__esmMin","init_sequence_functions","environmentVariable","context","name","varName","value","availableEnvironmentVariables","init_environment_functions","__esmMin","analyzeString","context","input","pattern","flags","str","pat","flgs","regexFlags","regex","result","lastIndex","match","g","e","formatInteger","value","picture","lang","num","pic","intValue","isNegative","absValue","toLetters","toRoman","toWords","c","paddingMatch","padLength","formatNumber","formatName","parts","integerPart","decimalPart","minIntDigits","minDecDigits","maxDecDigits","decimals","intPart","decPart","paddedInt","baseChar","base","n","romanMap","numeral","ones","teens","tens","scales","scaleIndex","chunk","convertHundreds","hundreds","remainder","tenDigit","oneDigit","init_string_functions_30","__esmMin","requireArray","value","funcName","isXPathArray","validatePosition","arr","position","arraySize","context","array","arrayGet","arrayPut","member","newMembers","createXPathArray","arrayAppend","appendage","arraySubarray","start","length","startIdx","arrayRemove","positions","posArray","pos","indicesToRemove","p","_","idx","arrayInsertBefore","arrayHead","arrayTail","arrayReverse","arrayJoin","arrays","arrList","allMembers","xpathArr","arrayFlatten","input","result","flatten","item","elem","arrayForEach","action","fn","index","arrayFilter","predicate","filteredMembers","arrayFoldLeft","zero","f","accumulator","arrayFoldRight","i","arraySort","collation","key","keyFn","indexedMembers","b","aKey","bKey","aStr","bStr","init_array_functions","__esmMin","init_array_constructor_expression","requireMap","value","funcName","isXPathMap","cloneMap","map","newMap","mapSize","context","m","k","mapKeys","mapContains","key","mapGet","mapPut","mapEntry","mapMerge","maps","options","mapList","duplicateHandling","validOptions","result","keyOccurrences","mm","mapForEach","fn","impl","v","mapRemove","keys","keyList","toRemove","init_map_functions","__esmMin","init_map_constructor_expression","jsToXPath","value","createXPathArray","map","k","v","XPathError","processLiberalJson","json","result","i","inString","stringChar","escaped","char","nextChar","j","parseJsonImpl","jsonString","options","opts","isXPathMap","dups","processedJson","parsed","e","parseJson","_contextOrJson","jsonStringOrOptions","xpathToJs","isXPathArray","obj","serializeImpl","ind","meth","toSerialize","jsValue","indent","serialize","_contextOrValue","valueOrOptions","jsonToXmlImpl","JsonToXmlConverter","jsonToXml","init_json_functions","__esmMin","init_map_constructor_expression","init_array_constructor_expression","init_errors","init_json_to_xml_converter","init_constants","QName","paramURI","paramQName","uri","toString","qname","colonIndex","prefix","localName","isValidNCName","resolveQName","element","_a","_b","qnameStr","elem","getElement","defaultNS","ns","getNamespaceForPrefix","prefixFromQName","arg","effectiveQName","closeBrace","localNameFromQName","namespaceUriFromQName","inScopePrefixes","prefixes","current","attrs","i","attr","name","namespaceUriForPrefix","prefixStr","value","node","NodeType","firstChar","attrName","init_qname_functions","__esmMin","init_constants","resolveUri","relative","base","context","_a","rel","toString","baseUri","e","encodeForUri","uriPart","str","ch","iriToUri","iri","escapeHtmlUri","uri","value","init_uri_functions","__esmMin","nodeName","arg","context","_a","node","getNode","nodeType","nilled","nilAttr","data","items","result","item","atomize","baseUri","_b","xmlBase","isNode","documentUri","root","current","depth","visited","lang","testlang","nodeArg","targetLang","toString","langAttr","nodeLang","generateId","idSymbol","timestamp","random","counter","path","pathSegments","segment","buildPathSegment","hasChildren","value","getStringValue","getDescendantTextContent","parts","child","parent","siblings","n","position","init_node_functions","__esmMin","function_call_expression_exports","__export","XPathFunctionCall","getBuiltInFunction","getBuiltInFunctionArity","name","BUILT_IN_FUNCTIONS","FUNCTION_ARITY","toStringValue","init_function_call_expression","__esmMin","init_expression","init_json_to_xml_converter","init_types","init_errors","init_higher_order_functions","init_math_functions","init_sequence_functions_30","init_sequence_functions","init_environment_functions","init_string_functions_30","init_array_functions","init_map_functions","init_json_functions","init_qname_functions","init_uri_functions","init_node_functions","arg","_a","firstNode","_ctx","args","a","seq","sep","s","str","start","len","startIdx","length","adjustedStart","sub","from","to","f","t","result","char","idx","input","pattern","replacement","regex","precision","p","n","floor","acc","val","v","pos","inserts","position","ctx","_b","_c","_d","node","generateId","path","hasChildren","forEach","filter","foldLeft","foldRight","forEachPair","sort","apply","functionName","functionArity","pi","exp","exp10","log","log10","pow","sqrt","sin","cos","tan","asin","acos","atan","atan2","head","tail","innermost","outermost","environmentVariable","availableEnvironmentVariables","arraySize","arrayGet","arrayPut","arrayAppend","arraySubarray","arrayRemove","arrayInsertBefore","arrayHead","arrayTail","arrayReverse","arrayJoin","arrayFlatten","arrayForEach","arrayFilter","arrayFoldLeft","arrayFoldRight","arraySort","mapSize","mapKeys","mapContains","mapGet","mapPut","mapEntry","mapMerge","mapForEach","mapRemove","parseJson","serialize","jsonToXml","analyzeString","formatInteger","formatNumber","castAs","uri","qname","QName","element","resolveQName","prefixFromQName","localNameFromQName","namespaceUriFromQName","inScopePrefixes","prefix","namespaceUriForPrefix","relative","base","resolveUri","uriPart","encodeForUri","iri","iriToUri","escapeHtmlUri","root","baseUri","documentUri","nilled","nodeName","data","testlang","lang","zeroOrOne","oneOrMore","exactlyOne","unordered","XPathExpression","JsonToXmlConverter","context","_e","_f","evaluatedArgs","constructorType","functionSignatureMismatch","raw","typeMismatch","groupIndex","regexGroups","currentGroup","currentGroupingKey","builtInFunc","localName","namespace","unresolvedNameReference","match","getAtomicType","value","err","invalidCastArgument","toNumberFromString","text","trimmed","stringValue","i","child","search","index","adjustedLength","nodeSet","targetLang","nodeLang","jsonText","options","documentNode","optionsMap","dup","XPathLetExpression","init_let_expression","__esmMin","init_expression","XPathExpression","bindings","returnExpr","context","_a","variables","__spreadValues","currentContext","__spreadProps","binding","value","b","XPathSimpleMapExpression","init_simple_map_expression","__esmMin","init_expression","XPathExpression","left","right","context","leftValue","sequence","results","size","i","item","itemContext","__spreadProps","__spreadValues","rightValue","value","XPathStringConcatExpression","init_string_concat_expression","__esmMin","init_expression","XPathExpression","left","right","context","leftValue","rightValue","leftStr","rightStr","value","node","parseStringTemplate","template","parts","current","i","char","depth","j","exprStr","StringTemplateExpression","init_string_template_expression","__esmMin","context","result","part","value","str","node","_a","_b","child","XPathArrowExpression","init_arrow_expression","__esmMin","init_expression","init_function_call_expression","XPathExpression","input","functionName","args","context","allArgs","XPathFunctionCall","argsStr","a","XPathNamedFunctionRef","init_named_function_ref_expression","__esmMin","init_function_type","init_expression","init_function_call_expression","XPathExpression","name","arity","context","funcItem","parsedNamespace","localName","namespace","builtIn","getBuiltInFunction","lookupName","MATH_NAMESPACE","getBuiltInFunctionArity","args","registeredFunc","customFunc","funcName","range","match","uri","colonIndex","prefix","FN_NAMESPACE","XPathInlineFunctionExpression","init_inline_function_expression","__esmMin","init_expression","XPathExpression","params","body","returnType","context","_a","closureVariables","__spreadValues","self","args","variables","i","param","arg","evalContext","__spreadProps","result","p","s","isFunctionItem","value","XPathDynamicFunctionCall","init_dynamic_function_call_expression","__esmMin","init_expression","init_map_constructor_expression","init_array_constructor_expression","XPathExpression","functionExpr","args","context","funcValue","isXPathMap","key","isXPathArray","position","getArrayMember","funcItem","evaluatedArgs","arg","argsStr","a","createTryExpression","tryExpression","catchExpression","errorPattern","errorVariableName","TryExpression","createTryOnly","createTryWithFallback","fallbackValue","fallbackExpr","XPathExpression","safeEvaluate","expr","context","XSLT3ErrorCodes","init_try_expression","__esmMin","init_expression","result","error","caughtError","catchContext","code","description","type","pattern","KeySpecifierType","XPathLookupExpression","init_lookup_expression","__esmMin","init_array_constructor_expression","init_map_constructor_expression","baseExpr","keySpecifier","context","target","isXPathMap","isXPathArray","map","key","intKey","dynamicKey","stringKey","array","position","dynamicPos","positionNum","members","result","member","value","e","num","str","base","keyStr","expressions_exports","__export","CommaExpression","EmptySequenceExpression","FilteredPathExpression","GeneralComparisonExpression","JsonToXmlConverter","KeySpecifierType","NodeComparisonExpression","ParenthesizedExpression","RangeExpression","StringTemplateExpression","TryExpression","ValueComparisonExpression","XPathArithmeticExpression","XPathArrowExpression","XPathBinaryExpression","XPathCastableExpression","XPathConditionalExpression","XPathCurlyBraceArrayConstructor","XPathDynamicFunctionCall","XPathExpression","XPathFilterExpression","XPathForExpression","XPathFunctionCall","XPathInlineFunctionExpression","XPathInstanceOfExpression","XPathLetExpression","XPathLocationPath","XPathLogicalExpression","XPathLookupExpression","XPathMapConstructorExpression","XPathNamedFunctionRef","XPathNumberLiteral","XPathPredicate","XPathQuantifiedExpression","XPathSimpleMapExpression","XPathSquareBracketArrayConstructor","XPathStep","XPathStringConcatExpression","XPathStringLiteral","XPathTreatExpression","XPathUnaryExpression","XPathUnionExpression","XPathVariableReference","XSLT3ErrorCodes","concatenateSequences","createSequence","createTryExpression","createTryOnly","createTryWithFallback","createXPathArray","flattenSequence","getArrayMember","getArraySize","getBuiltInFunction","getBuiltInFunctionArity","getNodeId","isXPathArray","isXPathMap","isXPathNode","parseStringTemplate","safeEvaluate","init_expressions","__esmMin","init_expression","init_literal_expression","init_variable_reference_expression","init_step_expression","init_location_path_expression","init_filter_expression","init_unary_expression","init_binary_expression","init_arithmetic_expression","init_logical_expression","init_conditional_expression","init_for_expression","init_quantified_expression","init_instance_of_expression","init_castable_expression","init_treat_expression","init_union_expression","init_sequence_construction","init_predicate_expression","init_value_comparison","init_general_comparison","init_node_comparison","init_function_call_expression","init_json_to_xml_converter","init_let_expression","init_simple_map_expression","init_string_concat_expression","init_string_template_expression","init_arrow_expression","init_named_function_ref_expression","init_inline_function_expression","init_dynamic_function_call_expression","init_try_expression","init_map_constructor_expression","init_array_constructor_expression","init_lookup_expression","src_exports","__export","ExprContext","XDocument","XNode","XPath","XmlParser","Xslt","domDocumentToXDocument","xmlEscapeText","XPathToken","type","lexeme","DEFAULT_LEXER_VERSION","COMMON_RESERVED_WORDS","XPATH20_RESERVED_WORDS","XPATH30_RESERVED_WORDS","XPATH31_RESERVED_WORDS","buildReservedWords","version","merged","__spreadValues","XPathLexer","versionOrOptions","_a","functionNames","name","char","expected","firstCharacter","characters","nextChar","likelyReservedWord","XPathToken","quoteChar","value","depth","uri","localName","fullEQName","expression","token","init_expressions","init_sequence_type","init_constants","ensureDefaultCollationPresent","collations","defaultCollation","createStaticContext","overrides","_a","_b","_c","_d","_e","_f","_g","_h","_i","_j","reserved","RESERVED_FUNCTION_NAMES","DEFAULT_COLLATION","XS_NAMESPACE","DEFAULT_FUNCTION_NAMESPACE","validateExtensions","extensions","errors","functionNames","func","init_errors","WARNING_CODES","DEFAULT_WARNING_CONFIG","SEVERITY_LEVELS","WarningCollector","config","__spreadValues","code","context","expression","metadata","warning","prefix","severity","w","category","lines","byCategory","warnings","formatCategoryName","createWarningCollector","config","WarningCollector","XPathBaseParser","options","_a","_b","_c","_d","createStaticContext","createWarningCollector","errors","validateExtensions","supportedVersions","defaultVersion","resolvedVersion","tokens","t","grammarViolation","expr","type","lexeme","types","message","left","right","XPathLogicalExpression","operator","XPathBinaryExpression","XPathArithmeticExpression","operand","XPathUnaryExpression","XPathUnionExpression","isDescendant","steps","XPathStep","locationPath","XPathLocationPath","FilteredPathExpression","token","next","nodeTestNames","absolute","axis","unsupportedAxis","nodeTest","predicates","testName","name","target","localName","XPathPredicate","XPathFilterExpression","XPathVariableReference","EmptySequenceExpression","value","XPathStringLiteral","XPathNumberLiteral","local","args","XPathFunctionCall","first","second","isNodeTestName","afterLocal","elementType","elementTest","XPath10Parser","XPathBaseParser","options","init_expressions","init_types","XPath20Parser","XPathBaseParser","options","left","right","XPathUnionExpression","_a","_b","name","XPathVariableReference","expr","sequenceType","XPathInstanceOfExpression","XPathTreatExpression","XPathCastableExpression","testExpr","thenExpr","elseExpr","XPathConditionalExpression","quantifier","bindings","satisfiesExpr","XPathQuantifiedExpression","returnExpr","XPathForExpression","expression","createEmptySequenceType","occurrence","createItemSequenceType","ITEM_TYPE","keyType","valueType","createTypedMapTest","mapItemType","memberType","createTypedArrayTest","arrayItemType","qname","localName","atomicType","getAtomicType","createAtomicSequenceType","operator","RangeExpression","first","local","parts","message","type","word","words","init_expressions","init_let_expression","init_simple_map_expression","init_string_concat_expression","init_string_template_expression","init_arrow_expression","init_named_function_ref_expression","init_inline_function_expression","init_dynamic_function_call_expression","init_types","init_errors","XPath30Parser","XPath20Parser","options","opts","__spreadValues","first","operands","CommaExpression","left","operator","right","XPathStringConcatExpression","XPathSimpleMapExpression","expr","sequenceType","funcExpr","args","varName","XPathVariableReference","XPathDynamicFunctionCall","name","local","XPathArrowExpression","XPathFunctionCall","template","nameToken","predicates","XPathFilterExpression","token","next","lookAhead","foundHash","tok","op","nextToken","grammarViolation","arityToken","arity","XPathNamedFunctionRef","params","paramName","paramType","returnType","body","XPathInlineFunctionExpression","bindings","returnExpr","XPathLetExpression","type","expression","word","message","_a","_b","createEmptySequenceType","occurrence","createItemSequenceType","ITEM_TYPE","keyType","valueType","createTypedMapTest","mapItemType","memberType","createTypedArrayTest","arrayItemType","parameterTypes","createFunctionTest","functionItemType","qname","localName","atomicType","getAtomicType","createAtomicSequenceType","parts","rawParts","parseStringTemplate","part","tokens","XPathLexer","ParserClass","StringTemplateExpression","init_map_constructor_expression","init_array_constructor_expression","init_lookup_expression","XPath31Parser","XPath30Parser","options","opts","__spreadValues","_a","_b","_c","prefix","localName","fullName","args","XPathFunctionCall","entries","XPathMapConstructorExpression","key","value","items","XPathSquareBracketArrayConstructor","item","XPathCurlyBraceArrayConstructor","expr","baseExpr","_d","_e","keySpecifier","numToken","position","name","XPathLookupExpression","firstType","memberTypes","nextType","createUnionType","createItemSequenceType","itemTypes","st","itemType","occurrence","unionItemType","createXPathParser","version","options","fullOptions","__spreadProps","__spreadValues","XPath10Parser","XPath20Parser","XPath30Parser","XPath31Parser","init_expressions","_XNode","type","name","opt_value","opt_owner","opt_namespace","value","owner","namespaceUri","node","opt_pre","opt_post","ret","c","namespace","newOwner","newNode","child","oldNode","i","p","newChildren","n","attributes","newAttribute","attribute","localName","newChildNodes","childNode","self","id","XNode","XDocument","XNode","node","name","namespace","value","data","target","domDocumentToXDocument","nativeNode","xDoc","XDocument","childNodes","i","converted","convertNode","ownerDoc","element","xNode","XNode","attrs","attr","attrNode","pi","dt","fragment","domGetAttributeValue","node","name","domSetAttribute","value","domAppendChild","child","domCreateTextNode","text","domCreateElement","doc","domCreateCDATASection","data","domCreateComment","domCreateDocumentFragment","domCreateDTDSection","domCreateProcessingInstruction","target","NAMED_ENTITIES","htmlEntityDecode","text","result","match","entity","lower","code","num","e","xmlValue","node","disallowBrowserSpecificOptimization","ret","browserNode","innerText","textContent","textNodes","n","i","xmlValueLegacyBehavior","returnedXmlString","len","xmlTransformedText","node","options","buffer","xmlTransformedTextRecursive","nodeType","nodeValue","isFromXslText","finalText","xmlEscapeText","xmlUnescapeText","xmlElementLogicTextOnly","xmlElementLogicTrivial","xmlElementLogicMuted","childNodes","child","a","b","i","xmlFullNodeName","attributes","n","attribute","xmlEscapeAttr","nodeName","text","s","xmlGetAttribute","name","value","domGetAttributeValue","htmlEntityDecode","nodeToJsonObject","node","nodeType","text","children","childObjects","i","child","childObj","obj","element","hasAttributes","attr","textContent","hasElementChildren","childElements","childType","childElement","childName","detectAdaptiveOutputFormat","elementCount","textCount","hasSignificantText","xmlToJson","rootElement","rootName","jsonObj","elementContent","cleaned","error","XML_S","XML_EQ","XML_CHAR_REF","XML10_VERSION_INFO","XML10_BASE_CHAR","XML10_IDEOGRAPHIC","XML10_COMBINING_CHAR","XML10_DIGIT","XML10_EXTENDER","XML10_LETTER","XML10_NAME_CHAR","XML10_NAME","XML10_ENTITY_REF","XML10_REFERENCE","XML10_ATT_VALUE","XML10_ATTRIBUTE","XML11_VERSION_INFO","XML11_NAME_START_CHAR","XML11_NAME_CHAR","XML11_NAME","XML11_ENTITY_REF","XML11_REFERENCE","XML11_ATT_VALUE","XML11_ATTRIBUTE","XML_NC_NAME_CHAR","XML_NC_NAME","XmlParser","XML10_NAME","XML10_ATTRIBUTE","XML11_NAME","XML11_ATTRIBUTE","xmlOrHtml","node","map","i","childNode","prefix","htmlText","xmlDocument","XDocument","root","stack","parent","tag","quotes","doublequotes","start","char","text","empty","tagName","domCreateElement","attribute","val","htmlEntityDecode","domSetAttribute","domAppendChild","domCreateTextNode","endTagIndex","domCreateComment","dtdValue","domCreateDTDSection","xml","regexTagname","regexAttribute","XML10_VERSION_INFO","XML11_VERSION_INFO","tagname","namespaceMap","domCreateCDATASection","createContext","node","options","__spreadValues","NodeSetValue","value","xmlValue","StringValue","value","text","NumberValue","value","BooleanValue","value","MapValue","value","clean","key","ArrayValue","value","FunctionValue","value","init_json_to_xml_converter","NodeConverter","exprContext","currentNode","xpathNode","nodeList","node","extensions","ctx","createContext","adapted","text","child","name","XNode","variables","contexts","i","current","value","nodeValue","n","functions","_context","keyName","keyValue","_a","keyDef","number","format","decimalFormatName","settings","nodes","jsonText","jsonStr","JsonToXmlConverter","ownerDoc","convertedNode","propertyName","propName","systemProperties","elementName","xsltElements","normalizedName","functionName","xpathCoreFunctions","xsltFunctions","additionalFunctions","uriOrNodeSet","_baseNode","_b","uri","doc","e","entityName","funcInfo","funcName","args","rootChild","textContent","childXPathNode","childXNode","xmlValue","result","NodeSetValue","StringValue","item","NumberValue","BooleanValue","MapValue","ArrayValue","FunctionValue","init_expressions","Expression","xpathExpression","nodeConverter","XPathLocationPath","step","index","ctx","xpathCtx","result","context","xpathContext","LocationExpr","Expression","xpathExpression","nodeConverter","step","predicates","UnionExpr","Expression","xpathExpression","nodeConverter","expr1","expr2","XPath","NodeConverter","version","v","XPathLexer","createXPathParser","expression","axis","cacheKey","lexer","parser","tokens","xpathExpr","wrappedExpr","select","context","effectiveVersion","sort","sortList","i","node","sortItem","clonedContext","s","value","evalue","nodes","v1","v2","o","XPathLocationPath","LocationExpr","XPathUnionExpression","expr1","expr2","UnionExpr","Expression","TOK_NUMBER","ExprContext","_ExprContext","nodeList","xsltVersion","opt_position","opt_decimalFormatSettings","opt_variables","opt_knownNamespaces","opt_parent","opt_caseInsensitive","opt_ignoreAttributesWithoutValue","opt_returnOnFirstMatch","opt_ignoreNonElementNodesForNTA","opt_warningsCallback","opt_nodeList","name","value","StringValue","BooleanValue","NumberValue","NodeSetValue","MapValue","ArrayValue","FunctionValue","TOK_NUMBER","index","_a","position","caseInsensitive","ignore","returnOnFirstMatch","ignoreNonElementNodesForNTA","MatchResolver","expression","context","LocationExpr","UnionExpr","e","contextNode","clonedContext","matchedNodes","finalList","element","_a","firstChildOfRoot","c","nodeList","nodes","NodeTestAny","BooleanValue","NodeTestComment","ctx","BooleanValue","NodeTestElementOrAttribute","context","node","BooleanValue","NodeTestName","name","nameAndNamespacePrefix","context","node","BooleanValue","NodeTestNC","nsprefix","ctx","n","BooleanValue","NodeTestPI","target","context","node","BooleanValue","NodeTestText","ctx","BooleanValue","makeComponentKey","component","isComponentVisible","fromPackage","canOverrideComponent","PackageRegistry","pkg","key","name","version","exactKey","exactMatch","matchingPackages","b","packageVersion","constraint","c","prefix","pkgParts","prefixParts","i","operatorMatch","operator","targetVersion","comparison","a","aParts","p","bParts","maxLength","aPart","bPart","packageKey","StreamablePatternValidator","pattern","issues","predicateMatches","predicate","parts","p","StreamingContext","copy","copyId","c","name","event","StreamingCopyManager","handler","id","copy","event","__async","copyId","StreamingMergeCoordinator","source","s","minSource","minKey","result","StreamingModeDetector","templateNode","_a","streamableAttr","nonStreamableInstructions","StreamingParserBase","source","handler","__async","document","XmlParser","child","node","depth","_a","_b","_c","_d","_e","attributeNodes","n","attributes","attribute","nonAttributeChildren","text","StreamingProcessor","options","StreamingContext","StreamingCopyManager","StreamingMergeCoordinator","StreamingParserBase","version","parser","pattern","StreamablePatternValidator","templateNode","StreamingModeDetector","exprContext","template","output","childProcessor","__async","select","xmlGetAttribute","previouslyEnabled","contextClone","selectedValue","nodes","node","child","copy","event","sources","selectAttr","source","keyChild","keySelect","order","result","s","item","mergeContext","calculateStepPriority","step","nodeTest","NodeTestAny","NodeTestElementOrAttribute","NodeTestText","NodeTestComment","NodeTestPI","NodeTestNC","NodeTestName","calculateLocationPathPriority","expr","axis","matchesMode","template","mode","templateMode","isTemplate","node","calculateSinglePatternPriority","pattern","xPath","expr","LocationExpr","calculateLocationPathPriority","e","collectAndExpandTemplates","stylesheetElement","templateSourceMap","_a","templates","docOrder","child","match","priorityAttr","explicitPriority","metadata","importPrecedence","DEPTH_WEIGHT","depthComponent","orderComponent","alternatives","splitUnionPattern","alternative","defaultPriority","effectivePriority","current","depth","inSingleQuote","inDoubleQuote","i","char","nodeMatchesSinglePattern","context","matchResolver","attrPattern","attrName","patternLocalName","evaluationPattern","rootContext","n","nodeContext","nodeMatchesPattern","alt","selectBestTemplate","warningsCallback","warn","matching","currentNode","t","a","b","winner","conflicts","emitConflictWarning","result","patterns","AccumulatorRegistry","definition","name","state","Xslt","options","PackageRegistry","AccumulatorRegistry","XPath","XmlParser","MatchResolver","uri","__async","globalFetch","StreamingProcessor","xmlDoc","stylesheet","outputDocument","xmlToJson","outputMethod","detectAdaptiveOutputFormat","serializationMethod","xmlTransformedText","XDocument","expressionContext","ExprContext","parameter","context","template","output","node","select","value","nodes","xmlGetAttribute","destinationNode","i","domCreateTextNode","domAppendChild","parent","elementName","fallback","_a","_b","_c","onEmpty","onNonEmpty","effectiveMode","top","expandedTemplates","collectAndExpandTemplates","paramContext","modifiedContext","j","currentNode","textNodeContext","textSelection","selectBestTemplate","metadata","matchPattern","modeAttr","previousOverrideContext","overrideContext","oldTextNodeContext","clonedContext","selection","emitConflictWarning","childNodes","n","k","childNode","textContext","childContext","childSelection","childMetadata","childMatchPattern","childModeAttr","mode","currentTemplateContext","currentDepth","currentMode","stylesheetRoots","doc","rootElement","child","allTemplates","docOrderOffset","root","templates","templateEntry","importedTemplates","t","nodeContext","importedContext","nameExpr","name","documentFragment","domCreateDocumentFragment","xmlValueLegacyBehavior","domSetAttribute","prefix","nsUri","nsAttr","foundTemplate","usedPkg","component","domGetAttributeValue","test","destination","source","domCreateElement","domCreateCDATASection","domCreateComment","commentData","xmlValue","commentNode","target","data","pi","domCreateProcessingInstruction","resolvedOutput","decimalSeparator","groupingSeparator","infinity","minusSign","naN","percent","perMille","zeroDigit","digit","patternSeparator","useAttributeSets","initialValue","as","streamableStr","streamable","rules","match","phase","definition","initialResult","state","e","allAccumulators","accumulator","rule","matchContext","matchedNodes","ruleContext","StringValue","newValue","accumulatorName","sortContext","groupBy","groupAdjacent","groupStartingWith","groupEndingWith","groupingMethods","m","items","groups","group","groupContext","keyExpr","groupMap","groupOrder","item","itemContext","keyString","key","currentKey","currentGroup","pattern","groupIndex","selfPattern","matches","onCompletionElements","onCompletion","completionContext","accumulators","paramElements","paramNode","paramName","selectValue","iterationContext","accName","allBodyNodes","bodyNode","elem","nextIterationElements","nextIteration","withParamElements","withParam","tryBodyNodes","catchElements","error","errorCode","caught","catchElement","errorsAttr","errorPatterns","p","xpathAttr","xpathExpr","contextItem","contextItemAttr","evalContext","result","arrayItems","textNode","isImport","hrefAttributeFind","href","fetchResponse","includedXslt","stylesheetRoot","version","packageVersion","declaredModes","inputTypeAnnotations","packageKey","wasAlreadyLoading","pkg","previousPackage","packageDoc","packageRoot","tempContext","usedPackage","componentType","names","visibility","nameList","actualComponent","makeComponentKey","type","templateName","functionName","varName","setName","visibilityOverride","parentUsePackage","packageName","componentsToAccept","isComponentVisible","componentName","acceptedComponent","__spreadProps","__spreadValues","componentKey","localName","componentMatch","originalComponent","identifier","canOverrideComponent","overridingComponent","namePatterns","results","isWildcard","templateOverrideContext","originalNode","streamableAttr","onNoMatch","onMultipleMatch","modeProperties","effectiveComponent","templateNode","originalForContext","templateMode","priorityAttr","explicitPriority","defaultPriority","effectivePriority","childProcessor","ctx","tmpl","out","use","errorMessage","keyContext","attributeValue","NodeSetValue","messageText","terminate","stylesheetPrefix","resultPrefix","level","count","from","format","lang","letterValue","groupingSize","numbers","formattedNumber","targetOutput","countPattern","num","sibling","matchingAncestors","ancestor","allNodes","alt","fromPattern","parentSibling","tokens","separators","formattedParts","tokenIndex","token","formatted","sepIndex","sep","tokenRegex","remaining","lastWasToken","sepEnd","number","width","size","formatChar","uppercase","romanNumerals","numeral","numStr","separator","parts","intPart","decPart","sort","expression","order","attrName","current","attributes","attribute","localPart","namespaceUri","elements","patterns","parentElement","xmlspace","parentName","element","elementNamespace","templateContext","text","disableOutputEscaping","a","destinationTextNode","stylesheetElement","validAttributes","validNamespaceAttributes","versionFound","nodeName","nodeValue","versionNum","prefixes","mainStylesheetMetadata","importsDone","nonTemplates","contextClone","matchCandidates","rootPatternMatch","c","winner","b","conflicts","rootNode","grandchildNodes","grandchildContext","grandchildNode","grandchildClonedContext","grandchildSelection","grandchildTemplateContext","docChild","fallbackContext","selectAttr","regexAttr","flagsAttr","inputString","matchingSubstring","nonMatchingSubstring","jsFlags","flag","regex","lastIndex","matchStart","matchEnd","nonMatchText","currentText","regexGroups","asAttr","overrideAttr","override","NumberValue","BooleanValue","functionDef","args","functionContext","params","paramType","paramValue","selectExpr","defaultValue","hrefExpr","methodAttr","omitXmlDeclaration","resultDocument","serialized","loader","sequenceChildren","fragment","filteredParameter","textValue","elementContext","newNode","qualifiedName","templatePrefix","aliasPrefix","useAttributeSetsAttr","templateAttributes","attributeName","ret","rp","val","char","depth","expr","axis","existing","functionsMap","funcDef","hasAccepted","setNames","processedSets","attributeNodes","attrNode","nestedSets","ownerNode","nestedName","opt_wantedName"]}
|