xslt-processor 4.6.0 → 4.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/dom/functions.ts","../src/constants.ts","../src/dom/xnode.ts","../src/dom/xdocument.ts","../src/dom/html-entity-decoder.ts","../src/dom/xml-functions.ts","../src/dom/xml-output-options.ts","../src/dom/xmltoken.ts","../src/dom/xml-parser.ts","../src/dom/xbrowser-node.ts","../src/dom/index.ts","../src/index.ts","../src/xpath/xpath.ts","../src/xpath/lib/src/lexer/token.ts","../src/xpath/lib/src/lexer/lexer.ts","../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/types/base.ts","../src/xpath/lib/src/types/kind-tests.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/index.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/json-to-xml-converter.ts","../src/xpath/lib/src/expressions/function-call-expression.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/base-parser.ts","../src/xpath/lib/src/parser/parser-10.ts","../src/xpath/lib/src/context.ts","../src/xpath/values/string-value.ts","../src/xpath/values/number-value.ts","../src/xpath/values/boolean-value.ts","../src/xpath/values/node-set-value.ts","../src/xpath/expr-context.ts","../src/xpath/tokens.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/xslt.ts","../src/xslt/functions.ts"],"sourcesContent":["// 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","// Based on <http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247>\r\nexport const DOM_ELEMENT_NODE = 1;\r\nexport const DOM_ATTRIBUTE_NODE = 2;\r\nexport const DOM_TEXT_NODE = 3;\r\nexport const DOM_CDATA_SECTION_NODE = 4;\r\nexport const DOM_ENTITY_REFERENCE_NODE = 5;\r\nexport const DOM_ENTITY_NODE = 6;\r\nexport const DOM_PROCESSING_INSTRUCTION_NODE = 7;\r\nexport const DOM_COMMENT_NODE = 8;\r\nexport const DOM_DOCUMENT_NODE = 9;\r\nexport const DOM_DOCUMENT_TYPE_NODE = 10;\r\nexport const DOM_DOCUMENT_FRAGMENT_NODE = 11;\r\nexport const DOM_NOTATION_NODE = 12;\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 this.documentElement = this.childNodes[0];\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","/**\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: &amp; &lt; &gt; &quot; &apos;\r\n * - Numeric entities: &#123; or &#xAB;\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: &#123;\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: &#xAB; or &#XAB;\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, '&amp;')\r\n .replace(/</g, '&lt;')\r\n .replace(/>/g, '&gt;')\r\n .replace(/\"/g, '&quot;')\r\n .replace(/'/g, '&#x27;');\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 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(/&lt;/g, '<').replace(/&gt;/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, '&amp;')\r\n .replace(/&amp;amp;/g, '&amp;')\r\n .replace(/</g, '&lt;')\r\n .replace(/>/g, '&gt;');\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, '&quot;');\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","export type XmlOutputOptions = {\r\n cData: boolean;\r\n escape: boolean;\r\n selfClosingTags: boolean;\r\n outputMethod: 'xml' | 'html' | 'text' | 'name' | 'xhtml';\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 { XNode } from \"./xnode\";\r\n\r\n/**\r\n * Special XNode class, that retains properties from browsers like \r\n * IE, Opera, Safari, etc.\r\n */\r\nexport class XBrowserNode extends XNode {\r\n innerText?: string;\r\n textContent?: string;\r\n}\r\n","export * from './functions';\r\nexport * from './xdocument';\r\nexport * from './xml-functions';\r\nexport * from './xml-output-options';\r\nexport * from './xml-parser';\r\nexport * from './xbrowser-node';\r\nexport * from './xnode';\r\n","export { XPath, ExprContext } from './xpath';\r\nexport { Xslt, XsltOptions } from './xslt';\r\nexport { XmlParser, xmlEscapeText } from './dom';\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 { XPath10Parser } from './lib/src/parser';\r\nimport { XPathExpression, XPathLocationPath, XPathUnionExpression } from './lib/src/expressions';\r\nimport { XPathContext, XPathResult, createContext } from './lib/src/context';\r\nimport { XPathNode } from './lib/src/node';\r\nimport { JsonToXmlConverter } from './lib/src/expressions/json-to-xml-converter';\r\nimport { ExprContext } from './expr-context';\r\nimport { NodeValue, StringValue, NumberValue, BooleanValue, NodeSetValue } from './values';\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}\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\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\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\nclass 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 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 });\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 for (const [name, value] of Object.entries(exprContext.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 {\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 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 console.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 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 const { XNode: XNodeClass } = require('../dom');\r\n const { DOM_DOCUMENT_NODE, DOM_TEXT_NODE, DOM_ELEMENT_NODE } = require('../constants');\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 XNodeClass(\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 XNodeClass(\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 // Text node - return the text content as a JSON string\r\n if (node.nodeType === 3) { // TEXT_NODE\r\n const text = node.nodeValue || '';\r\n return JSON.stringify(text);\r\n }\r\n\r\n // Element node - get text content\r\n if (node.nodeType === 1) { // ELEMENT_NODE\r\n const textContent = this.getTextContent(node);\r\n return JSON.stringify(textContent);\r\n }\r\n\r\n // Attribute node\r\n if (node.nodeType === 2) { // ATTRIBUTE_NODE\r\n return JSON.stringify(node.nodeValue || '');\r\n }\r\n\r\n // Default\r\n return '\"\"';\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 (Array.isArray(result)) {\r\n // Node set - nodes are already XNodes (we use them directly)\r\n const xnodes = result.map(node => this.xPathNodeToXNode(node)).filter(n => n !== null) as XNode[];\r\n return new NodeSetValue(xnodes);\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 // 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}\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 lexer: XPathLexer;\r\n private parser: XPath10Parser;\r\n private nodeConverter: NodeConverter;\r\n private parseCache: Map<string, Expression> = new Map();\r\n\r\n constructor() {\r\n // Use XPath 1.0 for backward compatibility with XSLT 1.0\r\n this.lexer = new XPathLexer('1.0');\r\n this.parser = new XPath10Parser();\r\n this.nodeConverter = new NodeConverter();\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 */\r\n xPathParse(expression: string, axis?: string): Expression {\r\n const cacheKey = `${expression}:${axis || ''}`;\r\n\r\n if (this.parseCache.has(cacheKey)) {\r\n return this.parseCache.get(cacheKey)!;\r\n }\r\n\r\n const tokens = this.lexer.scan(expression);\r\n const xpathExpr = this.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 expression = this.xPathParse(select);\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","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\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 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(char);\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(char);\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 (this.current < this.expression.length && this.isAlphaNumeric(this.expression[this.current])) {\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 (this.current < this.expression.length && this.expression[this.current] !== quoteChar) {\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 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 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 return new XPathToken(\"PIPE\", 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 // 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 return new XPathToken(\"COLON\", char);\r\n\r\n case \"=\":\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 throw new Error(`Unexpected character: ${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 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 { 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\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","/**\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(\r\n 'XPST0001',\r\n `Static context component undefined: ${component}`,\r\n );\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(\r\n 'XPST0003',\r\n `Grammar violation: ${message}`,\r\n );\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(\r\n 'XPST0005',\r\n `Empty sequence is not allowed in ${context}`,\r\n );\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(\r\n 'XPST0008',\r\n `Unresolved ${type} reference: ${name}`,\r\n );\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(\r\n 'XPST0010',\r\n `Unsupported axis: ${axis}`,\r\n );\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(\r\n 'XPST0051',\r\n `Unknown atomic type: ${typeName}`,\r\n );\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(\r\n 'XPDY0002',\r\n `Dynamic context component undefined: ${component}`,\r\n );\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\r\n ? `Context item is not a ${context}`\r\n : 'Context item is not a node';\r\n return new XPathDynamicError(\r\n 'XPDY0050',\r\n msg,\r\n );\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(\r\n expected: string,\r\n actual: string,\r\n context?: string,\r\n): 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(\r\n 'XPTY0019',\r\n `Path step requires node, got ${actual}`,\r\n );\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(\r\n 'XPTY0020',\r\n 'Context item is not a node for path evaluation',\r\n );\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(\r\n 'FODT0002',\r\n `Invalid timezone specification: ${timezone}`,\r\n );\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(\r\n 'FOAR0001',\r\n 'Division by zero',\r\n );\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 = 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","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: 'name' | 'node-type' | 'wildcard' | 'processing-instruction' | 'element' | 'attribute' | 'schema-element' | 'schema-attribute' | '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 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 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 = 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 (nodeType === 1 || nodeType === 2 || nodeType === 13) && nodeNsUri === nsUri;\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 = node.documentElement || (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\r\n nodes = context?.node ? [context.node] : [];\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 const stepContext = { ...context, node };\r\n const result = step.evaluate(stepContext);\r\n nextNodes.push(...result);\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 = 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 = 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 * 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 // 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.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","/**\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 * 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 * 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): { negative: boolean; years: number; months: number; days: number; hours: number; minutes: number; seconds: number } {\r\n const match = value.match(/^(-)?P(?:(\\d+)Y)?(?:(\\d+)M)?(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+(?:\\.\\d+)?)S)?)?$/);\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): { hours: number; minutes: number; seconds: number; timezone?: { sign: string; hours: number; minutes: number } } {\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 && \r\n '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 && \r\n '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 * 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 typeof value === 'object' && value !== null && \r\n 'localName' in value && 'namespaceURI' 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 // 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 (typeof value !== 'number' || !Number.isInteger(value) || !isFinite(value) || !Number.isSafeInteger(value)) {\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 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 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 { AnyAtomicTypeImpl, UntypedAtomicImpl, StringTypeImpl, BooleanTypeImpl } 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 { GYearMonthTypeImpl, GYearTypeImpl, GMonthDayTypeImpl, GDayTypeImpl, GMonthTypeImpl } 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// 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('long', integerType, decimalType, -9223372036854775808, 9223372036854775807);\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('nonPositiveInteger', integerType, decimalType, undefined, 0);\r\nconst negativeIntegerType = new IntegerDerivedTypeImpl('negativeInteger', nonPositiveIntegerType, decimalType, undefined, -1);\r\n\r\nconst nonNegativeIntegerType = new IntegerDerivedTypeImpl('nonNegativeInteger', integerType, decimalType, 0, undefined);\r\nconst positiveIntegerType = new IntegerDerivedTypeImpl('positiveInteger', nonNegativeIntegerType, decimalType, 1, undefined);\r\n\r\nconst unsignedLongType = new IntegerDerivedTypeImpl('unsignedLong', nonNegativeIntegerType, decimalType, 0, 18446744073709551615);\r\nconst unsignedIntType = new IntegerDerivedTypeImpl('unsignedInt', unsignedLongType, decimalType, 0, 4294967295);\r\nconst unsignedShortType = new IntegerDerivedTypeImpl('unsignedShort', unsignedIntType, decimalType, 0, 65535);\r\nconst unsignedByteType = new IntegerDerivedTypeImpl('unsignedByte', unsignedShortType, decimalType, 0, 255);\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(type.name);\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(\r\n private operands: XPathExpression[]\r\n ) {\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(\r\n `Range expression operands must be integers: ${String(e)}`\r\n );\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(\r\n private operand: XPathExpression\r\n ) {\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","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(value: any, elementName: string, options?: JsonToXmlOptions, parent?: XPathNode): 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(value[key], sanitizedKey, options, element);\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","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\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('single item', 'empty sequence', `constructor function ${this.name}`);\r\n }\r\n if (raw.length !== 1) {\r\n throw typeMismatch('single item', `sequence of ${raw.length} items`, `constructor function ${this.name}`);\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('single item', 'empty sequence', `constructor function ${this.name}`);\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 default:\r\n // Check for custom functions in context (including XSLT extension functions)\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 throw unresolvedNameReference(this.name, 'function');\r\n }\r\n }\r\n\r\n private getConstructorType(): AtomicType | undefined {\r\n // Only treat QName function names as constructor functions to avoid clobbering built-ins like string()\r\n if (!this.name.includes(':')) {\r\n return undefined;\r\n }\r\n\r\n const [, localName] = this.name.split(':');\r\n if (!localName) {\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 if (args.length === 0) {\r\n return Number(this.stringValue([], context));\r\n }\r\n return Number(args[0]);\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 firstNode?.textContent ?? String(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 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(length - (adjustedStart - start), str.length - adjustedStart);\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('json-to-xml() is only supported in XSLT 3.0. Use version=\"3.0\" in your stylesheet.');\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 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 } from './types/sequence-type';\r\nimport { DEFAULT_FUNCTION_NAMESPACE, DEFAULT_COLLATION, RESERVED_FUNCTION_NAMES, XS_NAMESPACE } 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 = (collations: string[], defaultCollation: string): 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(context: XPathStaticContext, name: string, type: SequenceType): 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(`Default collation ${context.defaultCollation} is not in the in-scope collations`);\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 * 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 = (\r\n context: XPathContext,\r\n ...args: any[]\r\n) => 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:\r\n '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:\r\n '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:\r\n '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:\r\n '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:\r\n '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:\r\n '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:\r\n '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:\r\n '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:\r\n '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:\r\n '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:\r\n '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 = warning.severity === 'deprecation' ? '[DEPRECATED]' :\r\n warning.severity === 'warning' ? '[WARNING]' : '[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(`XPath Warnings Report (${this.warnings.length} warning${this.warnings.length === 1 ? '' : 's'}):`);\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 { 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 {\r\n WarningCollector,\r\n createWarningCollector,\r\n createNoOpWarningCollector,\r\n} 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(supportedVersions: XPathVersion[], defaultVersion: XPathVersion): 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 (this.options.xpath10CompatibilityMode &&\r\n this.options.version &&\r\n this.options.version !== '1.0') {\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 (this.match('LESS_THAN', 'GREATER_THAN', 'LESS_THAN_OR_EQUAL', 'GREATER_THAN_OR_EQUAL')) {\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 (this.check('OPERATOR') && (this.peek().lexeme === 'div' || this.peek().lexeme === 'mod')) {\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(new XPathStep('descendant-or-self', { type: 'node-type', nodeType: 'node' }));\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 ((token.type === 'IDENTIFIER' || token.type === 'NODE_TYPE') && next?.type === 'OPEN_PAREN') {\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(new XPathStep('descendant-or-self', { type: 'node-type', nodeType: 'node' }));\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(new XPathStep('descendant-or-self', { type: 'node-type', nodeType: 'node' }));\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 (this.check('NODE_TYPE') || this.check('IDENTIFIER') || this.check('LOCATION') || this.check('FUNCTION') || this.check('OPERATOR')) {\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 (testName === 'node' || testName === 'text' || testName === 'comment' || testName === 'processing-instruction') {\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('CLOSE_PAREN', \"Expected ')' after processing-instruction target\");\r\n return { type: 'processing-instruction', target };\r\n }\r\n\r\n this.consume('CLOSE_PAREN', \"Expected ')' after node type\");\r\n return { type: 'node-type', nodeType: testName as 'node' | 'text' | 'comment' | 'processing-instruction' };\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 (this.check('IDENTIFIER') || this.check('LOCATION') || this.check('FUNCTION') ||\r\n this.check('NODE_TYPE') || this.check('OPERATOR')) {\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 (this.check('IDENTIFIER') || this.check('LOCATION') || this.check('FUNCTION') ||\r\n this.check('NODE_TYPE') || this.check('OPERATOR')) {\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 name = this.consume('IDENTIFIER', 'Expected variable name after $').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(`Unexpected token in primary expression: ${this.peek()?.lexeme ?? 'EOF'}`);\r\n }\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 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 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 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 // 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 (local && this.isFunctionNameToken(local.type) && afterLocal?.type === 'OPEN_PAREN') {\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 type === 'IDENTIFIER' || type === 'FUNCTION' || type === 'OPERATOR' || type === 'LOCATION';\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 type === 'IDENTIFIER' || type === 'FUNCTION' || type === 'OPERATOR' || type === 'LOCATION' || type === 'NODE_TYPE';\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('IDENTIFIER') || this.check('NODE_TYPE') || this.check('FUNCTION') || this.check('LOCATION') || this.check('OPERATOR')) {\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 (this.check('IDENTIFIER') || this.check('NODE_TYPE') || this.check('FUNCTION') || this.check('LOCATION') || this.check('OPERATOR')) {\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 (this.check('IDENTIFIER') || this.check('NODE_TYPE') || this.check('FUNCTION') || this.check('LOCATION')) {\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 (this.check('IDENTIFIER') || this.check('NODE_TYPE') || this.check('FUNCTION') || this.check('LOCATION')) {\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","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 { 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 * 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 // eslint-disable-next-line @typescript-eslint/ban-types\r\n | Function; // 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 } 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 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 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, 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 { 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 { TOK_NUMBER } from './tokens';\r\nimport { XNode } from '../dom';\r\nimport { XsltDecimalFormatSettings } from '../xslt/xslt-decimal-format-settings';\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 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 * 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 TODO\r\n * @param opt_position TODO\r\n * @param opt_parent TODO\r\n * @param opt_caseInsensitive TODO\r\n * @param opt_ignoreAttributesWithoutValue TODO\r\n * @param opt_returnOnFirstMatch TODO\r\n * @param opt_ignoreNonElementNodesForNTA TODO\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 ) {\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\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 TODO\r\n * @param opt_position TODO\r\n * @returns TODO\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 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 );\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 ) {\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 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) {\r\n return (this.caseInsensitive = caseInsensitive);\r\n }\r\n\r\n isIgnoreAttributesWithoutValue() {\r\n return this.ignoreAttributesWithoutValue;\r\n }\r\n\r\n setIgnoreAttributesWithoutValue(ignore) {\r\n return (this.ignoreAttributesWithoutValue = ignore);\r\n }\r\n\r\n isReturnOnFirstMatch() {\r\n return this.returnOnFirstMatch;\r\n }\r\n\r\n setReturnOnFirstMatch(returnOnFirstMatch) {\r\n return (this.returnOnFirstMatch = returnOnFirstMatch);\r\n }\r\n\r\n isIgnoreNonElementNodesForNTA() {\r\n return this.ignoreNonElementNodesForNTA;\r\n }\r\n\r\n setIgnoreNonElementNodesForNTA(ignoreNonElementNodesForNTA) {\r\n return (this.ignoreNonElementNodesForNTA = ignoreNonElementNodesForNTA);\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","// 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, LocationExpr, UnionExpr } from './xpath';\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","// 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_TEXT_NODE\r\n} from '../constants';\r\n\r\nimport { StringValue, NodeSetValue, NodeValue } from '../xpath/values';\r\nimport { XsltOptions } from './xslt-options';\r\nimport { XsltDecimalFormatSettings } from './xslt-decimal-format-settings';\r\nimport {\r\n collectAndExpandTemplates,\r\n selectBestTemplate,\r\n emitConflictWarning\r\n} from './functions';\r\nimport { TemplatePriority } from './template-priority';\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\n/**\r\n * The main class for XSL-T processing. The implementation is NOT\r\n * complete; some xsl element are left out.\r\n *\r\n * References:\r\n *\r\n * [XSLT] XSL-T Specification\r\n * <http://www.w3.org/TR/1999/REC-xslt-19991116>.\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 function\r\n * `xsltProcess()`. It receives as arguments the starting point in the\r\n * input document as an XPath expression context, the DOM root node of\r\n * the XSL-T stylesheet, and a DOM node that receives the output.\r\n *\r\n * NOTE: Actually, XSL-T processing according to the specification is\r\n * defined as operation on text documents, not as operation on DOM\r\n * trees. So, strictly speaking, this implementation is not an XSL-T\r\n * processor, but the processing engine that needs to be complemented\r\n * by an XML parser and serializer in order 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\r\n outputDocument: XDocument;\r\n outputMethod: 'xml' | 'html' | 'text' | 'name' | 'xhtml' | 'json' | 'adaptive';\r\n outputOmitXmlDeclaration: string;\r\n version: string;\r\n firstTemplateRan: 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: string[];\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: string[];\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 * 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 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.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.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 }\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 = new XDocument();\r\n this.outputDocument = outputDocument;\r\n const expressionContext = new ExprContext([xmlDoc]);\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, new StringValue(parameter.value));\r\n }\r\n }\r\n\r\n await this.xsltProcessContext(expressionContext, stylesheet, this.outputDocument);\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 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: outputMethod as 'xml' | 'html' | 'text' | 'xhtml'\r\n });\r\n\r\n return transformedOutputXml;\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 (!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 '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 'decimal-format':\r\n this.xsltDecimalFormat(context, template);\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 '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 'message':\r\n await this.xsltMessage(context, template);\r\n break;\r\n case 'namespace-alias':\r\n this.xsltNamespaceAlias(template);\r\n break;\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 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 'processing-instruction':\r\n await this.xsltProcessingInstruction(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 '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 throw new Error(`error if here: ${template.localName}`);\r\n }\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 // 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 top = template.ownerDocument.documentElement;\r\n\r\n // Collect all templates with their priority metadata\r\n const expandedTemplates: TemplatePriority[] = collectAndExpandTemplates(top, mode, this.xPath, this.templateSourceMap);\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 // If the current node is text, there's no need to test all the templates\r\n // against it. Just appending it to its parent is fine.\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 const textNodeContext = context.clone(\r\n [currentNode],\r\n 0\r\n );\r\n this.commonLogicTextNode(textNodeContext, currentNode, output);\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 );\r\n\r\n // Emit warning if there's a conflict\r\n if (selection.hasConflict) {\r\n emitConflictWarning(selection, currentNode);\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 || mode,\r\n match: matchPattern\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 }\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 allTemplates = collectAndExpandTemplates(top, currentMode, this.xPath, this.templateSourceMap);\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 // No imported templates found, silently do nothing (per spec)\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(importedTemplates, nodeContext, this.matchResolver, this.xPath);\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 this.currentTemplateStack.push({\r\n template: selection.selectedTemplate,\r\n stylesheetDepth: metadata.importDepth,\r\n mode: currentMode,\r\n match: matchPattern\r\n });\r\n \r\n await this.xsltChildNodes(importedContext, selection.selectedTemplate, output);\r\n \r\n this.currentTemplateStack.pop();\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 }\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 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 domSetAttribute(node, 'xmlns', source.namespaceUri);\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\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\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 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(undefined, 0);\r\n await this.xsltChildNodes(clonedContext, template, node);\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 if (nodes.length === 0) {\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.xsltChildNodes(sortContext.clone(sortContext.nodeList, i), template, output);\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 const [major, minor] = process.versions.node.split('.').map(Number);\r\n if (major <= 17 && minor < 5) {\r\n throw new Error(`Your Node.js version does not support \\`<${elementName}>\\`. If possible, please update your Node.js version to at least version 17.5.0.`);\r\n }\r\n\r\n // We need to test here whether `window.fetch` is available or not.\r\n // If it is a browser environemnt, it should be.\r\n // Otherwise, we will need to import an equivalent library, like 'node-fetch'.\r\n if (!global.globalThis.fetch) {\r\n global.globalThis.fetch = fetch as any;\r\n global.globalThis.Headers = Headers as any;\r\n global.globalThis.Request = Request as any;\r\n global.globalThis.Response = Response as any;\r\n }\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 fetchTest = await global.globalThis.fetch(href);\r\n const fetchResponse = await fetchTest.text();\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: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 number: 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 number = Math.round(result.numberValue());\r\n } else {\r\n // Otherwise, count nodes based on level, count, and from attributes\r\n number = this.xsltNumberCount(context, level, count, from);\r\n }\r\n\r\n // Format the number\r\n const formattedNumber = this.xsltFormatNumber(number, 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 start counting from.\r\n * @returns The count value.\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 // Count preceding siblings (plus 1 for self) that match the count pattern\r\n let num = 1;\r\n let sibling = currentNode.previousSibling;\r\n while (sibling) {\r\n if (sibling.nodeType === currentNode.nodeType) {\r\n if (this.nodeMatchesPattern(sibling, countPattern)) {\r\n num++;\r\n }\r\n }\r\n sibling = sibling.previousSibling;\r\n }\r\n return num;\r\n }\r\n case 'multiple': {\r\n // For multiple level, we'd return a sequence - simplified to single value here\r\n // Full implementation would return array for hierarchical numbering\r\n let num = 1;\r\n let sibling = currentNode.previousSibling;\r\n while (sibling) {\r\n if (sibling.nodeType === currentNode.nodeType) {\r\n if (this.nodeMatchesPattern(sibling, countPattern)) {\r\n num++;\r\n }\r\n }\r\n sibling = sibling.previousSibling;\r\n }\r\n return num;\r\n }\r\n case 'any': {\r\n // Count all preceding nodes in document order that match\r\n let num = 1;\r\n const allNodes = this.getAllPrecedingNodes(currentNode);\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 simple name pattern.\r\n * @param node The node to check.\r\n * @param pattern The pattern (node name) to match.\r\n * @returns True if the node matches.\r\n */\r\n protected nodeMatchesPattern(node: XNode, pattern: string): boolean {\r\n if (pattern === '*') {\r\n return node.nodeType === DOM_ELEMENT_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 * @returns Array of preceding nodes.\r\n */\r\n protected getAllPrecedingNodes(node: XNode): 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 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 let parentSibling = parent.previousSibling;\r\n while (parentSibling) {\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 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 // 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 /**\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 this.stripSpacePatterns.push(...patterns);\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 this.preserveSpacePatterns.push(...patterns);\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(elementName: string, pattern: string, element: XNode): boolean {\r\n // Universal match\r\n if (pattern === '*') {\r\n return true;\r\n }\r\n\r\n // Handle patterns with namespace prefixes\r\n if (pattern.includes(':')) {\r\n const [prefix, localPart] = pattern.split(':');\r\n\r\n // Check if element has a matching prefix\r\n const elementPrefix = element.prefix || '';\r\n\r\n if (localPart === '*') {\r\n // prefix:* - match any element in that namespace\r\n return elementPrefix === prefix;\r\n } else {\r\n // prefix:name - match specific element in namespace\r\n return elementPrefix === prefix && elementName === localPart;\r\n }\r\n }\r\n\r\n // Simple name match (no namespace prefix in pattern)\r\n return elementName === pattern;\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\r\n if (nodeName === 'version') {\r\n versionFound = true;\r\n if (!['1.0', '2.0', '3.0'].includes(nodeValue)) {\r\n throw new Error(\r\n `XSLT version not defined or invalid. Actual resolved version: ${nodeValue || '(none)'}.`\r\n );\r\n }\r\n this.version = nodeValue;\r\n context.xsltVersion = nodeValue as any;\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 // 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: TemplatePriority; 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 console.warn(`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: TemplatePriority; 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 console.warn(\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 );\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 );\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 * 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 let parameterValue = '';\r\n const filteredParameter = this.options.parameters.filter((p) => p.name === name);\r\n if (filteredParameter.length > 0) {\r\n parameterValue = filteredParameter[0].value;\r\n }\r\n value = new StringValue(parameterValue);\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 * 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 * 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 let node = domCreateTextNode(this.outputDocument, template.nodeValue);\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 newNode = domCreateElement(this.outputDocument, template.nodeName);\r\n newNode.siblingPosition = node.siblingPosition;\r\n\r\n domAppendChild(output || this.outputDocument, newNode);\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\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 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')) {\r\n // Recursively process nested stylesheets\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 * 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","import { XNode } from \"../dom/xnode\";\r\nimport { DOM_ELEMENT_NODE } from '../constants';\r\nimport { ExprContext, XPath, MatchResolver, Expression, LocationExpr, UnionExpr } from \"../xpath\";\r\nimport { TemplatePriority } from \"./template-priority\";\r\nimport { TemplateSelectionResult } from \"./template-selection-result\";\r\nimport { NodeTestAny, NodeTestComment, NodeTestElementOrAttribute, NodeTestName, NodeTestNC, NodeTestPI, NodeTestText } from \"../xpath/node-tests\";\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 return 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 - calculate based on the step's node test\r\n return calculateStepPriority(expr.steps[0]);\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(pattern: string, xPath: XPath): number {\r\n try {\r\n const expr = xPath.xPathParse(pattern, 'self-and-siblings');\r\n return calculateDefaultPriorityFromExpression(expr, xPath);\r\n } catch (e) {\r\n // If parsing fails, return default priority 0\r\n console.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 * Collect all templates from the stylesheet with their priority metadata.\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): TemplatePriority[] {\r\n const templates: TemplatePriority[] = [];\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 const defaultPriority = calculateDefaultPriority(match, xPath);\r\n const effectivePriority = explicitPriority !== null && !isNaN(explicitPriority)\r\n ? explicitPriority\r\n : defaultPriority;\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 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: match\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: TemplatePriority[],\r\n context: ExprContext,\r\n matchResolver: MatchResolver,\r\n xPath: XPath\r\n): TemplateSelectionResult {\r\n // 1. Filter to templates that match the current node\r\n const matching: TemplatePriority[] = [];\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 console.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 };\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(result: TemplateSelectionResult, node: XNode): 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 console.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"],"mappings":"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","names":["i","_a","_b","nodeLocalName","next","DOM_DOCUMENT_NODE","DOM_TEXT_NODE","DOM_ELEMENT_NODE","node","metadata"]}
1
+ {"version":3,"sources":["../src/dom/functions.ts","../src/constants.ts","../src/dom/xnode.ts","../src/dom/xdocument.ts","../src/dom/html-entity-decoder.ts","../src/dom/xml-functions.ts","../src/dom/xml-output-options.ts","../src/dom/xmltoken.ts","../src/dom/xml-parser.ts","../src/dom/xbrowser-node.ts","../src/dom/index.ts","../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/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/union-type.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/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/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/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/xpath.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/context.ts","../src/xpath/values/string-value.ts","../src/xpath/values/number-value.ts","../src/xpath/values/boolean-value.ts","../src/xpath/values/node-set-value.ts","../src/xpath/expr-context.ts","../src/xpath/tokens.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/xslt.ts","../src/xslt/functions.ts"],"sourcesContent":["// 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","// Based on <http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247>\r\nexport const DOM_ELEMENT_NODE = 1;\r\nexport const DOM_ATTRIBUTE_NODE = 2;\r\nexport const DOM_TEXT_NODE = 3;\r\nexport const DOM_CDATA_SECTION_NODE = 4;\r\nexport const DOM_ENTITY_REFERENCE_NODE = 5;\r\nexport const DOM_ENTITY_NODE = 6;\r\nexport const DOM_PROCESSING_INSTRUCTION_NODE = 7;\r\nexport const DOM_COMMENT_NODE = 8;\r\nexport const DOM_DOCUMENT_NODE = 9;\r\nexport const DOM_DOCUMENT_TYPE_NODE = 10;\r\nexport const DOM_DOCUMENT_FRAGMENT_NODE = 11;\r\nexport const DOM_NOTATION_NODE = 12;\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 this.documentElement = this.childNodes[0];\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","/**\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: &amp; &lt; &gt; &quot; &apos;\r\n * - Numeric entities: &#123; or &#xAB;\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: &#123;\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: &#xAB; or &#XAB;\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, '&amp;')\r\n .replace(/</g, '&lt;')\r\n .replace(/>/g, '&gt;')\r\n .replace(/\"/g, '&quot;')\r\n .replace(/'/g, '&#x27;');\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 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(/&lt;/g, '<').replace(/&gt;/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, '&amp;')\r\n .replace(/&amp;amp;/g, '&amp;')\r\n .replace(/</g, '&lt;')\r\n .replace(/>/g, '&gt;');\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, '&quot;');\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","export type XmlOutputOptions = {\r\n cData: boolean;\r\n escape: boolean;\r\n selfClosingTags: boolean;\r\n outputMethod: 'xml' | 'html' | 'text' | 'name' | 'xhtml';\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 { XNode } from \"./xnode\";\r\n\r\n/**\r\n * Special XNode class, that retains properties from browsers like \r\n * IE, Opera, Safari, etc.\r\n */\r\nexport class XBrowserNode extends XNode {\r\n innerText?: string;\r\n textContent?: string;\r\n}\r\n","export * from './functions';\r\nexport * from './xdocument';\r\nexport * from './xml-functions';\r\nexport * from './xml-output-options';\r\nexport * from './xml-parser';\r\nexport * from './xbrowser-node';\r\nexport * from './xnode';\r\n","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 // 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.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 * 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 * 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 * 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 * 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// 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 ancestor in the input sequence.\r\n * Most deeply nested nodes (descendants take precedence over ancestors).\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 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:outermost($nodes as node()*) as node()*\r\n * Returns nodes that have no descendant in the input sequence.\r\n * Least deeply nested nodes (ancestors take precedence over descendants).\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 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: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\r\n let current = node.parent || node.parentNode;\r\n while (current) {\r\n if (current === potential) {\r\n return true;\r\n }\r\n current = current.parent || current.parentNode;\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 const result = Object.create(null);\r\n result.__isMap = true;\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 // Later maps win\r\n result[k] = mm[k];\r\n }\r\n }\r\n\r\n // TODO: implement options handling (e.g., duplicates) per spec\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// 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 // Liberal mode: allow comments, trailing commas, etc. (not implemented)\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 // TODO: Implement liberal mode if needed\r\n const parsed = JSON.parse(jsonString);\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)","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\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 BUILT_IN_FUNCTIONS: Record<string, (context: XPathContext, ...args: any[]) => any> = {\r\n // String functions\r\n 'upper-case': (_ctx, arg) => String(arg).toUpperCase(),\r\n 'lower-case': (_ctx, arg) => String(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\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\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 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 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\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 default:\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 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 // Check for custom functions in context (including XSLT extension functions)\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 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 QName function names as constructor functions to avoid clobbering built-ins like string()\r\n if (!this.name.includes(':')) {\r\n return undefined;\r\n }\r\n\r\n const [, localName] = this.name.split(':');\r\n if (!localName) {\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 if (args.length === 0) {\r\n return Number(this.stringValue([], context));\r\n }\r\n return Number(args[0]);\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 // 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 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 * 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 */\r\n private atomizeToString(value: any): string {\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 // TODO: Proper atomization for other types\r\n return String(value);\r\n }\r\n\r\n /**\r\n * Atomize a value to a number for use as an array index.\r\n */\r\n private atomizeToNumber(value: any): number {\r\n if (typeof value === 'number') return value;\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 // TODO: Proper atomization for other types\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 './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 } from './dom';\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, xmlValue } from '../dom';\r\nimport { XPathLexer } from './lib/src/lexer';\r\nimport { XPath10Parser } from './lib/src/parser';\r\nimport { XPathExpression, XPathLocationPath, XPathUnionExpression } from './lib/src/expressions';\r\nimport { XPathContext, XPathResult, createContext } from './lib/src/context';\r\nimport { XPathNode } from './lib/src/node';\r\nimport { JsonToXmlConverter } from './lib/src/expressions/json-to-xml-converter';\r\nimport { ExprContext } from './expr-context';\r\nimport { NodeValue, StringValue, NumberValue, BooleanValue, NodeSetValue } from './values';\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}\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\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\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\nclass 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 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 });\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 for (const [name, value] of Object.entries(exprContext.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 {\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 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 console.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 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 const { XNode: XNodeClass } = require('../dom');\r\n const { DOM_DOCUMENT_NODE, DOM_TEXT_NODE, DOM_ELEMENT_NODE } = require('../constants');\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 XNodeClass(\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 XNodeClass(\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 (Array.isArray(result)) {\r\n // Node set - nodes are already XNodes (we use them directly)\r\n const xnodes = result.map(node => this.xPathNodeToXNode(node)).filter(n => n !== null) as XNode[];\r\n return new NodeSetValue(xnodes);\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 // 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}\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 lexer: XPathLexer;\r\n private parser: XPath10Parser;\r\n private nodeConverter: NodeConverter;\r\n private parseCache: Map<string, Expression> = new Map();\r\n\r\n constructor() {\r\n // Use XPath 1.0 for backward compatibility with XSLT 1.0\r\n this.lexer = new XPathLexer('1.0');\r\n this.parser = new XPath10Parser();\r\n this.nodeConverter = new NodeConverter();\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 */\r\n xPathParse(expression: string, axis?: string): Expression {\r\n const cacheKey = `${expression}:${axis || ''}`;\r\n\r\n if (this.parseCache.has(cacheKey)) {\r\n return this.parseCache.get(cacheKey)!;\r\n }\r\n\r\n const tokens = this.lexer.scan(expression);\r\n const xpathExpr = this.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 expression = this.xPathParse(select);\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","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\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 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 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 name = this.consume('IDENTIFIER', 'Expected variable name after $').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} 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 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 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 { 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.parseMultiplicativeExpr();\r\n\r\n while (this.match('CONCAT')) {\r\n const right = this.parseMultiplicativeExpr();\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 */\r\n protected parsePrimaryExpr(): XPathExpression {\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 * 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","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 } 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 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 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, 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 { 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 { TOK_NUMBER } from './tokens';\r\nimport { XNode } from '../dom';\r\nimport { XsltDecimalFormatSettings } from '../xslt/xslt-decimal-format-settings';\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 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 * 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 TODO\r\n * @param opt_position TODO\r\n * @param opt_parent TODO\r\n * @param opt_caseInsensitive TODO\r\n * @param opt_ignoreAttributesWithoutValue TODO\r\n * @param opt_returnOnFirstMatch TODO\r\n * @param opt_ignoreNonElementNodesForNTA TODO\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 ) {\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\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 TODO\r\n * @param opt_position TODO\r\n * @returns TODO\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 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 );\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 ) {\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 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) {\r\n return (this.caseInsensitive = caseInsensitive);\r\n }\r\n\r\n isIgnoreAttributesWithoutValue() {\r\n return this.ignoreAttributesWithoutValue;\r\n }\r\n\r\n setIgnoreAttributesWithoutValue(ignore) {\r\n return (this.ignoreAttributesWithoutValue = ignore);\r\n }\r\n\r\n isReturnOnFirstMatch() {\r\n return this.returnOnFirstMatch;\r\n }\r\n\r\n setReturnOnFirstMatch(returnOnFirstMatch) {\r\n return (this.returnOnFirstMatch = returnOnFirstMatch);\r\n }\r\n\r\n isIgnoreNonElementNodesForNTA() {\r\n return this.ignoreNonElementNodesForNTA;\r\n }\r\n\r\n setIgnoreNonElementNodesForNTA(ignoreNonElementNodesForNTA) {\r\n return (this.ignoreNonElementNodesForNTA = ignoreNonElementNodesForNTA);\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","// 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, LocationExpr, UnionExpr } from './xpath';\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","// 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 } from '../xpath/values';\r\nimport { XsltOptions } from './xslt-options';\r\nimport { XsltDecimalFormatSettings } from './xslt-decimal-format-settings';\r\nimport {\r\n collectAndExpandTemplates,\r\n selectBestTemplate,\r\n emitConflictWarning\r\n} from './functions';\r\nimport { TemplatePriority } from './template-priority';\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\n/**\r\n * The main class for XSL-T processing. The implementation is NOT\r\n * complete; some xsl element are left out.\r\n *\r\n * References:\r\n *\r\n * [XSLT] XSL-T Specification\r\n * <http://www.w3.org/TR/1999/REC-xslt-19991116>.\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 function\r\n * `xsltProcess()`. It receives as arguments the starting point in the\r\n * input document as an XPath expression context, the DOM root node of\r\n * the XSL-T stylesheet, and a DOM node that receives the output.\r\n *\r\n * NOTE: Actually, XSL-T processing according to the specification is\r\n * defined as operation on text documents, not as operation on DOM\r\n * trees. So, strictly speaking, this implementation is not an XSL-T\r\n * processor, but the processing engine that needs to be complemented\r\n * by an XML parser and serializer in order 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\r\n outputDocument: XDocument;\r\n outputMethod: 'xml' | 'html' | 'text' | 'name' | 'xhtml' | 'json' | 'adaptive';\r\n outputOmitXmlDeclaration: 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: string[];\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: string[];\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 * 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 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.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.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 }\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 = new XDocument();\r\n this.outputDocument = outputDocument;\r\n const expressionContext = new ExprContext([xmlDoc]);\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, new StringValue(parameter.value));\r\n }\r\n }\r\n\r\n await this.xsltProcessContext(expressionContext, stylesheet, this.outputDocument);\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 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: outputMethod as 'xml' | 'html' | 'text' | 'xhtml'\r\n });\r\n\r\n return transformedOutputXml;\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 (!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 '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 'decimal-format':\r\n this.xsltDecimalFormat(context, template);\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 '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 'message':\r\n await this.xsltMessage(context, template);\r\n break;\r\n case 'namespace-alias':\r\n this.xsltNamespaceAlias(template);\r\n break;\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 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 'processing-instruction':\r\n await this.xsltProcessingInstruction(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 '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 // 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 top = template.ownerDocument.documentElement;\r\n\r\n // Collect all templates with their priority metadata\r\n const expandedTemplates: TemplatePriority[] = collectAndExpandTemplates(top, mode, this.xPath, this.templateSourceMap);\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 );\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 || mode,\r\n match: matchPattern\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 }\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 );\r\n\r\n // Emit warning if there's a conflict\r\n if (selection.hasConflict) {\r\n emitConflictWarning(selection, currentNode);\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 || mode,\r\n match: matchPattern\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 }\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 allTemplates = collectAndExpandTemplates(top, currentMode, this.xPath, this.templateSourceMap);\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 // No imported templates found, silently do nothing (per spec)\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(importedTemplates, nodeContext, this.matchResolver, this.xPath);\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 this.currentTemplateStack.push({\r\n template: selection.selectedTemplate,\r\n stylesheetDepth: metadata.importDepth,\r\n mode: currentMode,\r\n match: matchPattern\r\n });\r\n \r\n await this.xsltChildNodes(importedContext, selection.selectedTemplate, output);\r\n \r\n this.currentTemplateStack.pop();\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 }\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 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 domSetAttribute(node, 'xmlns', source.namespaceUri);\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\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\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 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(undefined, 0);\r\n await this.xsltChildNodes(clonedContext, template, node);\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 if (nodes.length === 0) {\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.xsltChildNodes(sortContext.clone(sortContext.nodeList, i), template, output);\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 const [major, minor] = process.versions.node.split('.').map(Number);\r\n if (major <= 17 && minor < 5) {\r\n throw new Error(`Your Node.js version does not support \\`<${elementName}>\\`. If possible, please update your Node.js version to at least version 17.5.0.`);\r\n }\r\n\r\n // We need to test here whether `window.fetch` is available or not.\r\n // If it is a browser environemnt, it should be.\r\n // Otherwise, we will need to import an equivalent library, like 'node-fetch'.\r\n if (!global.globalThis.fetch) {\r\n global.globalThis.fetch = fetch as any;\r\n global.globalThis.Headers = Headers as any;\r\n global.globalThis.Request = Request as any;\r\n global.globalThis.Response = Response as any;\r\n }\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 fetchTest = await global.globalThis.fetch(href);\r\n const fetchResponse = await fetchTest.text();\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: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 // 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 /**\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 this.stripSpacePatterns.push(...patterns);\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 this.preserveSpacePatterns.push(...patterns);\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(elementName: string, pattern: string, element: XNode): boolean {\r\n // Universal match\r\n if (pattern === '*') {\r\n return true;\r\n }\r\n\r\n // Handle patterns with namespace prefixes\r\n if (pattern.includes(':')) {\r\n const [prefix, localPart] = pattern.split(':');\r\n\r\n // Check if element has a matching prefix\r\n const elementPrefix = element.prefix || '';\r\n\r\n if (localPart === '*') {\r\n // prefix:* - match any element in that namespace\r\n return elementPrefix === prefix;\r\n } else {\r\n // prefix:name - match specific element in namespace\r\n return elementPrefix === prefix && elementName === localPart;\r\n }\r\n }\r\n\r\n // Simple name match (no namespace prefix in pattern)\r\n return elementName === pattern;\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 console.warn(\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 // 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: TemplatePriority; 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 console.warn(`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: TemplatePriority; 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 console.warn(\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 );\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 );\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 * 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 let parameterValue = '';\r\n const filteredParameter = this.options.parameters.filter((p) => p.name === name);\r\n if (filteredParameter.length > 0) {\r\n parameterValue = filteredParameter[0].value;\r\n }\r\n value = new StringValue(parameterValue);\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 * 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 * 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 let node = domCreateTextNode(this.outputDocument, template.nodeValue);\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 newNode = domCreateElement(this.outputDocument, template.nodeName);\r\n newNode.siblingPosition = node.siblingPosition;\r\n\r\n domAppendChild(output || this.outputDocument, newNode);\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\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 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')) {\r\n // Recursively process nested stylesheets\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 * 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","import { XNode } from \"../dom/xnode\";\r\nimport { DOM_ELEMENT_NODE } from '../constants';\r\nimport { ExprContext, XPath, MatchResolver, Expression, LocationExpr, UnionExpr } from \"../xpath\";\r\nimport { TemplatePriority } from \"./template-priority\";\r\nimport { TemplateSelectionResult } from \"./template-selection-result\";\r\nimport { NodeTestAny, NodeTestComment, NodeTestElementOrAttribute, NodeTestName, NodeTestNC, NodeTestPI, NodeTestText } from \"../xpath/node-tests\";\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(pattern: string, xPath: XPath): 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 console.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): TemplatePriority[] {\r\n const templates: TemplatePriority[] = [];\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: TemplatePriority[],\r\n context: ExprContext,\r\n matchResolver: MatchResolver,\r\n xPath: XPath\r\n): TemplateSelectionResult {\r\n // 1. Filter to templates that match the current node\r\n const matching: TemplatePriority[] = [];\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 console.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 };\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(result: TemplateSelectionResult, node: XNode): 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 console.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"],"mappings":"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","names":["i","init_constants","functionName","init_constants","_a","_b","nodeLocalName","init_constants","init_constants","isNode","init_constants","init_constants","next","functionName","DOM_DOCUMENT_NODE","DOM_TEXT_NODE","DOM_ELEMENT_NODE","sort","node","metadata","pi","sort"]}