Skip to content

Instantly share code, notes, and snippets.

@philippn
Last active September 6, 2019 16:47
Show Gist options
  • Select an option

  • Save philippn/1a792ed79374f2c7fd51df696db931a4 to your computer and use it in GitHub Desktop.

Select an option

Save philippn/1a792ed79374f2c7fd51df696db931a4 to your computer and use it in GitHub Desktop.
A XSL transformation that constructs a single bootstrap.xsl from a bunch of XSL files comprising a pipeline. Useful for getting a XSL pipeline to work in Saxon-JS. In order to do so, first run this XSL, then compile the resulting bootstrap.xsl into SEF format, i.e. by using Oxygen.
<xsl:stylesheet
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:variable name="steps" select="collection('./xsl?select=*.xsl')" as="node()*"/>
<xsl:template match="/">
<xsl:for-each select="$steps">
<xsl:sort select="tokenize(base-uri(.), '/')[last()]"/>
<xsl:variable name="filename" select="tokenize(base-uri(.), '/')[last()]" as="xs:string"/>
<xsl:variable name="fullname" select="substring-before($filename, '.xsl')"/>
<xsl:variable name="shortname" select="concat('step', position())"/>
<xsl:variable name="package-decl" as="element(xsl:package)">
<xsl:element name="package" namespace="http://www.w3.org/1999/XSL/Transform">
<xsl:attribute name="name" select="$fullname"/>
<xsl:attribute name="package-version" select="'1.0'"/>
<xsl:attribute name="declared-modes" select="'no'"/>
<xsl:attribute name="exclude-result-prefixes" select="'#all'"/>
<xsl:attribute name="version" select="'3.0'"/>
<xsl:namespace name="{$shortname}" select="concat('urn:pipeline:', $shortname)"/>
<xsl:element name="import" namespace="http://www.w3.org/1999/XSL/Transform">
<xsl:attribute name="href" select="concat('./xsl/', $filename)"/>
</xsl:element>
<xsl:element name="function" namespace="http://www.w3.org/1999/XSL/Transform">
<xsl:attribute name="name" select="concat($shortname, ':main')"/>
<xsl:attribute name="as" select="'document-node()'"/>
<xsl:attribute name="visibility" select="'public'"/>
<xsl:element name="param" namespace="http://www.w3.org/1999/XSL/Transform">
<xsl:attribute name="name" select="'input'"/>
<xsl:attribute name="as" select="'document-node()'"/>
</xsl:element>
<xsl:element name="document" namespace="http://www.w3.org/1999/XSL/Transform">
<xsl:element name="apply-templates" namespace="http://www.w3.org/1999/XSL/Transform">
<xsl:attribute name="select" select="'$input'"/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:variable>
<xsl:result-document href="{concat('./package_', $fullname, '.xsl')}" indent="yes">
<xsl:sequence select="$package-decl"/>
</xsl:result-document>
</xsl:for-each>
<xsl:result-document href="./saxon-config.xml" indent="yes">
<configuration xmlns="http://saxon.sf.net/ns/configuration" edition="EE" label="Import packages">
<xsltPackages>
<xsl:for-each select="$steps">
<xsl:variable name="filename" select="tokenize(base-uri(.), '/')[last()]" as="xs:string"/>
<xsl:variable name="fullname" select="substring-before($filename, '.xsl')"/>
<package name="{$fullname}" version="1.0" sourceLocation="{concat('./package_', $fullname, '.xsl')}"/>
</xsl:for-each>
</xsltPackages>
</configuration>
</xsl:result-document>
<xsl:variable name="bootstrap-decl" as="element(xsl:stylesheet)">
<xsl:element name="stylesheet" namespace="http://www.w3.org/1999/XSL/Transform">
<xsl:attribute name="exclude-result-prefixes" select="'#all'"/>
<xsl:attribute name="version" select="'3.0'"/>
<xsl:for-each select="$steps">
<xsl:variable name="shortname" select="concat('step', position())"/>
<xsl:namespace name="{$shortname}" select="concat('urn:pipeline:', $shortname)"/>
</xsl:for-each>
<xsl:for-each select="$steps">
<xsl:variable name="filename" select="tokenize(base-uri(.), '/')[last()]" as="xs:string"/>
<xsl:variable name="fullname" select="substring-before($filename, '.xsl')"/>
<xsl:element name="use-package" namespace="http://www.w3.org/1999/XSL/Transform">
<xsl:attribute name="name" select="$fullname"/>
<xsl:attribute name="version" select="'1.0'"/>
</xsl:element>
</xsl:for-each>
<xsl:element name="template" namespace="http://www.w3.org/1999/XSL/Transform">
<xsl:attribute name="match" select="'/'"/>
<xsl:for-each select="$steps">
<xsl:variable name="input-pointer">
<xsl:choose>
<xsl:when test="position() eq 1">
<xsl:value-of select="'.'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat('$result', position()-1)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:element name="variable" namespace="http://www.w3.org/1999/XSL/Transform">
<xsl:attribute name="name" select="concat('result', position())"/>
<xsl:attribute name="select" select="concat('step', position(), ':main(', $input-pointer, ')')"/>
<xsl:attribute name="as" select="'document-node()'"/>
</xsl:element>
</xsl:for-each>
<xsl:element name="sequence" namespace="http://www.w3.org/1999/XSL/Transform">
<xsl:attribute name="select" select="concat('$result', count($steps))"/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:variable>
<xsl:result-document href="./bootstrap.xsl" indent="yes">
<xsl:sequence select="$bootstrap-decl"/>
</xsl:result-document>
</xsl:template>
</xsl:stylesheet>
@gimsieke

gimsieke commented Sep 6, 2019

Copy link
Copy Markdown

Excellent, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment