All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.saxon.s9api.XsltCompiler Maven / Gradle / Ivy

There is a newer version: 12.5
Show newest version
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2015 Saxonica Limited.
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

package net.sf.saxon.s9api;

import net.sf.saxon.Configuration;
import net.sf.saxon.PreparedStylesheet;
import net.sf.saxon.lib.ErrorGatherer;
import net.sf.saxon.lib.NamespaceConstant;
import net.sf.saxon.lib.StringCollator;
import net.sf.saxon.om.AxisInfo;
import net.sf.saxon.om.NodeInfo;
import net.sf.saxon.om.StandardNames;
import net.sf.saxon.pattern.NameTest;
import net.sf.saxon.style.*;
import net.sf.saxon.trace.XSLTTraceCodeInjector;
import net.sf.saxon.trans.*;
import net.sf.saxon.tree.iter.AxisIterator;
import net.sf.saxon.tree.linked.DocumentImpl;
import net.sf.saxon.tree.linked.ElementImpl;
import net.sf.saxon.type.Type;
import net.sf.saxon.value.NestedIntegerValue;
import net.sf.saxon.value.Whitespace;

import javax.xml.transform.ErrorListener;
import javax.xml.transform.Source;
import javax.xml.transform.URIResolver;
import javax.xml.transform.stream.StreamSource;
import java.net.URI;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * An XsltCompiler object allows XSLT 2.0 and XSLT 3.0 stylesheets to be compiled. The compiler holds information that
 * represents the static context for the compilation.
 * 

*

