I'm having some troubles with XSLHelper.fld method. I have a very simple XSLT file that I am trying to access sub-values that are inside my Sitecore image item.
Code Sample:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:sc="http://www.sitecore.net/sc"
xmlns:dot="http://www.sitecore.net/dot"
exclude-result-prefixes="dot sc">
<!-- output directives -->
<xsl:output method="html" indent="no" encoding="UTF-8" />
<!-- parameters -->
<xsl:param name="lang" select="'en'"/>
<xsl:param name="id" select="''"/>
<xsl:param name="sc_item"/>
<xsl:param name="sc_currentitem"/>
<!-- variables -->
<!-- Uncomment one of the following lines if you need a "home" variable in you code -->
<!--<xsl:variable name="home" select="sc:item('/sitecore/content/home',.)" />-->
<!--<xsl:variable name="home" select="/*/item[#key='content']/item[#key='home']" />-->
<!--<xsl:variable name="home" select="$sc_currentitem/ancestor-or-self::item[#template='site root']" />-->
<!-- entry point -->
<xsl:template match="*">
<xsl:apply-templates select="$sc_item" mode="main"/>
</xsl:template>
<!--==============================================================-->
<!-- main -->
<!--==============================================================-->
<xsl:template match="*" mode="main">
TEST BACKGROUND IMAGE
<br/>
ALT: <br/>
<xsl:value-of select="sc:fld('background',.,'alt')"/>
<br/>
SRC: <br/>
<xsl:value-of select="sc:fld('background',.,'src')"/>
<br/>
Field SRC: <br/>
<xsl:value-of select="sc:field('background',.,'src')"/>
</xsl:template>
</xsl:stylesheet>
When I test the following code, the results are strange as can be seen from the following screenshot:
You can clearly see that the alt field has a value and the src field is empty. So I definitely have access to my Sitecore image item but cannot get access to the src field.....
Can anyone shed some light on why the src field is empty?
Regards,
Comic Coder
As I stated on your other question, there is no longer a src attribute in the raw value of image fields. The alt attribute exists if you modify the Alternate Text in the properties of the image field or it will fall back to the alt text on the image item in the media library.
The sc:field method uses a field renderer to output a full <img> tag. The third parameter to that method is supposed to be for additional parameters like width and height or additional attributes. It should be formatted as a query string (e.g. width=150&height=100). It is probably just ignoring the src value that you are passing because it isn't valid.
Related
I realize that you are really good at programming and that your answers are dependable.
Is it possible for you to assist me in resolving an issue I am having with my xslt code? I'm new to progamming so I would appreciate any assistance I can get.
Your solution in grouping 3 divs in a row is found at the link below, but I do not know how to apply it to my code. I am using Sitecore and I have a div block that corresponds to each page generated to produce metro-like blocks, 3 in a row. So far I generates the desired divs but does not put them three in a row. My code is found below.
XSLT How can I wrap each 3 elements by div?
I would appreciate any help I can get.
<?xml version="1.0" encoding="UTF-8"?>
<!--=============================================================
File: ServicesFeatureblocks.xslt
Created by: sitecore\admin
Created: 3/27/2013 11:50:57 AM
Copyright notice at bottom of file
==============================================================-->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:sc="http://www.sitecore.net/sc"
xmlns:dot="http://www.sitecore.net/dot"
exclude-result-prefixes="dot sc">
<!-- output directives -->
<xsl:output method="html" indent="no" encoding="UTF-8" />
<!-- parameters -->
<xsl:param name="lang" select="'en'"/>
<xsl:param name="id" select="''"/>
<xsl:param name="sc_item"/>
<xsl:param name="sc_currentitem"/>
<!-- variables -->
<!-- Uncomment one of the following lines if you need a "home" variable in you code -->
<xsl:variable name="Services" select="sc:item('/sitecore/content/home/Services',.)" />
<!--<xsl:variable name="home" select="/*/item[#key='content']/item[#key='home']" />-->
<!--<xsl:variable name="home" select="$sc_currentitem/ancestor-or-self::item[#template='site root']" />-->
<!-- entry point -->
<xsl:template match="*">
<xsl:apply-templates select="$sc_item" mode="main"/>
</xsl:template>
<!--==============================================================-->
<!-- main -->
<!--==============================================================-->
<xsl:variable name="group" select="3" />
<xsl:template match="/">
<xsl:apply-templates select="$sc_currentitem[position() mod $group = 1]" />
</xsl:template>
<xsl:template match="item" mode="inner">
<div class="block orange">
<xsl:value-of select="sc:fld('Title',.)" />
</div>
<item/>
</xsl:template>
<xsl:template match="item">
<div>
<xsl:apply-templates
select="./item|following-sibling::services/item[position() < $group]" mode="inner" />
</div>
</xsl:template>
</xsl:stylesheet>
If you can use a sublayout instead of xslt rendering, You can achieve your functionality easily using Listview with GroupTemplate
<asp:ListView ID="listview1" runat="server" GroupItemCount="3" GroupPlaceholderID="groupPlaceholder"
ItemPlaceholderID="itemPlaceholder">
<LayoutTemplate>
<div class="productsContent">
<asp:PlaceHolder ID="groupPlaceholder" runat="server"></asp:PlaceHolder>
</div>
</LayoutTemplate>
<GroupTemplate>
<div class="product-rows">
<asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder>
</div>
</GroupTemplate>
<ItemTemplate>
<div class="products">
</div>
</ItemTemplate>
</asp:ListView>
I have an XSLT application which reads the internal format of Microsoft Word 2007/2010 zipped XML and translates it into HTML5 with XSLT. I am investigating how to add the ability to optionally read OpenOffice documents instead of MSWord.
Microsoft stores XML for footnote text separately from the XML of the document text, which happens to suit me because I want the footnotes in a block at the end of the output HTML page.
However, unfortunately for me, OpenOffice puts each footnote right next to its reference, inline with the text of the document. Here is a simple paragraph example:
<text:p text:style-name="Standard">The real breakthrough in aerial mapping
during World War II was trimetrogon
<text:note text:id="ftn0" text:note-class="footnote">
<text:note-citation>1</text:note-citation>
<text:note-body>
<text:p text:style-name="Footnote">Three separate cameras took three
photographs at once, a direct downward and an oblique on each side.</text:p>
</text:note-body>
</text:note>
photography, but the camera was large and heavy, so there were problems finding
the right aircraft to carry it.
</text:p>
My question is, can XSLT process the XML as normal, but hold each of the text:note items until the end of the document text, and then emit them all at one time?
You're thinking of your logic as being driven by the order of things in the input, but in XSLT you need to be driven by the order of things in the output. When you get to the point where you want to output the footnotes, go find the footnote text wherever it might be in the input. Admittedly that doesn't always play too well with the apply-templates recursive descent processing model, which is explicitly input-driven; but nevertheless, that's the way you have to do it.
Don't think of it as "holding" the text:note items, instead simply ignore them in the main pass and then gather them at the end with a //text:note and process them there, e.g.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:text="whateveritshouldbe">
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()" />
</xsl:copy>
</xsl:template>
<!-- normal mode - replace text:note element by [reference] -->
<xsl:template match="text:note">
<xsl:value-of select="concat('[', text:note-citation, ']')" />
</xsl:template>
<xsl:template match="/">
<document>
<xsl:apply-templates select="*" />
<footnotes>
<xsl:apply-templates select="//text:note" mode="footnotes"/>
</footnotes>
</document>
</xsl:template>
<!-- special "footnotes" mode to de-activate the usual text:node template -->
<xsl:template match="#*|node()" mode="footnotes">
<xsl:copy>
<xsl:apply-templates select="#*|node()" mode="footnotes" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
You could use <xsl:apply-templates mode="..."/>. I'm not sure on the exact syntax and your use case, but maybe the example below will give you a clue on how to approach your problem.
Basic idea is to process your nodes twice. First iteration would be pretty much the same as now, and the second iteration only looks for footnotes and only outputs those. You differentiate those iteration by setting "mode" parameter.
Maybe this example will give you a clue how to approach your problem. Note that I used different tags that in your code, so the example would be simpler.
XSLT sheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="doc">
<xml>
<!-- First iteration - skip footnotes -->
<doc>
<xsl:apply-templates select="text" />
</doc>
<!-- Second iteration, extract all footnotes.
'mode' = footnotes -->
<footnotes>
<xsl:apply-templates select="text" mode="footnotes" />
</footnotes>
</xml>
</xsl:template>
<!-- Note: no mode attribute -->
<xsl:template match="text">
<text>
<xsl:for-each select="p">
<p>
<xsl:value-of select="text()" />
</p>
</xsl:for-each>
</text>
</xsl:template>
<!-- Note: mode = footnotes -->
<xsl:template match="text" mode="footnotes">
<xsl:for-each select=".//footnote">
<footnote>
<xsl:value-of select="text()" />
</footnote>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Input XML:
<?xml version="1.0" encoding="UTF-8"?>
<doc>
<text>
<p>
some text
<footnote>footnote1</footnote>
</p>
<p>
other text
<footnote>footnote2</footnote>
</p>
</text>
<text>
<p>
some text2
<footnote>footnote3</footnote>
</p>
<p>
other text2
<footnote>footnote4</footnote>
</p>
</text>
</doc>
Output XML:
<?xml version="1.0" encoding="UTF-8"?>
<xml>
<!-- Output from first iteration -->
<doc>
<text>
<p>some text</p>
<p>other text</p>
</text>
<text>
<p>some text2</p>
<p>other text2</p>
</text>
</doc>
<!-- Output from second iteration -->
<footnotes>
<footnote>footnote1</footnote>
<footnote>footnote2</footnote>
<footnote>footnote3</footnote>
<footnote>footnote4</footnote>
</footnotes>
</xml>
Source:
<Data>
<AB>
<choice>Disclose</choice>
<image>
<img alt="No Image" xlink:href="abcd:202-11587" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:title="Image" />
</image>
<link>abcd</link>
</AB>
<AB>
<choice>All</choice>
<image>
<img alt="No Image" xlink:href="abcd:202-2202" xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:title="Image" />
</image>
<link>all</link>
</AB>
</Data>
XSLT
<xsl:template match="Data">
<xsl:for-each select="AB">
<xsl:variable name="temp" select="choice"/>
<xsl:choose>
<xsl:when test="$temp='Disclose'">
<xsl:apply-templates select="image/node()"/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<xsl:template match="simple:image/xhtml:img">
<!-- I want to get the the name of the "choice" here-->
<!-- some other process-->
<!-- how to access the value of the <choice> element of that section-->
<!-- how to access <link> element of that section-->
</xsl:template>
Can any one help how to do it.
Firstly, as this may just be an oversight with your code sample, you have specified namespaces in your matching template
<xsl:template match="simple:image/xhtml:img">
However, there are no references to the "simple" namespace in your sample XML, so in this case it should just be the following
<xsl:template match="image/xhtml:img">
But in answer to you question, to get the choice element, because you currently posisioned on the img element, you can search back up the hierarchy, like so
<xsl:value-of select="../../choice" />
The '..' represents the parent element. So, you are going back up to the AB element, and getting its child choice element.
And similarly for the link element
<xsl:value-of select="../../link" />
Note, it doesn't have to be xsl:value-of here, if there were multiple link elements, you could use xsl:apply-templates
<xsl:apply-templates select="../../link" />
And, if you required only link elements that occurred after the parent image element, you could do something like this
<xsl:apply-templates select="../following-sibling::link" />
I need to display HTML-element in comments (for example)
<!-- <img src="path" width="100px" height="100px"/> -->
I use this approach
<?xml version="1.0" encoding="windows-1251"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="no" encoding="windows-1251"/>
<xsl:template match="myNode">
...
<xsl:comment><xsl:apply-templates select="image" /></xsl:comment>
...
</xsl:template>
<xsl:template match="image">
<img src="{#src}" width="{#width}px" height="{#height}px" />
</xsl:template>
</xsl:stylesheet>
As a result:
<!---->
that is the code in the element xsl:comment ignored.
How do I display an item in the comments?
It might be possible to replace
<xsl:comment><xsl:apply-templates select="image" /></xsl:comment>
with
<xsl:text disable-output-escaping="yes"><!--</xsl:text>
<xsl:apply-templates select="image" />
<xsl:text disable-output-escaping="yes">--></xsl:text>
Haven't tried though.
<xsl:comment><xsl:apply-templates select="image" /></xsl:comment>
As a result:
<!---->
that is the code in the element
xsl:comment ignored
The XSLT 1.0 Spec says:
It is an error if instantiating the
content of xsl:comment creates nodes
other than text nodes. An XSLT
processor may signal the error; if it
does not signal the error, it must
recover by ignoring the offending
nodes together with their content.
How do I display an item in the
comments?
It depends what is meant for "display": in a browser:
<-- <xsl:apply-templates select="image" /> -->
may be useful, provided the result of <xsl:apply-templates/> aboveis just simple text (not markup).
If to "display" means to provide the result as text, then DOE, if allowed by the XSLT processor, may give us the wanted result:
<--
Some text -->
Finally, if it is required that what should be inside the "comment" should be markup and it should be displayed as markup, then this is rather challenging. In this case one has to use:
<xsl:output method="text"/>
and should present every XML lexical item with its desired serialization (i.e. escaped).
This is how the XPath Visualizer constructs its output.
Here is a small transformation that demonstrates the first two approaches:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<-- Hello, World -->
<xsl:text disable-output-escaping="yes"><--</xsl:text>
Hello,world! --<xsl:text disable-output-escaping="yes">></xsl:text>
</xsl:template>
</xsl:stylesheet>
this transformation, when applied on any XML document (not used), produces:
<-- Hello, World -->
<--
Hello,world! -->
Both "comments" may be viewed as comments in a browser, while only the second is presented as comment in free text.
The third approach (most probably what you want) is illustrated below:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<-- <xsl:apply-templates select="image"/> -->
</xsl:template>
<xsl:template match="image">
<img src="<xsl:value-of select="#src"/>"
width="<xsl:value-of select="#width"/>px"
height="<xsl:value-of select="#height"/>px"/>
</xsl:template>
</xsl:stylesheet>
when this transformation is applied on the following XML document:
<image src="http://example.com/yyy.jpg" width="200" height="300"/>
the wanted result is produced:
<--
<img src="http://example.com/yyy.jpg"
width="200px"
height="300px"/>
-->
viewed in a browser as:
<--
<img src="http://example.com/yyy.jpg"
width="200px"
height="300px"/>
-->
From http://www.w3.org/TR/xslt#section-Creating-Comments:
The xsl:comment element is instantiated to create a comment node in the result tree. The content of the xsl:comment element is a template for the string-value of the comment node.
For example, this
<xsl:comment>This file is
automatically generated. Do not
edit!</xsl:comment>
would create the comment
<!--This file is automatically
generated. Do not edit!-->
It is an error if instantiating the
content of xsl:comment creates nodes
other than text nodes. An XSLT
processor may signal the error; if it
does not signal the error, it must
recover by ignoring the offending
nodes together with their content.
It is an error if the result of
instantiating the content of the
xsl:comment contains the string -- or
ends with -. An XSLT processor may
signal the error; if it does not
signal the error, it must recover by
inserting a space after any occurrence
of - that is followed by another - or
that ends the comment.
So, in order to do what you want you need to use DOE mechanism.
As example, this stylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl">
<xsl:output method="html" indent="no" encoding="windows-1251"/>
<xsl:template match="img">
<img src="{.}"/>
</xsl:template>
<xsl:template match="root">
<xsl:variable name="vResult">
<xsl:apply-templates/>
</xsl:variable>
<html>
<xsl:copy-of select="$vResult"/>
<xsl:comment>
<xsl:apply-templates select="msxsl:node-set($vResult)"
mode="encode"/>
</xsl:comment>
</html>
</xsl:template>
<xsl:template match="*" mode="encode">
<xsl:value-of select="concat('<',name())"
disable-output-escaping="yes"/>
<xsl:apply-templates select="#*" mode="encode"/>
<xsl:text>></xsl:text>
<xsl:apply-templates mode="encode"/>
<xsl:value-of select="concat('<',name(),'>')"
disable-output-escaping="yes"/>
</xsl:template>
<xsl:template match="*[not(node())]" mode="encode">
<xsl:value-of select="concat('<',name())"
disable-output-escaping="yes"/>
<xsl:apply-templates select="#*" mode="encode"/>
<xsl:text>/></xsl:text>
</xsl:template>
<xsl:template match="#*" mode="encode">
<xsl:value-of select="concat(' ',name(),'="',.,'"')"/>
</xsl:template>
</xsl:stylesheet>
With this input:
<root>
<img>http://example.org/image1.jpg</img>
<img>http://example.org/image2.jpg</img>
<img>http://example.org/image3.jpg</img>
</root>
Output:
<html>
<img src="http://example.org/image1.jpg">
<img src="http://example.org/image2.jpg">
<img src="http://example.org/image3.jpg">
<!--<img src="http://example.org/image1.jpg"/>
<img src="http://example.org/image2.jpg"/>
<img src="http://example.org/image3.jpg"/>-->
</html>
Note: node-set extension function for two pass transformation. disable-output-escaping attribute for xsl:value-of instruction.
As said before by Dimitri you can't use the xsl:comment instruction.
If your purpose is simply to comment a fragment of tree, the simplest way is to put the comments markers as text (unescaped) like this :
<xsl:text disable-output-escaping="yes"><!--</xsl:text><xsl:apply-templates select="image" /><xsl:text disable-output-escaping="yes">--></xsl:text>
instead of :
<xsl:comment><xsl:apply-templates select="image" /></xsl:comment>
and you will obtain exactly this
<!-- <img src="path" width="100px" height="100px"/> -->
used with msxml and saxon
I'm trying to conditionally display the content of HTML page depending if a document being generated for a recognised company or not.
However, the transformation doesn't work and I can't understand why :( I use MSXML3.0 as transformer and oXygen as IDE, which gives the errors I presented below.
What I do is to construct a long string of all recognised companies (default and extra if any). I then split them into <token> elements that are stored in the $companiesKnownList variable. To determine if a company is in that list I count how many times it occurs:
count($companiesKnownList/token[normalize-space(.) = $productName]) < 1
If it's less than 1, then the company doesn't appear in the $companiesKnownList variable and therefore is not recognized. Otherwise, if it appears in the $companiesKnownList variable once or more times it is a recognized company. Nevertheless, this is where it breaks and displays the following error:
Description: Code: 0x80004005
Description: The XSL processor stack has overflowed - probable cause is infinite template recursion.
Description: The transformer process ended with code: 1
I've noticed that if my XML has got a recognised company, ex #ProductName="ski" then transformation fails with stack overflow. If I have an unrecognized company, ex #ProductName="bla" the transformation works and text that it isn't a recognized company is displayed.
I don't understand what's going wrong with valid companies. I would be more than grateful if you could help me out. I have been staring at it for a day now...without any progress :S
Thanks!
Here is my stylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:str="http://exslt.org/strings"
extension-element-prefixes="msxsl str"
version="1.0">
<!-- Taken from http://www.exslt.org/str/functions/tokenize/index.html -->
<xsl:import href="str.tokenize.template.xsl"/>
<!-- normalize and lowcase product name -->
<xsl:variable name="productName"
select="normalize-space(translate(/Doc/#ProductName, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'))"/>
<!-- default recognised companies for all docs -->
<xsl:variable name="defaultRecognisedCompanies" select="'ski, holiday, summer trips'"/>
<!-- Determine what companies to generate a doc for -->
<xsl:variable name="companiesKnownListRaw">
<xsl:call-template name="recognisedCompanies"/>
</xsl:variable>
<xsl:variable name="companiesKnownList" select="msxsl:node-set($companiesKnownListRaw)"/>
<!-- Lists recognised companies for a document to be generated for -->
<xsl:template name="recognisedCompanies">
<xsl:call-template name="recognisedCompaniesListForDocument"/>
</xsl:template>
<xsl:template name="recognisedCompaniesListForDocument">
<xsl:param name="defaultCompanies" select="$defaultRecognisedCompanies"/>
<xsl:param name="isUseDefaultsCompanies" select="true()"/>
<xsl:param name="extraCompanies" select="''"/>
<xsl:variable name="allCompaniesRaw">
<xsl:call-template name="str:tokenize">
<xsl:with-param name="string">
<xsl:choose>
<!-- keep default companies -->
<xsl:when test="$isUseDefaultsCompanies = 'true'">
<xsl:value-of select="concat($defaultCompanies, ', ', $extraCompanies)"/>
</xsl:when>
<!-- discard default companies -->
<xsl:otherwise>
<xsl:value-of select="$extraCompanies"/>
</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
<xsl:with-param name="delimiters" select="','" />
</xsl:call-template>
</xsl:variable>
<!-- Normalize token's value and discard empty values -->
<xsl:for-each select="msxsl:node-set($allCompaniesRaw)/token">
<xsl:if test="normalize-space(.) != ''">
<token>
<xsl:value-of select="normalize-space(.)"/>
</token>
</xsl:if>
</xsl:for-each>
</xsl:template>
<!-- Construct HTML doc. Display appropriate message for a company if it's recognized or not -->
<xsl:output method="html" doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"
doctype-system="http://www.w3.org/TR/html4/loose.dtd" encoding="UTF-8" indent="yes"/>
<xsl:template match="/Doc">
<html>
<xsl:choose>
<!-- Not recognised company -->
<!-- There is something wrong with the count conditions, and I don't understand what :( -->
<xsl:when test="count($companiesKnownList/token[normalize-space(.) = $productName]) < 1">
<body>
<div align="center">
This type of company is NOT recognised for this document.
</div>
</body>
</xsl:when>
<!-- Recognised company -->
<xsl:otherwise>
<body>
<div align="center">
This type of company is recognised for this document.
</div>
</body>
</xsl:otherwise>
</xsl:choose>
</html>
</xsl:template>
</xsl:stylesheet>
XML is something simple like:
In this example, ski is recognized company, but transformation fails.
<?xml version="1.0" encoding="UTF-8"?>
<Doc ProductName="ski" />
In this example, bla is not a recognized company and transformation succeeds with displaying text: "This type of company is NOT recognised for this document."
<?xml version="1.0" encoding="UTF-8"?>
<Doc ProductName="bla" />
You need to add the implementation of your named template str:tokenize. Check Jeni Tennison implementation at http://www.exslt.org/str/functions/tokenize/str.tokenize.template.xsl
Then, add this as stylesheet top element, with correct href:
<xsl:include href="str.tokenize.template.xsl"/>
With that changes (and closing your last template) with this input:
<Doc ProductName="ski" />
Ouput:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<body>
<div align="center">
This type of company is recognised for this document.
</div>
</body>
</html>
MSXML (any version) does not support EXSLT -- and the XSLT processor produces an error message.
Could you, please, correct the question so that only true information is present?