Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XSLT conditional include of external file

Tags:

xml

xslt

I want to perform a conditional include in XSLT, but xsl:include is a top level element. You can only use xsl:if or xsl:choose inside of a template. Is there any kind of hack or work around which allows a conditional include of an external file? I tried to use the document() function, but it fails to load my external file ( probably because it doesn't conform to some set of rules which would make it "valid" ).

My external xml file is a bunch of xslt code fragments. depending on the value of a variable in the main XSLT file, the corisponding code from the external file should be "copy/pasted" in place ( like conditional include in C or PHP ).

The flow of my main XSLT file should proceed in the following manner:

$configurationMode
if ( $configurationMode = Standard ) { xsl:include="standard.xml" } else { xsl:include="alt.xml" }

Obviously I cannot do it as simply as the above, hence why I am asking if there is a hack or workaround.

like image 380
Roy Jons Avatar asked Jan 24 '12 17:01

Roy Jons


Video Answer


3 Answers

This cannot be done with XSLT 1.0 and can be done (to a very limited extent) in XSLT 2.0 using the use-when attribute.

There exist non-xslt ways of achieving the wanted dynamic altering of an xsl:include or an xsl:import directive.

One such method is to load the XSLT stylesheet as an XmlDocument, and using the available DOM methods for access to and modification of attributes, to set the href attribute to the desired value. Then initiate the transformation from this in-memory-modified XMLDocument-contained XSLT stylesheet.

like image 127
Dimitre Novatchev Avatar answered Sep 21 '22 14:09

Dimitre Novatchev


As I understand things, 'include' happens when the xml parser is parsing and compiling the style sheet. This means that no logic or expression evaluation can happen before the include gets processed and therefore there's no way to make it conditional as such. You need to make the conditional behavior happen outside of the style sheet.

Have a look at this http://www.dpawson.co.uk/xsl/sect2/N4760.html#d6065e100

In particular does this comment by Mike Kay help:

This has been raised a number of times. On a previous thread we came to the conclusion that the user was trying to write a general-purpose stylesheet G and then specialize it by conditionally including a special-purpose stylesheet A or B. The way to meet this requirement is to have A and B include G, not the other way around, and then you conditionally select A or B as the principal stylesheet when starting the transformation.

like image 20
Kevan Avatar answered Sep 21 '22 14:09

Kevan


Try inverting the structure: if you have two special purpose modules pink.xsl and blue.xsl, and a general-purpose module baby.xsl, then instead of trying to import/include one of pink.xsl or blue.xsl into baby.xsl, instead use pink.xsl or blue.xsl as the top-level entry stylesheet, and have each of these two import baby.xsl. That's the way it was designed to be used, it's nto a hack or a workaround.

Alternatively, given this description of your scenario "My external xml file is a bunch of xslt code fragments", a better approach in your case might be to assemble the stylesheet from these fragments as a separate step, using an XSLT tranformation rather than using xsl:include/xsl:import.

like image 44
Michael Kay Avatar answered Sep 21 '22 14:09

Michael Kay