diff --git a/src/xslt/xslt.ts b/src/xslt/xslt.ts index 90bd0b6..5ceec67 100644 --- a/src/xslt/xslt.ts +++ b/src/xslt/xslt.ts @@ -13,6 +13,7 @@ import fetch, { Headers, Request, Response } from 'node-fetch'; import { XDocument, XNode, + XmlParser, domAppendChild, domAppendTransformedChild, domCreateCDATASection, @@ -71,6 +72,7 @@ import { MatchResolver } from '../xpath/match-resolver'; */ export class Xslt { xPath: XPath; + xmlParser: XmlParser; matchResolver: MatchResolver; options: XsltOptions; decimalFormatSettings: XsltDecimalFormatSettings; @@ -89,6 +91,7 @@ export class Xslt { } ) { this.xPath = new XPath(); + this.xmlParser = new XmlParser(); this.matchResolver = new MatchResolver(); this.options = { cData: options.cData === true, @@ -397,22 +400,8 @@ export class Xslt { case 'import': throw new Error(`not implemented: ${template.localName}`); case 'include': - // We need to test here whether `window.fetch` is available or not. - // If it is a browser environemnt, it should be. - // Otherwise, we will need to import an equivalent library, like 'node-fetch'. - if (!global.globalThis.fetch) { - global.globalThis.fetch = fetch as any; - global.globalThis.Headers = Headers as any; - global.globalThis.Request = Request as any; - global.globalThis.Response = Response as any; - } - - const fetchTest = await global.globalThis.fetch( - 'https://raw.githubusercontent.com/DesignLiquido/xslt-processor/xsl-include/examples/head.xsl' - ); - const fetchResponse = await fetchTest.text(); - console.log(fetchResponse); - throw new Error(`not implemented: ${template.localName}`); + await this.xsltInclude(context, template, output); + break; case 'key': throw new Error(`not implemented: ${template.localName}`); case 'message': @@ -618,6 +607,35 @@ export class Xslt { } } + /** + * Implements `xsl:include`. + * @param input The Expression Context. + * @param template The template. + * @param output The output. + */ + protected async xsltInclude(context: ExprContext, template: XNode, output: XNode) { + // We need to test here whether `window.fetch` is available or not. + // If it is a browser environemnt, it should be. + // Otherwise, we will need to import an equivalent library, like 'node-fetch'. + if (!global.globalThis.fetch) { + global.globalThis.fetch = fetch as any; + global.globalThis.Headers = Headers as any; + global.globalThis.Request = Request as any; + global.globalThis.Response = Response as any; + } + + const hrefAttributeFind = template.childNodes.filter(n => n.nodeName === 'href'); + if (hrefAttributeFind.length <= 0) { + throw new Error(' with no href attribute defined.'); + } + const hrefAttribute = hrefAttributeFind[0]; + + const fetchTest = await global.globalThis.fetch(hrefAttribute.nodeValue); + const fetchResponse = await fetchTest.text(); + const includedXslt = this.xmlParser.xmlParse(fetchResponse); + await this.xsltChildNodes(context, includedXslt.childNodes[0], output); + } + /** * Orders the current node list in the input context according to the * sort order specified by xsl:sort child nodes of the current diff --git a/tests/xslt/include.test.tsx b/tests/xslt/include.test.tsx index f192f02..d96cdc8 100644 --- a/tests/xslt/include.test.tsx +++ b/tests/xslt/include.test.tsx @@ -17,7 +17,6 @@ describe('xsl:include', () => { const xml = xmlParser.xmlParse(xmlSource); const xslt = xmlParser.xmlParse(xsltSource); const resultingXml = await xsltClass.xsltProcess(xml, xslt); - // assert.equal(html, '

Hello-World

'); - assert.ok(resultingXml) + assert.equal(resultingXml, '</head><body><div id="container"><div id="header"><div id="menu"><ul><li><a href="#" class="active">Home</a></li><li><a href="#">about</a></li></ul></div></div></div></body></html>'); }); });