Umbraco - error when using umbraco.library:NiceUrl(...) - xslt

<!-- Get the url of a node based on a list of positions (starting point = language root) -->
<xsl:template name="getUrl">
<xsl:param name="id" />
<xsl:param name="positions" />
<xsl:param name="i" select="0" />
<xsl:param name="max" />
<!-- Return the url -->
<xsl:if test="$i = $max">
<xsl:value-of select="umbraco.library:NiceUrl($id)" />
</xsl:if>
<xsl:if test="$i < $max">
<xsl:call-template name="getUrl">
<xsl:with-param name="id">
<!-- Define the id of the next item in the tree structure -->
<xsl:for-each select="//* [#id = $id]/child::* [#isDoc]">
<xsl:if test="position() = number(umbraco.library:Split($positions, ',')/value[number($i)])">
<xsl:value-of select="#id" />
</xsl:if>
</xsl:for-each>
</xsl:with-param>
<xsl:with-param name="positions">
<xsl:value-of select="$positions"/>
</xsl:with-param>
<xsl:with-param name="i">
<xsl:value-of select="$i + 1"/>
</xsl:with-param>
<xsl:with-param name="max">
<xsl:value-of select="$max"/>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>
I am using a macro with XLST file.
When using this code, I get an error (Value was either too large or too small for an Int32).
The error occurs on these two lines:
<xsl:value-of select="umbraco.library:NiceUrl($id)" />
<xsl:call-template name="getUrl">
Can someone tell me what I'm doing wrong here, becuase this XSLT file works fine on every page, except for new pages I create.

Ok I found a solution: I added an extra check to this part:
<!-- Return the url -->
<xsl:if test="$i = $max">
<xsl:if test="$id != '' ">
<xsl:value-of select="umbraco.library:NiceUrl($id)" />
</xsl:if>
</xsl:if>
this fixed my problem.

Related

How can I split a string in xslt?

I want to split a string at the double quotation. Input string is as follow,
<S>Test Example "{test1}" is "{equal}" "{test2}"</S>
The xslt code that I'm using is,
<xsl:template name="SplitString">
<xsl:param name="text" select="''" />
<xsl:variable name="tag" select="substring-before(substring-after($text, '"'), '"')" />
<xsl:variable name="Remainder" select="substring-after($text, '"')" />
<xsl:choose>
<xsl:when test="$tag != ''">
<xsl:element name = "NP">
<xsl:value-of select = "$tag"/>
</xsl:element>
<!--recursive loop -->
<xsl:call-template name="SplitString">
<xsl:with-param name="text" select="$Remainder" />
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:template>
The output that I'm getting is as follow,
<NP>{test}</NP>
<NP>is</NP>
<NP>{equal}</NP>
<NP> </NP>
<NP>{test2}</NP>
How can avoid the creation of empty element?
the desired output would be,
<NP>{test}</NP>
<NP>is</NP>
<NP>{equal}</NP>
<NP>{test2}</NP>
Just add a condition:
<xsl:if test="normalize-space($tag)">
<xsl:element name = "NP">
<xsl:value-of select = "$tag"/>
</xsl:element>
</xsl:if>

xslt case change transformation is removing the <br/ > tag from xml