To construct an XsltCompiler, use the factory method {@link Processor#newXsltCompiler} on the Processor object.

*

*

An XsltCompiler may be used repeatedly to compile multiple queries. Any changes made to the * XsltCompiler (that is, to the static context) do not affect queries that have already been compiled. * An XsltCompiler may be used concurrently in multiple threads, but it should not then be modified once * initialized.

* * @since 9.0 */ public class XsltCompiler { private Processor processor; private Configuration config; private CompilerInfo compilerInfo; /** * Protected constructor. The public way to create an XsltCompiler is by using the factory method * {@link Processor#newXsltCompiler} . * * @param processor the Saxon processor */ protected XsltCompiler(Processor processor) { this.processor = processor; this.config = processor.getUnderlyingConfiguration(); compilerInfo = new CompilerInfo(config.getDefaultXsltCompilerInfo()); compilerInfo.setGenerateByteCode(config.isGenerateByteCode(Configuration.XSLT)); compilerInfo.setTargetEdition(config.getEditionCode()); } /** * Get the Processor from which this XsltCompiler was constructed * * @return the Processor to which this XsltCompiler belongs * @since 9.3 */ public Processor getProcessor() { return processor; } /** * Set the URIResolver to be used during stylesheet compilation. This URIResolver, despite its name, * is not used for resolving relative URIs against a base URI; it is used for dereferencing * an absolute URI (after resolution) to return a {@link javax.xml.transform.Source} representing the * location where a stylesheet module can be found. *

*

This URIResolver is used to dereference the URIs appearing in xsl:import, * xsl:include, and xsl:import-schema declarations. It is not used * for resolving the URI supplied for the main stylesheet module (as supplied to the * {@link #compile(javax.xml.transform.Source)} or {@link #compilePackage(javax.xml.transform.Source)} methods. * It is not used at run-time for resolving requests to the document() or similar functions.

* * @param resolver the URIResolver to be used during stylesheet compilation. */ public void setURIResolver(URIResolver resolver) { compilerInfo.setURIResolver(resolver); } /** * Set the value of a stylesheet parameter. Static (compile-time) parameters must be provided using * this method on the XsltCompiler object, prior to stylesheet compilation. Non-static parameters * may also be provided using this method if their values will not vary from one transformation * to another. * * @param name the StructuredQName of the parameter * @param value as a XdmValue of the parameter */ public void setParameter(QName name, XdmValue value) { compilerInfo.setParameter(name.getStructuredQName(), value.getUnderlyingValue()); } /** * Clear the values of all stylesheet parameters previously set using {@link #setParameter(QName, XdmValue)}. * This resets the parameters to their initial ("undeclared") state */ public void clearParameters() { compilerInfo.clearParameters(); } /** * Get the URIResolver to be used during stylesheet compilation. * * @return the URIResolver used during stylesheet compilation. Returns null if no user-supplied * URIResolver has been set. */ public URIResolver getURIResolver() { return compilerInfo.getURIResolver(); } /** * Set the ErrorListener to be used during this compilation episode * * @param listener The error listener to be used. This is notified of all errors detected during the * compilation. */ public void setErrorListener(ErrorListener listener) { compilerInfo.setErrorListener(listener); } /** * Get the ErrorListener being used during this compilation episode * * @return listener The error listener in use. This is notified of all errors detected during the * compilation. Returns null if no user-supplied ErrorListener has been set. */ public ErrorListener getErrorListener() { return compilerInfo.getErrorListener(); } /** * Say that the stylesheet must be compiled to be schema-aware, even if it contains no * xsl:import-schema declarations. Normally a stylesheet is treated as schema-aware * only if it contains one or more xsl:import-schema declarations. If it is not schema-aware, * then all input documents must be untyped, and validation of temporary trees is disallowed * (though validation of the final result tree is permitted). Setting the argument to true * means that schema-aware code will be compiled regardless. * * @param schemaAware If true, the stylesheet will be compiled with schema-awareness * enabled even if it contains no xsl:import-schema declarations. If false, the stylesheet * is treated as schema-aware only if it contains one or more xsl:import-schema declarations. * @since 9.2 */ public void setSchemaAware(boolean schemaAware) { compilerInfo.setSchemaAware(schemaAware); } /** * Ask whether schema-awareness has been requested by means of a call on * {@link #setSchemaAware} * * @return true if schema-awareness has been requested * @since 9.2 */ public boolean isSchemaAware() { return compilerInfo.isSchemaAware(); } /** * Set the target edition under which the stylesheet will be executed. * * @param edition the Saxon edition for the run-time environment. One of "EE", "PE", "HE", or "JS". * @since 9.7.0.5. Experimental and subject to change. */ public void setTargetEdition(String edition) { if (!("EE".equals(edition) || "PE".equals(edition) || "HE".equals(edition) || "JS".equals(edition))) { throw new IllegalArgumentException("Unknown Saxon edition " + edition); } compilerInfo.setTargetEdition(edition); } /** * Get the target edition under which the stylesheet will be executed. * * @return the Saxon edition for the run-time environment. One of "EE", "PE", "HE", or "JS". * @since 9.7.0.5. Experimental and subject to change. */ public String getTargetEdition() { return compilerInfo.getTargetEdition(); } /** * Bind a collation URI to a collation * * @param uri the absolute collation URI * @param collation a {@link java.text.Collator} object that implements the required collation * @throws IllegalArgumentException if an attempt is made to rebind the standard URI * for the Unicode codepoint collation * @since 9.5 * @deprecated since 9.6. Collations are now held globally. If this method is called, the effect * is to update the pool of collations held globally by the Processor. */ public void declareCollation(String uri, final java.text.Collator collation) { getProcessor().declareCollation(uri, collation); } /** * Declare the default collation * * @param uri the absolute URI of the default collation. This URI must have been bound to a collation * using the method {@link #declareCollation(String, java.text.Collator)}, or it must be a * collation that is recognized implicitly, such as a UCA collation * @throws IllegalStateException if the collation URI has not been registered, unless it is the standard * Unicode codepoint collation which is registered implicitly * @since 9.5 */ public void declareDefaultCollation(String uri) { StringCollator c; try { c = getProcessor().getUnderlyingConfiguration().getCollation(uri); } catch (XPathException e) { c = null; } if (c == null) { throw new IllegalStateException("Unknown collation " + uri); } compilerInfo.setDefaultCollation(uri); } /** * Get the default collation * * @return the URI of the default collation if one has been set, or the URI of the codepoint collation otherwise * @since 9.7.0.2 */ public String getDefaultCollation() { return compilerInfo.getDefaultCollation(); } /** * Set the XSLT (and XPath) language level to be supported by the processor. * * @param version the language level to be supported. The value 2.0 requests a processor conforming to the * XSLT 2.0 specification; 3.0 requests an XSLT 3.0 processor, while the value "0.0" (which is the * default setting in the absence of a call on this method) gets a processor according to the * value of the version attribute on the xsl:stylesheet element. *

Although this interface can be used to run a 1.0 stylesheet, it is not possible to request * a 1.0 processor; Saxon will handle it as a 2.0 processor in backwards-compatibility mode, which * is not quite the same thing.

*

Note that Saxon-HE does not support XSLT 3.0. However, requesting 3.0 * via this interface does not cause an error; an error only occurs if the stylesheet * actually uses XSLT 3.0 features.

* @throws IllegalArgumentException if the value is not equal to 0.0, 2.0, or 3.0 * @since 9.3 */ public void setXsltLanguageVersion(String version) { int v = 0; if ("2.0".equals(version)) { v = 20; } else if ("3.0".equals(version)) { v = 30; } else if ("0.0".equals(version)) { v = 0; } else { throw new IllegalArgumentException("XSLT version must be 0.0, 2.0, or 3.0"); } compilerInfo.setXsltVersion(v); } /** * Get the XSLT (and XPath) language level supported by the processor. * * @return the language level supported. The value 2.0 represents a processor conforming to the * XSLT 2.0 specification; 3.0 represents an XSLT 3.0 processor, while the value zero (which is the * default setting in the absence of a call on {@link #setXsltLanguageVersion} represents a processor * selected according to the value of the version attribute on the xsl:stylesheet element. * @since 9.3 */ public String getXsltLanguageVersion() { int v = compilerInfo.getXsltVersion(); switch (v) { case 0: return "0.0"; case 20: return "2.0"; case 30: return "3.0"; default: return "" + v; } } /** * Ask whether assertions (xsl:assert instructions) should be enabled. By default * they are disabled. If assertions are enabled at compile time, then by * default they will also be enabled at run time; but they can be * disabled at run time by specific request * * @return true if assertions are enabled at compile time * @since 9.7 */ public boolean isAssertionsEnabled() { return compilerInfo.isAssertionsEnabled(); } /** * Say whether assertions (xsl:assert instructions) should be enabled. By default * they are disabled. If assertions are enabled at compile time, then by * default they will also be enabled at run time; but they can be * disabled at run time by specific request * * @param enabled true if assertions are enabled at compile time * @since 9.7 */ public void setAssertionsEnabled(boolean enabled) { compilerInfo.setAssertionsEnabled(enabled); } /** * Set whether trace hooks are to be included in the compiled code. To use tracing, it is necessary * both to compile the code with trace hooks included, and to supply a TraceListener at run-time * * @param option true if trace code is to be compiled in, false otherwise * @since 9.3 */ public void setCompileWithTracing(boolean option) { if (option) { compilerInfo.setCodeInjector(new XSLTTraceCodeInjector()); } else { compilerInfo.setCodeInjector(null); } } /** * Ask whether trace hooks are included in the compiled code. * * @return true if trace hooks are included, false if not. * @since 9.3 */ public boolean isCompileWithTracing() { return compilerInfo.isCompileWithTracing(); } /** * Set whether bytecode should be generated for the compiled stylesheet. This option * is available only with Saxon-EE. The default depends on the setting in the configuration * at the time the XsltCompiler is instantiated, and by default is true for Saxon-EE. * * @param option true if bytecode is to be generated, false otherwise * @since 9.6 */ public void setGenerateByteCode(boolean option) { compilerInfo.setGenerateByteCode(option); } /** * Ask whether bytecode is to be generated in the compiled code. * * @return true if bytecode is to be generated, false if not. * @since 9.6 */ public boolean isGenerateByteCode() { return compilerInfo.isGenerateByteCode(); } // /** // * Import a compiled XQuery function library. // * @param queryCompiler An XQueryCompiler that has been used to compile a library of XQuery functions // * (by using one of the overloaded methods named compileLibrary). // * @param namespace The namespace of the functions that are to be made available to the stylesheet. // * All the global functions with this namespace that are // * defined in libraries that have been compiled using this XQueryCompiler are added to the static context // * of the XSLT stylesheet. The stylesheet does not need to (and should not) contain a call on // * saxon:import-query to import these functions. // */ // // public void importXQueryLibrary(XQueryCompiler queryCompiler, String namespace) { // compilerInfo.importXQueryLibrary(queryCompiler.) // } /** * Get the stylesheet associated * via the xml-stylesheet processing instruction (see * http://www.w3.org/TR/xml-stylesheet/) with the document * document specified in the source parameter, and that match * the given criteria. If there are several suitable xml-stylesheet * processing instructions, then the returned Source will identify * a synthesized stylesheet module that imports all the referenced * stylesheet module. *

*

The returned Source will have an absolute URI, created by resolving * any relative URI against the base URI of the supplied source document, * and redirected if necessary by using the URIResolver associated with this * XsltCompiler.

* * @param source The XML source document. Note that if the source document * is available as an instance of {@link XdmNode}, a corresponding Source * can be obtained using the method {@link net.sf.saxon.s9api.XdmNode#asSource()}. * If the source is a StreamSource or SAXSource, it will be read only as far as the * xml-stylesheet processing instruction (but the Source will be consumed and must not * be re-used). * @param media The media attribute to be matched. May be null, in which * case the prefered templates will be used (i.e. alternate = no). * Note that Saxon does not implement the complex CSS3-based syntax for * media queries. By default, the media value is simply ignored. An algorithm for * comparing the requested media with the declared media can be defined using * the method {@link Configuration#setMediaQueryEvaluator(Comparator)}. * @param title The value of the title attribute to match. May be null. * @param charset The value of the charset attribute to match. May be null. * @return A Source object suitable for passing to {@link #compile(javax.xml.transform.Source)}. * @throws SaxonApiException if any problems occur, including the case where no matching * xml-stylesheet processing instruction is found. * @since 9.6 */ public Source getAssociatedStylesheet(Source source, String media, String title, String charset) throws SaxonApiException { try { return StylesheetModule.getAssociatedStylesheet(config, compilerInfo.getURIResolver(), source, media, title, charset); } catch (XPathException e) { throw new SaxonApiException(e); } } /** * Compile a library package. *

*

The source argument identifies an XML file containing an <xsl:package> element. Any packages * on which this package depends must have been made available to the XsltCompiler * by importing them either using {@link #importPackage} * or added previously through {@link #addCompilePackages(Iterable, boolean)}}.

* * @param source identifies an XML document holding the the XSLT package to be compiled * @return the XsltPackage that results from the compilation. Note that this package * is not automatically imported to this XsltCompiler; if the package is required * for use in subsequent compilations then it must be explicitly imported. * @throws SaxonApiException if the source cannot be read or if static errors are found during the * compilation. Any such errors will have been notified to the registered ErrorListener * if there is one, or reported on the System.err output stream otherwise. * @since 9.6 */ public XsltPackage compilePackage(Source source) throws SaxonApiException { try { Compilation compilation; if (source instanceof DocumentImpl && ((DocumentImpl)source).getDocumentElement() instanceof StyleElement) { compilation = ((StyleElement)((DocumentImpl) source).getDocumentElement()).getCompilation(); } else { compilation = new Compilation(config, compilerInfo); } XsltPackage pack = new XsltPackage(processor, compilation.compilePackage(source).getStylesheetPackage()); if (compilation.getErrorCount() > 0) { throw new SaxonApiException("Package compilation failed: " + compilation.getErrorCount() + " errors reported"); } return pack; } catch (XPathException e) { throw new SaxonApiException(e.getMessage()); } } /** * Initialise a fresh package library for this compiler * This permits incremental additions to the library */ public void newPackageLibrary() { compilerInfo.setPackageLibrary(new PackageLibrary()); } public PackageLibrary getPackageLibrary() { return compilerInfo.getPackageLibrary(); } public void setPackageLibrary(PackageLibrary packageLibrary) { compilerInfo.setPackageLibrary(packageLibrary); } /** * Compile a list of packages. * * @param sources the collection of packages to be compiled, in the form of an Iterable * @return the collection of compiled packages, in the form of an Iterable. * @throws SaxonApiException if the source cannot be read or if static errors are found during the * compilation. Any such errors will have been notified to the registered ErrorListener * if there is one, or reported on the System.err output stream otherwise. * @since 9.6 */ public Iterable compilePackages(Iterable sources) throws SaxonApiException, XPathException { Compilation compilation = new Compilation(config, compilerInfo); compilerInfo.setPackageLibrary(new PackageLibrary()); List result = new ArrayList(); ArrayList depends = new ArrayList(); for (Source s : sources) { DocumentImpl document = StylesheetModule.loadStylesheetModule(s, true, compilation, NestedIntegerValue.TWO); ElementImpl packageElement = document.getDocumentElement(); String packageName = packageElement.getAttributeValue("", "name"); if (packageName == null) { throw new SaxonApiException("Outermost element must be an xsl:package element with a name attribute"); } depends.add(new PackDepends(document)); } for (PackDepends p : resolveDependencies(depends)) { XsltPackage packagei = compilePackage(p.doc); compilerInfo.getPackageLibrary().addPackage(packagei.getName(), packagei.getUnderlyingPreparedPackage()); result.add(packagei); } return result; } /** * Add new packages to a package library. * It assumes that a library (possibly empty) already exists in the compilerInfo and adds to anything there. * In particular stylesheets can exploit packages that are already compiled * and they can be linked during this process * * @param sources Sources for the packages * @param link Link each of the packages when loaded if true * @return the collection of compiled packages, in the form of an Iterable * ..... note that unless link = true these will probably require link() processing before execution. * @throws SaxonApiException if the source cannot be read or if static errors are found during the * compilation. Any such errors will have been notified to the registered ErrorListener * if there is one, or reported on the System.err output stream otherwise. * @throws XPathException if there are XPath errors in the stylesheet */ public Iterable addCompilePackages(Iterable sources, boolean link) throws SaxonApiException, XPathException { Compilation compilation = new Compilation(config, compilerInfo); List result = new ArrayList(); ArrayList depends = new ArrayList(); for (Source s : sources) { DocumentImpl document = StylesheetModule.loadStylesheetModule(s, true, compilation, NestedIntegerValue.TWO); // ElementImpl packageElement = document.getDocumentElement(); // String packageName = packageElement.getAttributeValue("", "name"); // if (packageName == null) { // throw new SaxonApiException("Outermost element must be an xsl:package element with a name attribute"); // } depends.add(new PackDepends(document)); } // // Find the packages that have already been processed and thus have had dependencies resolved. // ArrayList alreadyResolved = new ArrayList(); // for (StylesheetPackage p : compilerInfo.getPackageLibrary().getPackages()) { // alreadyResolved.add(new PackDepends(p)); // } PackageLibrary pl = compilerInfo.getPackageLibrary(); // Compile the newly provided packages in dependency order and add them to the package library ArrayList resolved = resolveDependencies(depends); for (PackDepends p : resolved) { if (p.doc != null) { XsltPackage packagei; ElementImpl top = p.doc.getDocumentElement(); if (top.getURI().equals(NamespaceConstant.SAXON_XSLT_EXPORT)) { IPackageLoader loader = config.makePackageLoader(); StylesheetPackage pack = loader.loadPackageDoc(p.doc); packagei = new XsltPackage(processor, pack); } else { packagei = compilePackage(p.doc); } pl.addPackage(packagei.getName(), packagei.getUnderlyingPreparedPackage()); if (link) { packagei.link(); } result.add(packagei); } } return result; } /* At present we don't need to track the package versions, but we could to pre-evaluate and avoid * compiling packages that aren't used. */ /** * A class to accommodate a package and its dependencies * - it can either hold a pre-compiled or a post-compiled version */ private class PackDepends { DocumentImpl doc; StylesheetPackage pack; String packageName; PackageVersion packageVersion; ArrayList uses; PackDepends(StylesheetPackage p) { pack = p; packageName = p.getPackageName(); packageVersion = p.getPackageVersion(); /* We shouldn't need to track the package uses of a compiled package */ //p.getUsedPackages(); } PackDepends(DocumentImpl d) throws XPathException { doc = d; ElementImpl packageElement = doc.getDocumentElement(); uses = new ArrayList(); if (packageElement.getURI().equals(NamespaceConstant.XSLT)) { packageName = packageElement.getAttributeValue("", "name"); if (packageName == null) { packageName = "#unnamedPackage"; } String pv = packageElement.getAttributeValue("", "package-version"); packageVersion = pv == null ? PackageVersion.ONE : new PackageVersion(pv); // TODO: this is flawed - see bug 2779 AxisIterator iter = doc.iterateAxis(AxisInfo.DESCENDANT, new NameTest(Type.ELEMENT, StandardNames.XSL_USE_PACKAGE, config.getNamePool())); NodeInfo current; while ((current = iter.next()) != null) { uses.add(new UsePack(current)); } } else { packageName = packageElement.getAttributeValue("", "name"); String pv = packageElement.getAttributeValue("", "packageVersion"); packageVersion = pv == null ? PackageVersion.ONE : new PackageVersion(pv); } } // For checking that this package is suitable for a given use // typically via a contains() invocation boolean equals(UsePack u) { return u.packageName.equals(packageName) && u.ranges.contains(packageVersion); } } /** * Describes an xsl:use-package requirement from within a package, * in terms of a name and a set of version ranges */ private class UsePack { String packageName; PackageVersionRanges ranges; UsePack(NodeInfo current) throws XPathException { packageName = Whitespace.trim(current.getAttributeValue("", "name")); String pvr = Whitespace.trim(current.getAttributeValue("", "package-version")); ranges = new PackageVersionRanges(pvr == null ? "*" : pvr); } } /** * Reorder the packages to hopefully place them in increasing dependency order. * * @param in packages to be analysed * @return packages in increasing dependency order * @throws SaxonApiException if there appears to be circular dependency */ ArrayList resolveDependencies(ArrayList in) throws SaxonApiException { ArrayList resolved = new ArrayList(); resolveDependencies(in, resolved); return resolved; } /** * Reorder the packages to hopefully place them in increasing dependency order. * * @param in packages remaining to be analysed * @param resolved packages whose dependencies have already been resolved * @return packages in increasing dependency order, i.e. * it should be possible to compile and add to the package library each in sequence * @throws SaxonApiException if there appears to be circular dependency, * which is effectively that at some pass every stylesheet has a dependency on one * whose dependency order is still to be determined. */ private void resolveDependencies(ArrayList in, ArrayList resolved) throws SaxonApiException { if (in.isEmpty()) { return; } ArrayList unresolved = new ArrayList(); boolean changed = false; for (PackDepends p : in) { if (allDependenciesSatisfied(p, resolved)) { resolved.add(p); changed = true; } else { unresolved.add(p); } } if (changed) { resolveDependencies(unresolved, resolved); } else { String message = "Unable to resolve package dependencies for " + unresolved.get(0).packageName; throw new SaxonApiException(message); // TODO: be more specific if there's a circularity } } private boolean allDependenciesSatisfied(PackDepends packDepends, List resolved) { PackageLibrary lib = getPackageLibrary(); for (UsePack u : packDepends.uses) { boolean found = false; if (lib.getPackage(u.packageName, u.ranges) != null) { continue; } for (PackDepends pd : resolved) { if (pd.packageName.equals(u.packageName) && u.ranges.contains(pd.packageVersion)) { found = true; break; } } if (!found) { return false; } } return true; } /** * Load a compiled package from a file or from a remote location. *

*

The supplied URI represents the location of a resource which must have been originally * created using {@link XsltPackage#save(java.io.File)}.

*

*

The result of loading the package is returned as an XsltPackage object. * Note that this package is not automatically imported to this XsltCompiler; * if the package is required for use in subsequent compilations then it must be explicitly * imported.

* * @param location the location from which the package is to be loaded, as a URI * @return the compiled package loaded from the supplied file or remote location * @throws SaxonApiException if no resource can be loaded from the supplied location or if the * resource that is loaded is not a compiled package, or if the compiled package is not * consistent with this XsltCompiler (for example, if it was created using an * incompatible Saxon version). * @since 9.7 */ public XsltPackage loadLibraryPackage(URI location) throws SaxonApiException { try { Source input = new StreamSource(location.toString()); IPackageLoader loader = processor.getUnderlyingConfiguration().makePackageLoader(); if(loader != null){ StylesheetPackage pack = loader.loadPackage(input); return new XsltPackage(processor, pack); } throw new SaxonApiException("Loading library package requires Saxon PE or higher"); } catch (XPathException e) { throw new SaxonApiException(e); } } /** * Load a compiled package from a file or from a remote location, with the intent to use this as a complete * executable stylesheet, not as a library package. *

*

The supplied URI represents the location of a resource which must have been originally * created using {@link XsltPackage#save(java.io.File)}.

*

*

The result of loading the package is returned as an XsltExecutable object. *

* * @param location the location from which the package is to be loaded, as a URI * @return the compiled package loaded from the supplied file or remote location * @throws SaxonApiException if no resource can be loaded from the supplied location or if the * resource that is loaded is not a compiled package, or if the compiled package is not * consistent with this XsltCompiler (for example, if it was created using an * incompatible Saxon version). * @since 9.7 */ public XsltExecutable loadExecutablePackage(URI location) throws SaxonApiException { return loadLibraryPackage(location).link(); } /** * Import a library package. Calling this method makes the supplied package available for reference * in the xsl:use-package declaration of subsequent compilations performed using this * XsltCompiler. * * @param thePackage the package to be imported * @throws SaxonApiException if the imported package was created under a different {@link Processor} * @since 9.6 */ public void importPackage(XsltPackage thePackage) throws SaxonApiException { if (thePackage.getProcessor() != processor) { throw new SaxonApiException("The imported package and the XsltCompiler must belong to the same Processor"); } compilerInfo.getPackageLibrary().addPackage(thePackage.getName(), thePackage.getUnderlyingPreparedPackage()); } /** * Compile a stylesheet. *

*

Note: the term "compile" here indicates that the stylesheet is converted into an executable * form. There is no implication that this involves code generation.

*

*

The source argument identifies the XML document holding the principal stylesheet module. Other * modules will be located relative to this module by resolving against the base URI that is defined * as the systemId property of the supplied Source.

*

*

The following kinds of {@link javax.xml.transform.Source} are recognized:

*

*

    *
  • {@link javax.xml.transform.stream.StreamSource}, allowing the stylesheet to be supplied as a * URI, as a {@link java.io.File}, as an {@link java.io.InputStream}, or as a {@link java.io.Reader}
  • *
  • {@link javax.xml.transform.sax.SAXSource}, allowing the stylesheet to be supplied as a stream * of SAX events from a SAX2-compliant XML parser (or any other source of SAX events)
  • *
  • {@link javax.xml.transform.dom.DOMSource}, allowing the stylesheet to be supplied as a * DOM tree. This option is available only if saxon9-dom.jar is on the classpath.
  • *
  • Document wrappers for XOM, JDOM, or DOM4J trees, provided the appropriate support libraries * are on the classpath
  • *
  • A Saxon NodeInfo, representing the root of a tree in any of the native tree formats supported * by Saxon
  • *
  • An {@link XdmNode} representing the document node of the stylesheet module
  • *
* * @param source Source object representing the principal stylesheet module to be compiled * @return an XsltExecutable, which represents the compiled stylesheet. * @throws SaxonApiException if the stylesheet contains static errors or if it cannot be read. Note that * the exception that is thrown will not contain details of the actual errors found in the stylesheet. These * will instead be notified to the registered ErrorListener. The default ErrorListener displays error messages * on the standard error output. */ public XsltExecutable compile(/*@NotNull*/ Source source) throws SaxonApiException { try { PreparedStylesheet pss = Compilation.compileSingletonPackage(config, compilerInfo, source); return new XsltExecutable(processor, pss); } catch (XPathException e) { throw new SaxonApiException(e); } } /** * Get the underlying CompilerInfo object, which provides more detailed (but less stable) control * over some compilation options * * @return the underlying CompilerInfo object, which holds compilation-time options. The methods on * the CompilerInfo object are not guaranteed stable from release to release. */ public CompilerInfo getUnderlyingCompilerInfo() { return compilerInfo; } /** * Supply a List object which will be populated with information about any static errors * encountered during the transformation. * * @param errorList a List (typically empty) to which information will be appended about * static errors found during the compilation. Each such error is represented by a * {@link StaticError} object. */ public void setErrorList(List errorList) { compilerInfo.setErrorListener(new ErrorGatherer(errorList)); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy