libxslt-wasm
Version:
JavaScript bindings for libxslt compiled to WebAssembly
70 lines (69 loc) • 3.08 kB
JavaScript
import { XmlDocument } from "./XmlDocument.js";
import { XmlOutputBuffer } from "./XmlOutputBuffer.js";
import { NULL_POINTER } from "../constants.js";
import { xsltApplyStylesheet, xsltLoadStylesheetPI, xsltFreeStylesheet, xsltParseStylesheetDoc, xsltSaveResultTo, } from "../internal/libxslt.js";
import { parseXsltParams } from "../utils/parseXsltParams.js";
class XsltStylesheet extends XmlDocument {
/**
* Assuming the XML document is a valid XSLT stylesheet, creates a new
* instance of XsltStylesheet
*/
static async fromXmlDocument(xmlDocument) {
const xsltStylesheet = await xsltParseStylesheetDoc(xmlDocument.byteOffset);
return new XsltStylesheet(xsltStylesheet);
}
/**
* Given an XML document with an embedded XSLT stylesheet (e.g. a processing
* instruction like <?xml-stylesheet?>), return the corresponding
* XsltStylesheet instance
*/
static async fromEmbeddedXmlDocument(xmlDocument) {
const xsltStylesheetPtr = await xsltLoadStylesheetPI(xmlDocument.byteOffset);
return xsltStylesheetPtr === NULL_POINTER ? null : (new XsltStylesheet(xsltStylesheetPtr));
}
static async fromUrl(fileOrUrl) {
return this.fromXmlDocument(await super.fromUrl(fileOrUrl));
}
static async fromString(string) {
return this.fromXmlDocument(await super.fromString(string));
}
static async fromBuffer(buffer, options) {
return this.from(new Uint8Array(buffer), options);
}
static async from(buffer, { url, encoding, options } = {}) {
const xmlDocument = await super.from(buffer, { url, encoding, options });
return this.fromXmlDocument(xmlDocument);
}
// Since `xsltApplyStylesheet()` uses `xmlXPathCompOpEval()` internally for
// params, this must be async. Consider using `applyToOutputBuffer()` or
// `applyToString()` for synchronous operations
async apply(xmlDocument, params) {
const xsltParams = parseXsltParams(params);
const result = await xsltApplyStylesheet(this.byteOffset, xmlDocument.byteOffset, xsltParams !== null ? xsltParams.byteOffset : NULL_POINTER);
xsltParams?.delete();
if (result === NULL_POINTER) {
throw new Error("Failed to apply XSLT stylesheet to XML document");
}
return new XmlDocument(result);
}
applyToOutputBuffer(xmlDocument) {
const outputBuffer = XmlOutputBuffer.allocate();
const bytesWritten = xsltSaveResultTo(outputBuffer.byteOffset, xmlDocument.byteOffset, this.byteOffset);
if (bytesWritten === -1) {
throw new Error("Failed to save result to XML output buffer");
}
return outputBuffer;
}
applyToString(xmlDocument) {
const outputBuffer = this.applyToOutputBuffer(xmlDocument);
const result = outputBuffer.toString();
outputBuffer.delete();
return result;
}
delete() {
if (this.byteOffset !== null) {
xsltFreeStylesheet(this.byteOffset);
}
}
}
export { XsltStylesheet };