UNPKG

libxslt-wasm

Version:

JavaScript bindings for libxslt compiled to WebAssembly

70 lines (69 loc) 3.08 kB
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 };