I have from XML for example the String "AA"
and i need to increment it Like:
AA AB AC AD AE (...) AZ BA BB (...)
For example increment it for 35 times (coming from a varaible called (`xsl:variable name ="NumIncr">)) starting at AA and finishing in BG.
The string don't always have "AA" can be any 2 letters...
Any idea to do this?!
I think the <xsl:number> tag can help, but still the problem to pass from letters to numbers.
Need something like
<fo:table-cell border-collapse="collapse" border-color="gray" font-family="Helvetica" font-size="8pt" border="solid 1pt gray" padding="1pt" display-align="before">
<fo:block text-align="center">
<xsl:value-of select="string($Sequence)"/>
</fo:block>
</fo:table-cell>
Where $sequence is the AA AB AC (...)
Can writte evrything in the same cell, the problem isn't the output but the tamplate to increment the AA
HELP!!!
To translate a string like "AA" to its numerical value, you can use the following template:
<xsl:template name="string-to-num">
<xsl:param name="string"/>
<xsl:param name="alpha" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:param name="magnitude" select="1"/>
<xsl:param name="carryover" select="0"/>
<xsl:param name="bit" select="substring($string, string-length($string), 1)"/>
<xsl:param name="bit-value" select="string-length(substring-before($alpha, $bit)) + 1"/>
<xsl:variable name="return" select="$carryover + $bit-value * $magnitude"/>
<xsl:choose>
<xsl:when test="string-length($string) > 1">
<xsl:call-template name="string-to-num">
<xsl:with-param name="string" select="substring($string, 1, string-length($string) - 1)"/>
<xsl:with-param name="magnitude" select="string-length($alpha) * $magnitude"/>
<xsl:with-param name="carryover" select="$return"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$return" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Some examples of calling the template:
<xsl:call-template name="string-to-num">
<xsl:with-param name="string">A</xsl:with-param>
</xsl:call-template>
returns 1;
<xsl:call-template name="string-to-num">
<xsl:with-param name="string">Z</xsl:with-param>
</xsl:call-template>
returns 26;
<xsl:call-template name="string-to-num">
<xsl:with-param name="string">AA</xsl:with-param>
</xsl:call-template>
returns 27;
<xsl:call-template name="string-to-num">
<xsl:with-param name="string">ZZ</xsl:with-param>
</xsl:call-template>
returns 702;
<xsl:call-template name="string-to-num">
<xsl:with-param name="string">AAA</xsl:with-param>
</xsl:call-template>
returns 703.
These results are the exact reverse of:
<xsl:number value="$return" format="A"/>
Related
I'm trying to generate a pdf using xsl + xml, but Im having problems on a part of the document where there is some lines of text with line breaks.
When generating the document it did not keep those line breaks.
I have tried everything, and Im completely stuck.
My code is:
<fo:table-row>
<fo:table-cell margin-right="0mm" margin-left="0mm"
margin-bottom="0mm" margin-top="0mm"
xsl:use-attribute-sets="bordergris" number-columns-spanned="5">
<fo:block xsl:use-attribute-sets="titoldades"
space-before.optimum="0pt" space-after.optimum="0pt"
keep-together="always" >
More info:
</fo:block>
<fo:block xsl:use-attribute-sets="dades"
space-before.optimum="0pt" space-after.optimum="0pt"
keep-together="always" linefeed-treatment="preserve">
<xsl:call-template name="replace-string">
<xsl:with-param name="text" select="/Response/DataList/Data/MoreInfo"/>
<xsl:with-param name="replace" select="' '" />
<xsl:with-param name="with" select="'<fo:block/>'"/>
</xsl:call-template>
</fo:block>
</fo:table-cell>
</fo:table-row>
Which use a template function:
<xsl:template name="replace-string">
<xsl:param name="text"/>
<xsl:param name="replace"/>
<xsl:param name="with"/>
<xsl:choose>
<xsl:when test="contains($text,$replace)">
<xsl:value-of select="substring-before($text,$replace)"/>
<xsl:value-of select="$with"/>
<xsl:call-template name="replace-string">
<xsl:with-param name="text"
select="substring-after($text,$replace)"/>
<xsl:with-param name="replace" select="$replace"/>
<xsl:with-param name="with" select="$with"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
And the resulting text appears with the hardcoded text "<fo:block/>" instead of applying the line break.
What am I doing wrong?
Thanks!!!
The important thing is to put the following properties inside the fo:block:
inefeed-treatment="preserve" white-space-collapse="false" white-space-treatment="preserve"
And then do the replace with the following:
<fo:block xsl:use-attribute-sets="dades"
linefeed-treatment="preserve" white-space-collapse="false" white-space-treatment="preserve">
<xsl:call-template name="replace-string">
<xsl:with-param name="text" select="/Response/DataList/Data/MoreInfo"/>
<xsl:with-param name="replace" select="' '" />
<xsl:with-param name="with" select="'
'"/>
</xsl:call-template>
I have following code:
<xsl:if test="#class = 'abc' and name(.) = 'span'">
<xsl:call-template name="multiReplace">
<xsl:with-param name="pText" select="."/>
</xsl:call-template>
</xsl:if>
The template "multiReplace" is finding old value and replacing new values.
I want to replace the following span text with NewText text :
<span class="abc">Old:</span>
to
<span class="abc">NewText:</span>
but I am getting :
<span class="abc">Old:NewText:</span>
below is the other related code:
<my:params xml:space="preserve">
<pattern>
<old>Old: </old>
<new>NewText:</new>
</pattern>
<pattern>
<old>Contact</old>
<new>Phone</new>
</pattern>
</my:params>
<xsl:variable name="vPats" select="document('')/*/my:params/*"/>
<xsl:template name="multiReplace">
<xsl:param name="pText" select="."/>
<xsl:param name="pPatterns" select="$vPats"/>
<xsl:if test="string-length($pText) > 0">
<xsl:variable name="vPat" select="$vPats[starts-with($pText, old)][1]"/>
<xsl:choose>
<xsl:when test="not($vPat)">
<xsl:copy-of select="substring($pText,1,1)"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$vPat/new/node()"/>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="multiReplace">
<xsl:with-param name="pText" select="substring($pText, 1 + not($vPat) + string-length($vPat/old/node()))"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
Can you please take a look, what is the error here?
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 ' ' added and quotes are shown as '"'. 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
I have a string like : "ABCDEFGHI"
I want the output as A,B,C,D,E,F,G,H,I in xslt-
I have been using -
<xsl:variable name="string_Comma_Delimited">a,b,c,d,e,f,g,h,i</xsl:variable>
<xsl:call-template name="parseString">
<xsl:with-param name="list" select="$string_Comma_Delimited"/>
</xsl:call-template>
<xsl:template name="parseString">
<xsl:param name="list"/>
<xsl:if test="contains($list, ',')">
<fo:table-cell border-width="0.000pt " border-style="solid" border-color="rgb(0,0,0)" padding-top="4.000pt">
<fo:block-container height="6mm" border-width="0.200pt" border-style="solid" border-color="rgb(0,0,0)" text-align="center">
<fo:block text-align="center">
<xsl:value-of select="substring-before($list, ',')"/>
</fo:block>
</fo:block-container>
</fo:table-cell>
<xsl:call-template name="parseString">
<xsl:with-param name="list" select="substring-after($list, ',')"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
Your current template splits the string by commas. To simply split it on every single character you can still use a recursive template. All the template would do is output the first character using substring, and then, if the length of the string was 2 or more characters, recursively call the template with the remaining portion of the string.
Try this
<xsl:template name="parseString">
<xsl:param name="text"/>
<letter>
<xsl:value-of select="substring($text, 1, 1)"/>
</letter>
<xsl:if test="string-length($text) > 1">
<xsl:call-template name="parseString">
<xsl:with-param name="text" select="substring($text, 2, string-length($text) - 1)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
Given INDIA as input, the following is output:
<letter>I</letter>
<letter>N</letter>
<letter>D</letter>
<letter>I</letter>
<letter>A</letter>
Now, if you were using XSLT 2.0, you could use the xsl:analyze-string function to achieve the same
<xsl:template name="parseString">
<xsl:param name="text"/>
<xsl:analyze-string select="$text" regex=".">
<xsl:matching-substring>
<letter>
<xsl:value-of select="." />
</letter>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:template>
(Of course, if you were using XSLT 2.0, you could have used tokenize in the first case to split the comma-delimited string)
I have a delimited string (delimited by spaces in my example below) that I need to tokenize, sort, and then join back together and I need to do all this using XSLT 1.0. How would I do that? I know I need to use xsl:sort somehow, but everything I’ve tried so far has given me some sort of error.
For example, if I run the code at the bottom of this posting, I get this:
strawberry blueberry orange raspberry
lime lemon
What would I do if I wanted to get this instead?:
blueberry lemon lime orange raspberry
strawberry
Note that I’m using XSLT 1.0.
Here is the code, which is based on code by Jeni Tennison.
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="tokenize1.xsl"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:call-template name="tokenize">
<xsl:with-param name="string" select="'strawberry blueberry orange raspberry lime lemon'" />
</xsl:call-template>
</xsl:template>
<xsl:template name="tokenize">
<xsl:param name="string" />
<xsl:param name="delimiter" select="' '" />
<xsl:choose>
<xsl:when test="$delimiter and contains($string, $delimiter)">
<token>
<xsl:value-of select="substring-before($string, $delimiter)" />
</token>
<xsl:text> </xsl:text>
<xsl:call-template name="tokenize">
<xsl:with-param name="string"
select="substring-after($string, $delimiter)" />
<xsl:with-param name="delimiter" select="$delimiter" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<token><xsl:value-of select="$string" /></token>
<xsl:text> </xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Here's an inefficient pure version 1 solution:
<!-- Sort the tokens -->
<xsl:template name="sortTokens">
<xsl:param name="tokens" select="''"/> <!-- The list of tokens -->
<xsl:param name="separator" select="' '"/> <!-- What character separates the tokens? -->
<xsl:param name="pivot" select="''"/> <!-- A pivot word used to divide the list -->
<xsl:param name="lessThan" select="''"/> <!-- Accumulator for tokens less than the pivot (with leading separator) -->
<xsl:param name="moreThan" select="''"/> <!-- Accumulator for tokens more than the pivot (with leading separator) -->
<xsl:param name="leadWith" select="''"/> <!-- If set, output this before sorting -->
<xsl:param name="trailWith" select="''"/> <!-- If set, output this after sorting -->
<!-- The first token -->
<xsl:variable name="firstToken" select="substring-before(concat($tokens,$separator),$separator)"/>
<!-- Is the first token more or less than the pivot? -->
<xsl:variable name="pivotVsFirstToken">
<xsl:call-template name="compareStrings">
<xsl:with-param name="a" select="$pivot"/>
<xsl:with-param name="b" select="$firstToken"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<!-- No input, no output -->
<xsl:when test="$tokens = '' and $pivot = ''"></xsl:when>
<!-- At the outset, the first token becomes the pivot -->
<xsl:when test="$pivot = ''">
<xsl:value-of select="$leadWith"/>
<xsl:call-template name="sortTokens">
<xsl:with-param name="separator" select="$separator"/>
<xsl:with-param name="tokens" select="substring-after($tokens,$separator)"/>
<xsl:with-param name="pivot" select="$firstToken"/>
</xsl:call-template>
<xsl:value-of select="$trailWith"/>
</xsl:when>
<!-- When all tokens are in a bucket, output the pivot between sorted buckets -->
<xsl:when test="$tokens = ''">
<xsl:call-template name="sortTokens">
<xsl:with-param name="separator" select="$separator"/>
<xsl:with-param name="tokens" select="substring-after($lessThan,$separator)"/>
<xsl:with-param name="trailWith" select="$separator"/>
</xsl:call-template>
<xsl:value-of select="$pivot"/>
<xsl:call-template name="sortTokens">
<xsl:with-param name="separator" select="$separator"/>
<xsl:with-param name="tokens" select="substring-after($moreThan,$separator)"/>
<xsl:with-param name="leadWith" select="$separator"/>
</xsl:call-template>
</xsl:when>
<!-- If the first token is less than the pivot, put it in the lessThan bucket -->
<xsl:when test="number($pivotVsFirstToken) = 1">
<xsl:call-template name="sortTokens">
<xsl:with-param name="separator" select="$separator"/>
<xsl:with-param name="tokens" select="substring-after($tokens,$separator)"/>
<xsl:with-param name="pivot" select="$pivot"/>
<xsl:with-param name="lessThan" select="concat($separator,$firstToken,$lessThan)"/>
<xsl:with-param name="moreThan" select="$moreThan"/>
</xsl:call-template>
</xsl:when>
<!-- If the first token is more than the pivot, put it in the moreThan bucket -->
<xsl:otherwise>
<xsl:call-template name="sortTokens">
<xsl:with-param name="separator" select="$separator"/>
<xsl:with-param name="tokens" select="substring-after($tokens,$separator)"/>
<xsl:with-param name="pivot" select="$pivot"/>
<xsl:with-param name="lessThan" select="$lessThan"/>
<xsl:with-param name="moreThan" select="concat($separator,$firstToken,$moreThan)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Quote an apostrophe -->
<xsl:variable name="apos" select=""'""/>
<!-- The comparison order of the characters -->
<xsl:variable name="characterOrder" select="concat(' !"#$%&',$apos,'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~')"/>
<!-- Return -1 if string a is less, 1 if string b is less, or 0 if they are equal -->
<xsl:template name="compareStrings">
<xsl:param name="a" select="''"/>
<xsl:param name="b" select="''"/>
<xsl:choose>
<xsl:when test="$a = '' and $b = ''">0</xsl:when>
<xsl:when test="$a = ''">-1</xsl:when>
<xsl:when test="$b = ''">1</xsl:when>
<xsl:when test="substring($a,1,1) = substring($b,1,1)">
<xsl:call-template name="compareStrings">
<xsl:with-param name="a" select="substring($a,2)"/>
<xsl:with-param name="b" select="substring($b,2)"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="contains(substring-after($characterOrder,substring($a,1,1)),substring($b,1,1))">-1</xsl:when>
<xsl:otherwise>1</xsl:otherwise>
</xsl:choose>
</xsl:template>
If your processor supports EXSLT, you'd better use str:tokenize
For sorting, why not use xsl:sort?
<xsl:template match="/">
<xsl:variable name="tokens">
<xsl:call-template name="tokenize">
<xsl:with-param name="string" select="'strawberry blueberry orange raspberry lime lemon'" />
</xsl:call-template>
</xsl:variable>
<xsl:for-each select="$tokens">
<xsl:sort select="text()" />
<xsl:value-of select="." />
<xsl:if test="not(last())">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
Note that you might need exsl:node-set do to the iteration.