2

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!

Nikowhy
  • 141
  • 2
  • 10
  • 1
    Using multiple stylesheets via xsl:include is normally completely straightforward and it's hard to see what you are doing wrong. But the message about "external entities" is very confusing: this suggests you are using DTDs and entities for inclusion, not using xsl:include at all. I think you need to tell us more precisely what you are doing. Don't tell us you've tried everything: tell us one thing that you've tried, describe it in detail, and tell us exactly how it failed. And try to get a simple noddy example working before you try it on you massive stylesheet. – Michael Kay Mar 05 '18 at 22:28

1 Answers1

1

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" />
unor
  • 92,415
  • 26
  • 211
  • 360
Nikowhy
  • 141
  • 2
  • 10