Wednesday, April 13, 2016

Manage includes in XSL

Leave a Comment

I have a code generating XSL that includes several XSL files. The files are included in order to call templates. There can be the case when one of the files that I need to include does not exist in my file. I could create a dummy file with the same name and an empty template when the original file is missing but I would get a duplicate error when the original file exists.

Bellow is an example:

<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0"      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"     xmlns:xs="http://www.w3.org/2001/XMLSchema"     xmlns:date="java.util.Date"                     xmlns:vector="java.util.Vector"                     xmlns:math="java.lang.Math"     xmlns:int="java.lang.Integer" xmlns:saxon="http://saxon.sf.net/"     extension-element-prefixes="date vector math int saxon">   <xsl:include href="file_for_template1.xsl"/> <!-- MIGHT NOT EXIST -->   <xsl:include href="file_for_template2.xsl"/> <!-- MIGHT NOT EXIST -->   <xsl:include href="file_for_template3.xsl"/> <!-- MIGHT NOT EXIST -->   <xsl:output method="xml"                version="1.0"                encoding="UTF-8"                indent="yes"/>   <xsl:variable name="path"                  select="concat(base-uri(//Test),'.temp')"/>    <xsl:template match="/">       <xsl:result-document href="file:/{$path}" method="xml">        <!-- create the root node -->       <TEST_GENERATION xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"                         xsi:noNamespaceSchemaLocation="test.xsd">          <xsl:element name="TEST_ELEMENT">           <!-- SHOULD NOT BE CALLED IF THE FILE DOES NOT EXIST -->           <xsl:call-template name="template1Call"/>            <!-- SHOULD NOT BE CALLED IF THE FILE DOES NOT EXIST -->           <xsl:call-template name="template2Call"/>            <!-- SHOULD NOT BE CALLED IF THE FILE DOES NOT EXIST -->           <xsl:call-template name="template3Call"/>          </xsl:element>        <!-- end of root node -->       </TEST_GENERATION>       <!-- end of document -->     </xsl:result-document>   </xsl:template> 

1 Answers

Answers 1

I wish you had told us more about the problem you are trying to solve, rather than focusing on the difficulties you are having with your chosen approach. If we knew the real requirement, we might be able to suggest better ways of tackling it.

The use-when attribute allows you compile-time control of this kind, enabling you to selectively exclude parts of a stylesheet (including xsl:import/include declarations) based on external conditions. You could try:

<xsl:import href="module1.xsl"              use-when="doc-available('module1.xsl')"/> 

XSLT 2.0 says that in the context for evaluating use-when expressions there are no available documents, so this will always return false, but this rule changes in XSLT 3.0. In 3.0 you could also pass a static parameter to say whether an xsl:import should be active or not, and reference the static parameter in the use-when attribute.

Your next problem will be that the call-template instructions will fail if the import has been excluded, unless you do something to de-activate these instructions as well. One solution would be to replace them with function calls, which you can conditionally exclude with a test on function-available().

But I'm uneasy about helping you down this road, which is why I didn't answer the question before. I think I might be leading you into a swamp, and that if we knew your real destination, we might be able to suggest a better route to it than the one you are taking.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment