Skip to content

Commit 7f37a37

Browse files
<xsl:include> base implementation.
1 parent d065a3d commit 7f37a37

File tree

2 files changed

+35
-18
lines changed

2 files changed

+35
-18
lines changed

src/xslt/xslt.ts

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import fetch, { Headers, Request, Response } from 'node-fetch';
1313
import {
1414
XDocument,
1515
XNode,
16+
XmlParser,
1617
domAppendChild,
1718
domAppendTransformedChild,
1819
domCreateCDATASection,
@@ -71,6 +72,7 @@ import { MatchResolver } from '../xpath/match-resolver';
7172
*/
7273
export class Xslt {
7374
xPath: XPath;
75+
xmlParser: XmlParser;
7476
matchResolver: MatchResolver;
7577
options: XsltOptions;
7678
decimalFormatSettings: XsltDecimalFormatSettings;
@@ -89,6 +91,7 @@ export class Xslt {
8991
}
9092
) {
9193
this.xPath = new XPath();
94+
this.xmlParser = new XmlParser();
9295
this.matchResolver = new MatchResolver();
9396
this.options = {
9497
cData: options.cData === true,
@@ -397,22 +400,8 @@ export class Xslt {
397400
case 'import':
398401
throw new Error(`not implemented: ${template.localName}`);
399402
case 'include':
400-
// We need to test here whether `window.fetch` is available or not.
401-
// If it is a browser environemnt, it should be.
402-
// Otherwise, we will need to import an equivalent library, like 'node-fetch'.
403-
if (!global.globalThis.fetch) {
404-
global.globalThis.fetch = fetch as any;
405-
global.globalThis.Headers = Headers as any;
406-
global.globalThis.Request = Request as any;
407-
global.globalThis.Response = Response as any;
408-
}
409-
410-
const fetchTest = await global.globalThis.fetch(
411-
'https://raw.githubusercontent.com/DesignLiquido/xslt-processor/xsl-include/examples/head.xsl'
412-
);
413-
const fetchResponse = await fetchTest.text();
414-
console.log(fetchResponse);
415-
throw new Error(`not implemented: ${template.localName}`);
403+
await this.xsltInclude(context, template, output);
404+
break;
416405
case 'key':
417406
throw new Error(`not implemented: ${template.localName}`);
418407
case 'message':
@@ -618,6 +607,35 @@ export class Xslt {
618607
}
619608
}
620609

610+
/**
611+
* Implements `xsl:include`.
612+
* @param input The Expression Context.
613+
* @param template The template.
614+
* @param output The output.
615+
*/
616+
protected async xsltInclude(context: ExprContext, template: XNode, output: XNode) {
617+
// We need to test here whether `window.fetch` is available or not.
618+
// If it is a browser environemnt, it should be.
619+
// Otherwise, we will need to import an equivalent library, like 'node-fetch'.
620+
if (!global.globalThis.fetch) {
621+
global.globalThis.fetch = fetch as any;
622+
global.globalThis.Headers = Headers as any;
623+
global.globalThis.Request = Request as any;
624+
global.globalThis.Response = Response as any;
625+
}
626+
627+
const hrefAttributeFind = template.childNodes.filter(n => n.nodeName === 'href');
628+
if (hrefAttributeFind.length <= 0) {
629+
throw new Error('<xsl:include> with no href attribute defined.');
630+
}
631+
const hrefAttribute = hrefAttributeFind[0];
632+
633+
const fetchTest = await global.globalThis.fetch(hrefAttribute.nodeValue);
634+
const fetchResponse = await fetchTest.text();
635+
const includedXslt = this.xmlParser.xmlParse(fetchResponse);
636+
await this.xsltChildNodes(context, includedXslt.childNodes[0], output);
637+
}
638+
621639
/**
622640
* Orders the current node list in the input context according to the
623641
* sort order specified by xsl:sort child nodes of the current

tests/xslt/include.test.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ describe('xsl:include', () => {
1717
const xml = xmlParser.xmlParse(xmlSource);
1818
const xslt = xmlParser.xmlParse(xsltSource);
1919
const resultingXml = await xsltClass.xsltProcess(xml, xslt);
20-
// assert.equal(html, '<h1><D>Hello</D>-<D>World</D></h1>');
21-
assert.ok(resultingXml)
20+
assert.equal(resultingXml, '<html><head><link rel="stylesheet" type="text/css" href="style.css"><title/></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>');
2221
});
2322
});

0 commit comments

Comments
 (0)