I am doing a upper case to first character content in the xml data using the delimiters (space and hyphen) and am able to get the output correctly however this template is removing the break line tag in the table td area of xml. The output should be an xml.
eg:<text>
<table>
<tbody>
<tr>
<td>test<br />testing<br />tested</td>
</tr>
I see the code transforming as continous line without break tag in the output as below:I need to see the same br tag in xml output as in input xml however by capitalizing first letter of the word.
<text>
<table>
<tbody>
<tr>
<td>Testtestingtested</td>
</tr>
I am expecting to preserve and display the same break line tag to be in output xml even after the xslt tranformation so that the output will look correct instead of continous line
I am using the below xslt transformation:
<?xml version="1.0" encoding="utf-8"?>
<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"
xmlns:n1="urn:hl7-org:v3" xmlns:n2="urn:hl7-org:sdtc">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match='n1:ClinicalDocument/n1:component/n1:structuredBody/n1:component/n1:section/n1:text/n1:table/n1:tbody/n1:tr'>
<xsl:copy>
<xsl:apply-templates select='n1:td'/>
</xsl:copy>
</xsl:template>
<xsl:template match="n1:td">
<xsl:copy>
<xsl:if test="./#ID">
<xsl:attribute name="ID" xml:space="default">
<xsl:value-of select="./#ID"/>
</xsl:attribute>
</xsl:if>
<xsl:call-template name="capitalize">
<xsl:with-param name="text" select="string(.)"/>
</xsl:call-template>
</xsl:copy>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template name="capitalize">
<xsl:param name="text" />
<xsl:param name="delimiter" select = "' '"/>
​
<xsl:variable name="upper-case" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:variable name="lower-case" select="'abcdefghijklmnopqrstuvwxyz'"/>
<xsl:variable name="word" select="substring-before(concat($text, $delimiter), $delimiter)" />
<xsl:choose>
<xsl:when test="$delimiter=' '">
<!-- tokenize word by 2nd delimiter -->
<xsl:call-template name="capitalize">
<xsl:with-param name="text" select="$word"/>
<xsl:with-param name="delimiter" select="'-'"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!-- capitalize word -->
<xsl:value-of select="translate(substring($word, 1, 1), $lower-case, $upper-case) " />
<xsl:value-of select="translate(substring($word, 2), $upper-case, $lower-case)" />
</xsl:otherwise>
</xsl:choose>
<xsl:if test="contains($text, $delimiter)">
<xsl:value-of select="$delimiter"/>
<!-- recursive call -->
<xsl:call-template name="capitalize">
<xsl:with-param name="text" select="substring-after($text, $delimiter)" />
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Can anyone check and answer?
UPDATE: Both XSLT 1.0 and 2.0 solutions
All solutions preserve your line breaks and also work if you have inline markup of the text content.
First I make the lc and uc parameters global for more minified templates:
<xsl:param name="lc" select="'abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ'"/>
<xsl:param name="uc" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ'"/>
XSLT 1.0 or 2.0: You need to rewrite your first template to this regardless of the following XSLT solutions:
<xsl:template match="n1:td">
<xsl:copy>
<xsl:if test="./#ID">
<xsl:attribute name="ID" xml:space="default">
<xsl:value-of select="./#ID"/>
</xsl:attribute>
</xsl:if>
<xsl:apply-templates select="node()" />
</xsl:copy>
<xsl:text>
</xsl:text>
</xsl:template>
XSLT 1.0
With XSLT 1.0 you need to combine a match template with a name template.
Match template: n1:td//text()
With this match template it becomes precisely what you request, make initial letter uppercase, and make letters following space and - uppercase:
<xsl:template match="n1:td//text()" >
<xsl:param name="text" select="." />
<xsl:param name="currentTextBlock" select="ancestor::n1:td[1]" />
<xsl:param name="isFirstTextNode">
<xsl:choose>
<xsl:when test="preceding::text()[ancestor::n1:td[generate-id(.) = generate-id($currentTextBlock)]]">false</xsl:when>
<xsl:otherwise>true</xsl:otherwise>
</xsl:choose>
</xsl:param>
<xsl:choose>
<xsl:when test="$isFirstTextNode = 'true'">
<xsl:value-of select="translate(substring($text, 1, 1), $lc, $uc)" />
<xsl:call-template name="capitalize">
<xsl:with-param name="text" select="$text" />
<xsl:with-param name="remainingText" select="substring($text,2)" />
<xsl:with-param name="index" select="2" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="capitalize">
<xsl:with-param name="text" select="$text" />
<xsl:with-param name="remainingText" select="$text" />
<xsl:with-param name="index" select="1" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
If you also want initial letter for each text node to be uppercase without adding space or hyphen, you can use this:
<xsl:template match="n1:td//text()" >
<xsl:param name="text" select="." />
<xsl:value-of select="translate(substring($text, 1, 1), $lc, $uc)" />
<xsl:call-template name="capitalize">
<xsl:with-param name="text" select="$text" />
<xsl:with-param name="remainingText" select="substring($text,2)" />
<xsl:with-param name="index" select="2" />
</xsl:call-template>
</xsl:template>
Name template: capitalize
This name template is can be used "as is" with both of the above match templates.
<xsl:template name="capitalize">
<xsl:param name="text" select="''" />
<xsl:param name="remainingText" select="''" />
<xsl:param name="index" select="1" />
<xsl:if test="$remainingText != ''">
<xsl:variable name="currentChar" select="substring($remainingText, 1, 1)" />
<xsl:choose>
<xsl:when test="$index = 1">
<xsl:value-of select="translate($currentChar, $uc, $lc)" />
</xsl:when>
<xsl:otherwise>
<xsl:variable name="previousChar" select="substring($text, $index - 1, 1)" />
<xsl:choose>
<xsl:when test="$previousChar = ' ' or $previousChar = '-'">
<xsl:value-of select="translate($currentChar, $lc, $uc)" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="translate($currentChar, $uc, $lc)" />
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="capitalize">
<xsl:with-param name="text" select="$text" />
<xsl:with-param name="remainingText" select="substring($remainingText, 2)" />
<xsl:with-param name="index" select="$index + 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
XSLT 2.0 (same as before):
This solution does precisely what you request, make initial letter uppercase, and make letters following space and - uppercase:
<xsl:template match="n1:td//text()" >
<xsl:param name="text" select="." />
<xsl:param name="currentTextBlock" select="ancestor::n1:td[1]" />
<xsl:param name="isFirstTextNode">
<xsl:choose>
<xsl:when test="preceding::text()[ancestor::n1:td[generate-id(.) = generate-id($currentTextBlock)]]">false</xsl:when>
<xsl:otherwise>true</xsl:otherwise>
</xsl:choose>
</xsl:param>
<xsl:for-each select="tokenize(replace(replace($text,'(.)','$1\\n'),'\\n$',''),'\\n')">
<xsl:variable name="pos" select="position()" />
<xsl:variable name="char" select="." />
<xsl:choose>
<xsl:when test="$isFirstTextNode = 'true' and $pos = 1">
<xsl:value-of select="translate($char, $lc, $uc) " />
</xsl:when>
<xsl:when test="substring($text, $pos - 1, 1) = ' ' or substring($text, $pos - 1, 1) = '-'">
<xsl:value-of select="translate($char, $lc, $uc) " />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="translate($char, $uc, $lc)" />
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
If you also want initial letter for each text node to be uppercase without adding space or hyphen, you can use this:
<xsl:template match="n1:td//text()" >
<xsl:param name="text" select="." />
<xsl:param name="currentTextBlock" select="ancestor::n1:td[1]" />
<xsl:for-each select="tokenize(replace(replace($text,'(.)','$1\\n'),'\\n$',''),'\\n')">
<xsl:variable name="pos" select="position()" />
<xsl:variable name="char" select="." />
<xsl:choose>
<xsl:when test="$pos = 1">
<xsl:value-of select="translate($char, $lc, $uc) " />
</xsl:when>
<xsl:when test="substring($text, $pos - 1, 1) = ' ' or substring($text, $pos - 1, 1) = '-'">
<xsl:value-of select="translate($char, $lc, $uc) " />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="translate($char, $uc, $lc)" />
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
The problem is your call on string(.), which takes the string value of the element: this strips out all markup.
You should be doing a recursive descent using xsl:apply-templates at each level to apply template rules to child nodes, all the way down to the leaf text nodes, and then your template rule for text nodes should be doing the case conversion.
Except that your capitalize logic seems to be trying to do something smart (I'm not sure what) which means it might need to look at something larger than a single text node. You might need a different rule for the first text node and for subsequent text nodes: it's hard to be sure without seeing a spec.
Another approach to this kind of problem is to do multiple passes: the first pass replaces the <br/> elements with some textual marker, e.g. "§br§", in the next pass you process the text as a string, and then finally you convert the markers back to element nodes.
With XSLT 3.0 you could do the first pass using fn:serialize() and the final pass using fn:parse-xml-fragment(); the "textual marker" would then be the actual lexical markup "<br/>" as a string of five characters. (But take care not to capitalise it!)

Attaching parent attributes to child nodes with multiple children

this is linked from Attaching ancestor attributes to child nodes
I'm extracting names from a large xml dataset, I need to extract displayname, and the other name types (currently I am only picking out Synonyms and SystematicNames). Right now with the help of an awesome person I've gotten so far, but it only extracts the first of each type...
Sample XML
<Chemical id="0000103902" displayFormula="C8-H9-N-O2" displayName="Acetaminophen [USP:JAN]">
<NameList>
<DescriptorName>Acetaminophen<SourceList><Source>MeSH</Source></SourceList></DescriptorName>
<NameOfSubstance>Acetaminophen<SourceList><Source>HSDB</Source><Source>MeSH</Source></SourceList></NameOfSubstance>
<NameOfSubstance>Acetaminophen [USP:JAN]<SourceList><Source>NLM</Source></SourceList></NameOfSubstance>
<MixtureName>Actifed Plus<SourceList><Source>MeSH</Source></SourceList></MixtureName>
<MixtureName>Jin Gang<SourceList><Source>NLM</Source></SourceList></MixtureName>
<MixtureName>Talacen<SourceList><Source>NLM</Source></SourceList></MixtureName>
<SystematicName>Acetamide, N-(4-hydroxyphenyl)-<SourceList><Source>EPA SRS</Source><Source>MeSH</Source><Source>TSCAINV</Source></SourceList></SystematicName>
<SystematicName>Acetaminophen<SourceList><Source>CCRIS</Source></SourceList></SystematicName>
<SystematicName>Acetanilide, 4'-hydroxy-<SourceList><Source>RTECS</Source></SourceList></SystematicName>
<SystematicName>Paracetamol<SourceList><Source>ECHA</Source><Source>EINECS</Source></SourceList></SystematicName>
<Synonyms>4-13-00-01091 (Beilstein Handbook Reference)<SourceList><Source>RTECS</Source></SourceList></Synonyms>
<Synonyms>Abensanil<SourceList><Source>HSDB</Source><Source>RTECS</Source></SourceList></Synonyms>
<Synonyms>Acetagesic<SourceList><Source>HSDB</Source><Source>RTECS</Source></SourceList></Synonyms>
<Synonyms>Acetamide, N-(p-hydroxyphenyl)-<SourceList><Source>RTECS</Source></SourceList></Synonyms>
</NameList>
</Chemical>
Current code
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:variable name="FS">
<!-- Field seperator -->
<xsl:text>;</xsl:text>
</xsl:variable>
<xsl:variable name="LT">
<!-- Line terminator -->
<xsl:text>
</xsl:text>
</xsl:variable>
<xsl:strip-space elements="*" />
<xsl:template match="/">
<xsl:for-each select="//Chemical[#displayName != '' and #displayName != 'INDEX NAME NOT YET ASSIGNED']">
<xsl:call-template name="printValues">
<xsl:with-param name="val1" select="#id" />
<xsl:with-param name="val2" select="#displayName" />
</xsl:call-template>
<xsl:if test="normalize-space(NameList/SystematicName/text()) != ''">
<xsl:call-template name="printValues">
<xsl:with-param name="val1" select="#id" />
<xsl:with-param name="val2" select="normalize-space(NameList/SystematicName/text())" />
</xsl:call-template>
</xsl:if>
<xsl:if test="normalize-space(NameList/Synonyms/text()) != ''">
<xsl:call-template name="printValues">
<xsl:with-param name="val1" select="#id" />
<xsl:with-param name="val2" select="normalize-space(NameList/Synonyms/text())" />
</xsl:call-template>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template name="printValues">
<xsl:param name="val1" />
<xsl:param name="val2" />
<!-- constants -->
<xsl:variable name="url" select="'https://chem.nlm.nih.gov/chemidplus/sid/startswith/'" />
<xsl:variable name="src" select="'nlm'" />
<xsl:text>"</xsl:text>
<xsl:call-template name="escapeQuote">
<xsl:with-param name="paramStr" select="$val2" />
</xsl:call-template>
<xsl:text>"</xsl:text>
<xsl:text>,</xsl:text>
<xsl:text>"</xsl:text>
<xsl:value-of select="concat($url, $val1)" />
<xsl:text>"</xsl:text>
<xsl:text>,</xsl:text>
<xsl:text>"</xsl:text>
<xsl:value-of select="$src" />
<xsl:text>"</xsl:text>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template name="escapeQuote">
<xsl:param name="paramStr" />
<xsl:if test="string-length($paramStr) > 0">
<xsl:value-of select="substring-before(concat($paramStr, '"'), '"')" />
<xsl:if test="contains($paramStr, '"')">
<xsl:text>\"</xsl:text>
<xsl:call-template name="escapeQuote">
<xsl:with-param name="paramStr" select="substring-after($paramStr, '"')" />
</xsl:call-template>
</xsl:if>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
However this only gives:-
"Acetaminophen [USP:JAN]","https://chem.nlm.nih.gov/chemidplus/sid/startswith/0000103902","nlm"
"Acetamide, N-(4-hydroxyphenyl)-","https://chem.nlm.nih.gov/chemidplus/sid/startswith/0000103902","nlm"
"4-13-00-01091 (Beilstein Handbook Reference)","https://chem.nlm.nih.gov/chemidplus/sid/startswith/0000103902","nlm"
How do I go about extracting all the children in the same manner?
Printing of the text values in the <SystematicName> and <Synonyms> nodes can be achieved by adding <xsl:for-each> loop for those elements. The <xsl:if> condition can also be handled in the <xsl:for-each> selection.
Please modify the <xsl:template match="/"> as shown below.
<xsl:template match="Chemical[#displayName != '' and #displayName != 'INDEX NAME NOT YET ASSIGNED']">
<xsl:variable name="idValue" select="#id" />
<xsl:call-template name="printValues">
<xsl:with-param name="val1" select="$idValue" />
<xsl:with-param name="val2" select="#displayName" />
</xsl:call-template>
<xsl:for-each select="NameList/SystematicName[text() != '']">
<xsl:call-template name="printValues">
<xsl:with-param name="val1" select="$idValue" />
<xsl:with-param name="val2" select="normalize-space(text())" />
</xsl:call-template>
</xsl:for-each>
<xsl:for-each select="NameList/Synonyms[text() != '']">
<xsl:call-template name="printValues">
<xsl:with-param name="val1" select="$idValue" />
<xsl:with-param name="val2" select="normalize-space(text())" />
</xsl:call-template>
</xsl:for-each>
</xsl:template>
Output
"Acetaminophen [USP:JAN]","https://chem.nlm.nih.gov/chemidplus/sid/startswith/0000103902","nlm"
"Acetamide, N-(4-hydroxyphenyl)-","https://chem.nlm.nih.gov/chemidplus/sid/startswith/0000103902","nlm"
"Acetaminophen","https://chem.nlm.nih.gov/chemidplus/sid/startswith/0000103902","nlm"
"Acetanilide, 4'-hydroxy-","https://chem.nlm.nih.gov/chemidplus/sid/startswith/0000103902","nlm"
"Paracetamol","https://chem.nlm.nih.gov/chemidplus/sid/startswith/0000103902","nlm"
"4-13-00-01091 (Beilstein Handbook Reference)","https://chem.nlm.nih.gov/chemidplus/sid/startswith/0000103902","nlm"
"Abensanil","https://chem.nlm.nih.gov/chemidplus/sid/startswith/0000103902","nlm"
"Acetagesic","https://chem.nlm.nih.gov/chemidplus/sid/startswith/0000103902","nlm"
"Acetamide, N-(p-hydroxyphenyl)-","https://chem.nlm.nih.gov/chemidplus/sid/startswith/0000103902","nlm"

Removing &#160 with XSLT

I hope someone can help me with this...
I am using SharePoint 2013 and trying to render a CQWP to show the latest blog posts. The problem I have is that when displaying the 'content' from the post I get '&#160' added and quotes are shown as '&quot'. I have managed to strip the HTML mark up but can't seem to get rid of these.
My code is as follows - any help would be much appreciated, thanks.
Generate Summary and Remove HTML
<!-- Generate Summary -->
<xsl:template name="GenerateSummary">
<xsl:param name="Content"/>
<xsl:param name="Length"/>
<xsl:param name="Suffix"/>
<xsl:variable name="cleanContent">
<xsl:call-template name="RemoveHtml">
<xsl:with-param name="String" select="$Content"/>
</xsl:call-template>
</xsl:variable>
<xsl:call-template name="SubstringBeforeLast">
<xsl:with-param name="String"
select="substring($cleanContent, 1, $Length)"/>
<xsl:with-param name="Char" select="' '"/>
</xsl:call-template>
<xsl:if test="string-length($cleanContent) > $Length">
<xsl:value-of select="$Suffix"
disable-output-escaping="yes"/>
</xsl:if>
</xsl:template>
<!-- RemoveHTML -->
<xsl:template name="RemoveHtml">
<xsl:param name="String"/>
<xsl:choose>
<xsl:when test="contains($String, '<')">
<xsl:value-of select="substring-before($String, '<')"/>
<xsl:call-template name="RemoveHtml">
<xsl:with-param name="String"
select="substring-after($String, '>')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$String"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="SubstringBeforeLast">
<xsl:param name="String" />
<xsl:param name="Char" />
<xsl:param name="subsequent"/>
<xsl:choose>
<xsl:when test="contains($String, $Char)">
<xsl:if test="$subsequent = 1">
<xsl:value-of select="$Char"/>
</xsl:if>
<xsl:value-of select="substring-before($String, $Char)"/>
<xsl:call-template name="SubstringBeforeLast">
<xsl:with-param name="String"
select="substring-after($String, $Char)" />
<xsl:with-param name="Char" select="$Char" />
<xsl:with-param name="subsequent" select="1"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:if test="$subsequent != 1">
<xsl:value-of select="$String"/>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Calling it here
<div class="fcItemContent">
<xsl:call-template name="GenerateSummary">
<xsl:with-param name="Content" select="#content" />
<xsl:with-param name="Length" select="200" />
<xsl:with-param name="Suffix" select="'...'"/>
</xsl:call-template>
</div>
Use function of XSLT
normalize-space()
**<xsl:value-of select="normalize-space()"/>**
White space is normalized by stripping leading and trailing white space and replacing sequences of white space characters with a single space. If the argument is omitted, the string-value of the context node is normalized and returned.
referred Link :
Remove Space using XSLT

Umbraco Navigation using XSLT macro - issue with childless nodes

I have implemented the superfish navigation menu into an umbraco installation. Superfish simply takes a UL element and turns it into a hierarchical menu that shows child items when you hover over the parent (you remember when they were cool back in 1999 right?).
I cannot figure out why, on certain pages (usually ones without children), the menu does not show child items for any page. My exposure to XSLT is minimal, so i must be overlooking some logic.
You can see the actual site here Hover over 'personal training' to see the menu work, now click on 'weight management' and hey-presto the magic stops happening.
The XSLT that creates the UL structure is below, and the HTML page source tells me that its simply not generating any LI elements for child pages when the issue occurs.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp " "> ]>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxml="urn:schemas-microsoft-com:xslt"
xmlns:umbraco.library="urn:umbraco.library"
exclude-result-prefixes="msxml umbraco.library">
<xsl:output method="html" omit-xml-declaration="yes"/>
<xsl:param name="currentPage" />
<!--This sets the level that the nav starts at and tells us if we should recurse through child elements-->
<xsl:variable name="startDepth" select="/macro/startingLevel" />
<xsl:variable name="recurse" select="/macro/recurse" />
<xsl:variable name="selectBranches" select="/macro/selectBranches"></xsl:variable>
<xsl:variable name="maxMenuDepth" select="/macro/maxMenuDepth"></xsl:variable>
<xsl:variable name="forceNode" select="/macro/forceNode"></xsl:variable>
<xsl:variable name="walkChildren" select="/macro/expandChildren"></xsl:variable>
<xsl:variable name="forceHome" select="/macro/forceHome"></xsl:variable>
<xsl:variable name="securityTrimming" select="/macro/securityTrimming"></xsl:variable>
<!--Alternate page title variable in here-->
<!--Styles for the navigation-->
<xsl:variable name="ulBaseClass" select="/macro/ulBaseClass"></xsl:variable>
<xsl:variable name="branchClass" select="/macro/branchClass"></xsl:variable>
<xsl:variable name="selectedClass" select="/macro/selectedClass"></xsl:variable>
<xsl:variable name="startLevel">
<xsl:choose>
<xsl:when test="$startDepth >= 0">
<xsl:value-of select="$startDepth"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$currentPage/#level"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!--This calls first iteration of the navigation, sending the first node at the correct depth found in the ancestors of the current page-->
<xsl:template match="/">
<xsl:choose>
<xsl:when test="$forceNode">
<xsl:variable name="currentNode" select="umbraco.library:GetXmlNodeById($forceNode)"></xsl:variable>
<xsl:call-template name="nodeIterator">
<xsl:with-param name="parentNode" select="$currentNode/ancestor-or-self::*[#isDoc][#level=$startLevel]
[
string(umbracoNaviHide) != '1'
and ($securityTrimming != '1'
or umbraco.library:IsProtected(#id, #path) = false()
or umbraco.library:HasAccess(#id, #path) = true())
]" />
<xsl:with-param name="pseudoCurrentPage" select="$currentNode" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="currentNode" select="$currentPage"></xsl:variable>
<xsl:call-template name="nodeIterator">
<xsl:with-param name="parentNode" select="$currentNode/ancestor-or-self::*[#isDoc][#level=$startLevel]
[
string(umbracoNaviHide) != '1'
and ($securityTrimming != '1'
or umbraco.library:IsProtected(#id, #path) = false()
or umbraco.library:HasAccess(#id, #path) = true())
]" />
<xsl:with-param name="pseudoCurrentPage" select="$currentNode" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="nodeIterator">
<xsl:param name="parentNode" />
<xsl:param name="pseudoCurrentPage" />
<!-- do not show info doc node types-->
<xsl:variable name="calculatedMenuDepth" select="($parentNode/#level - $startLevel)+1" />
<xsl:if test="$parentNode/*[#isDoc] or ($calculatedMenuDepth = 1 and $forceHome)">
<ul>
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="$calculatedMenuDepth = 1">
<xsl:value-of select="$ulBaseClass" />
</xsl:when>
<!--<xsl:when test="$calculatedMenuDepth = 1">
<xsl:value-of select="concat($ulBaseClass, ' lv', $calculatedMenuDepth)" />
</xsl:when>
<xsl:when test="$calculatedMenuDepth > 1">
<xsl:value-of select="concat('lv', $calculatedMenuDepth)" />
</xsl:when>-->
</xsl:choose>
</xsl:attribute>
<xsl:if test="$forceHome = 1 and $calculatedMenuDepth = 1">
<!-- Create the class for the li element-->
<li>
<xsl:variable name="isHomeSelected">
<xsl:choose>
<xsl:when test="$currentPage/ancestor-or-self::*[#isDoc][#level=1]/#id = $currentPage/#id">1</xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:call-template name="cssClassConstructor">
<xsl:with-param name="isSelected" select="$isHomeSelected" />
<xsl:with-param name="isSelectedBranch" select="0" />
<xsl:with-param name="hasChildren" select="1" />
<xsl:with-param name="selectedClass" select="$selectedClass" />
<xsl:with-param name="branchClass" select="$branchClass" />
</xsl:call-template>
<a href="{umbraco.library:NiceUrl($currentPage/ancestor-or-self::*[#isDoc][#level=1]/#id)}">
<xsl:call-template name="cssClassConstructor">
<xsl:with-param name="isSelected" select="$isHomeSelected" />
<xsl:with-param name="isSelectedBranch" select="0" />
<xsl:with-param name="hasChildren" select="0" />
<xsl:with-param name="selectedClass" select="$selectedClass" />
<xsl:with-param name="branchClass" select="$branchClass" />
</xsl:call-template>
<!--set the innerText for the a element-->
<xsl:value-of select="$currentPage/ancestor-or-self::*[#isDoc][#level=1]/text()"/>
<xsl:if test="string($currentPage/ancestor-or-self::*[#isDoc][#level=1]/text()) = ''">
<xsl:value-of select="$currentPage/ancestor-or-self::*[#isDoc][#level=1]/#nodeName"/>
</xsl:if>
</a>
</li>
</xsl:if>
<!--End force home-->
<!--for each node in the parent node that is not hidden by Umbraco-->
<xsl:for-each select="$parentNode/*[#isDoc][
string(umbracoNaviHide) != '1'
and ($securityTrimming != '1'
or umbraco.library:IsProtected(#id, #path) = false()
or umbraco.library:HasAccess(#id, #path) = true())
]">
<!--Set the current node id i.e. the node we have looped to not the current page-->
<xsl:variable name="currentNodeID" select="#id" />
<!--Is the node a branch? i.e. are there children and is it in the colletion of ancestor nodes -->
<xsl:variable name="isBranch">
<xsl:choose>
<xsl:when test="$currentPage/ancestor-or-self::*[#isDoc][#id = $currentNodeID]/child::*[#isDoc]">1</xsl:when>
</xsl:choose>
</xsl:variable>
<!--Is the node selected? i.e. is it the same as the currentPage node-->
<xsl:variable name="isSelected">
<xsl:choose>
<xsl:when test="$currentPage/#id = $currentNodeID">1</xsl:when>
<!-- parent selected -->
<xsl:when test="$pseudoCurrentPage/#id = $currentNodeID">1</xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:variable name="isSelectedBranch">
<xsl:choose>
<xsl:when test="$isBranch = 1 and $selectBranches = 1">1</xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:variable name="hasChildren">
<xsl:choose>
<xsl:when test="./*[#isDoc]">1</xsl:when>
</xsl:choose>
</xsl:variable>
<li>
<!-- Create the class attribute for the element-->
<xsl:call-template name="cssClassConstructor">
<xsl:with-param name="isSelected" select="$isSelected" />
<xsl:with-param name="isSelectedBranch" select="$isSelectedBranch" />
<xsl:with-param name="hasChildren" select="$hasChildren" />
<xsl:with-param name="selectedClass" select="$selectedClass" />
<xsl:with-param name="branchClass" select="$branchClass" />
</xsl:call-template>
<a href="{umbraco.library:NiceUrl(#id)}">
<xsl:call-template name="cssClassConstructor">
<xsl:with-param name="isSelected" select="$isSelected" />
<xsl:with-param name="isSelectedBranch" select="$isSelectedBranch" />
<xsl:with-param name="hasChildren" select="0" />
<xsl:with-param name="selectedClass" select="$selectedClass" />
<xsl:with-param name="branchClass" select="$branchClass" />
</xsl:call-template>
<!--set the innerText for the a element-->
<xsl:value-of select="./pageTitle/text()"/>
<xsl:if test="string(./pageTitle/text()) = ''">
<xsl:value-of select="#nodeName"/>
</xsl:if>
</a>
<!-- if it's a branch recurse through it's children-->
<xsl:if test="((($isBranch = 1 and $recurse = 1) or ($walkChildren = 1 and $pseudoCurrentPage/descendant-or-self::*[#isDoc][#id = $currentNodeID]/child::*[#isDoc])) and $maxMenuDepth > $calculatedMenuDepth)">
<xsl:call-template name="nodeIterator">
<xsl:with-param name="parentNode" select="." />
<xsl:with-param name="pseudoCurrentPage" select="$pseudoCurrentPage" />
</xsl:call-template>
</xsl:if>
</li>
</xsl:for-each>
</ul>
</xsl:if>
</xsl:template>
<xsl:template name="cssClassConstructor">
<xsl:param name="isSelected"></xsl:param>
<xsl:param name="isSelectedBranch"></xsl:param>
<xsl:param name="hasChildren"></xsl:param>
<xsl:param name="selectedClass"></xsl:param>
<xsl:param name="branchClass"></xsl:param>
<xsl:variable name="class">
<xsl:if test="$isSelected = 1">
<xsl:value-of select="concat($selectedClass,' ')"/>
</xsl:if>
<xsl:if test="$isSelectedBranch = 1">
<xsl:value-of select="concat($branchClass,' ')"/>
</xsl:if>
<xsl:if test="$hasChildren = 1">
<xsl:value-of select="'hasChildren '"/>
</xsl:if>
</xsl:variable>
<xsl:if test="string-length($class) > 0">
<xsl:attribute name="class">
<xsl:value-of select="normalize-space($class)"/>
</xsl:attribute>
</xsl:if>
</xsl:template>
</xsl:stylesheet>​
The issue you describe above isn't replicating for me (I've checked your source code using Notepad++ and a diff viewer). I see from your code that you're using the CogWorks' Flexible Navigation package. Can you ensure you're using the latest code from here?
Many thanks,
Benjamin