From 89664d254ea47a45c5cca1b92967d7f01ee60ba8 Mon Sep 17 00:00:00 2001 From: Leonel Sanches da Silva <53848829+leonelsanchesdasilva@users.noreply.github.com> Date: Mon, 10 Aug 2026 12:07:12 -0700 Subject: [PATCH] Fix recursive xsl:call-template producing NaN via result-tree fragment variables xsl:variable/xsl:param with element content builds a NodeSetValue wrapping a DocumentFragment (nodeType 11). Arithmetic expressions atomizing such a value fell through getStringValueFromNode() to null, coercing to NaN. This blocked recursive named-template patterns (factorial, power, etc.) that stash a nested call-template's result in a variable before using it in arithmetic. Bumps src/xpath/lib submodule to DesignLiquido/xpath@3dff86f, which fixes getStringValueFromNode() to treat document fragment nodes like elements. Resolves https://github.com/DesignLiquido/xslt-processor/issues/217 Co-Authored-By: Claude Sonnet 5 --- src/xpath/lib | 2 +- tests/xslt/call-template.test.ts | 49 ++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 tests/xslt/call-template.test.ts diff --git a/src/xpath/lib b/src/xpath/lib index a567fbf..3dff86f 160000 --- a/src/xpath/lib +++ b/src/xpath/lib @@ -1 +1 @@ -Subproject commit a567fbf1d84071821de455ec442453790a90ea33 +Subproject commit 3dff86fa9190498f07ffed8c075b8ee5b7f4c29e diff --git a/tests/xslt/call-template.test.ts b/tests/xslt/call-template.test.ts new file mode 100644 index 0000000..17f094f --- /dev/null +++ b/tests/xslt/call-template.test.ts @@ -0,0 +1,49 @@ +import { Xslt, XmlParser } from '../../src/index'; + +describe('xsl:call-template', () => { + let xslt: Xslt; + let xmlParser: XmlParser; + + beforeEach(() => { + xslt = new Xslt(); + xmlParser = new XmlParser(); + }); + + // https://github.com/DesignLiquido/xslt-processor/issues/217 + it('supports recursion, using a variable to hold the result of a nested call-template', async () => { + const xml = xmlParser.xmlParse(''); + const stylesheet = xmlParser.xmlParse(` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`); + const result = await xslt.xsltProcess(xml, stylesheet); + expect(result).toBe(''); + }); +});