Reputation: 151
I am writing an XSLT 1.0 stylesheet for a big project and it is becoming massive. I would like to take some parts in separate smaller stylesheets and use them in my "main" stylesheet with xsl:include
. All XSLT stylesheets are in the same directory.
I've seen numerous trivial examples that suggest merely including a statement like <xsl:include href="smallerStylesheet.xslt"/>
within the main stylesheet would do the job. I tried it, but got the annoying I/O warning : failed to load external entity "smallerStylesheet.xslt"
. Tried all sorts of things like <xsl:include href="file:///smallerStylesheet.xslt"/>
, <xsl:include href="file:./smallerStylesheet.xslt"/>
and many other variations.
Specifying the full path to the file on my local machine works well, but is not an option as this is supposed to run as a standalone service. I researched the topic and found out that the base URI of my stylesheet is important in order to resolve relative URI paths properly. Yet, I cannot figure out an appropriate way to solve my problem.
EDIT:
I tried to make several simpler examples work, e.g. https://msdn.microsoft.com/en-us/library/ms256125(v=vs.110).aspx
More specifically, with a collection.xml:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="xslinclude.xsl"?>
<COLLECTION>
<BOOK>
<TITLE>Lover Birds</TITLE>
<AUTHOR>Cynthia Randall</AUTHOR>
<PUBLISHER>Lucerne Publishing</PUBLISHER>
</BOOK>
<BOOK>
<TITLE>The Sundered Grail</TITLE>
<AUTHOR>Eva Corets</AUTHOR>
<PUBLISHER>Lucerne Publishing</PUBLISHER>
</BOOK>
<BOOK>
<TITLE>Splish Splash</TITLE>
<AUTHOR>Paula Thurman</AUTHOR>
<PUBLISHER>Scootney</PUBLISHER>
</BOOK>
</COLLECTION>
Main stylesheet xslinclude.xsl:
<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:for-each select="COLLECTION/BOOK">
<xsl:apply-templates select="TITLE"/>
<xsl:apply-templates select="AUTHOR"/>
<xsl:apply-templates select="PUBLISHER"/>
<BR/> <!-- add this -->
</xsl:for-each>
</xsl:template>
<!-- The following template rule will not be called,
because the related template in the including stylesheet
will be called. If we move this template so that
it follows the xsl:include instruction, this one
will be called instead.-->
<xsl:template match="TITLE">
<DIV STYLE="color:blue">
Title: <xsl:value-of select="."/>
</DIV>
</xsl:template>
<xsl:include href="xslincludefile.xsl" />
</xsl:stylesheet>
And a smaller stylesheet xslincludefile.xsl:
<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xml:space="preserve">
<xsl:template match="TITLE">
Title - <xsl:value-of select="."/><BR/>
</xsl:template>
<xsl:template match="AUTHOR">
Author - <xsl:value-of select="."/><BR/>
</xsl:template>
<xsl:template match="PUBLISHER">
Publisher - <xsl:value-of select="."/><BR/><!-- removed second <BR/> -->
</xsl:template>
</xsl:stylesheet>
I get the error Failed: xsl:include : unable to load xslincludefile.xsl
. Both stylesheets are in the same directory. I am working with Node.js and node-libxslt.
Any suggestions on the issue would be highly appreciated!
Upvotes: 2
Views: 957
Reputation: 151
Solution turned out to be extremely simple. As per node-libxslt documentation:
XSL includes are supported but relative paths must be given from the execution directory, usually the root of the project
So, if your stylesheets are in a "project" folder, make sure you specify:
<xsl:include href="project/xslincludefile.xsl" />
Upvotes: 1