Future of XSLT and Velocity

nicban's Avatar

nicban

12 May, 2015 08:25 PM

Can you tell me what the future is regarding XSLT and Velocity. Hannon Hill seems to be moving towards and focusing more on Velocity, than XSLT.
Will they both still be supported in the future. Is it recommended to move towards velocity?

  1. 1 Posted by Wing Ming Chan on 12 May, 2015 09:33 PM

    Wing Ming Chan's Avatar

    Hi Nic,

    When talking about XSLT vs. Velocity, I don't have an answer, for one or the other. But I do have a few things to add to the discussion:

    1. Velocity is more powerful. Besides transforming block data, a Velocity script can be used alone, locating data source somewhere. XSLT cannot do this. In fact, I figured out a way to enhance the power of Velocity, so that it can access the Cascade database directly. It can also invoke XSLT.

    2. There is no namespace support in Velocity, and macros are not exactly named templates. It is a bit easier to organize XSLT code into libraries. Reusability is very well-supported there. Velocity is catching up by introducing #import. But it still has a long way to go.

    3. Until Hannon Hill introduces Velocity into the realm of tempate formats, there is no substitute for XSLT. I use template formats extensively and I am 'stuck'.

    4. I am not sure if Hannon Hill has any plan to allow for custom widgets. They are written in Velocity. If they are made available, I want to become an expert in widgets, with the enhanced power of Velocity in mind.

    I would say that Hannon Hill has to support XSLT for the next few years, though everybody can see that Velocity is getting a lot of support.

    Wing

  2. 2 Posted by nicban on 13 May, 2015 02:12 PM

    nicban's Avatar

    Thanks for you input Wing! I was just curious on the status of XSLT with Hannon Hill. I definitely see that Velocity getting more support and attention.
    I personally choose Velocity over XSLT, I like the whole less is more. With XSLT I have to write so many lines of code, with Velocity it is less lines of code and and easier to read.

  3. 3 Posted by Wing Ming Chan on 13 May, 2015 02:23 PM

    Wing Ming Chan's Avatar

    I absolutely agree that XSLT generally requires more lines of code. One major advantage of XSLT is that you can build reusable library code, using namespaces, named templates, and Xalan components. When I first started with Cascade, I could not use Velocity at all, due to a bug in Cascade prior 7.10.1. So the only choice for me was XSLT. In the past three years, I built a substantial XSLT library. This library is so helpful that I do not need to write much code when we switched to RWD. Everything written is still usable. I have also started writing Velocity formats just for fun. My main interest now is enhancing Velocity by going through the back door, using Java. This I can never do with XSLT.

    Wing

  4. 4 Posted by Ryan Griffith on 13 May, 2015 03:40 PM

    Ryan Griffith's Avatar

    Hi Nic,

    To echo your point, we have been continuing to focus more on Velocity since it is much more flexible in terms of adding functionality (eg Locator Tool and Query API) than XSLT is; however, there is no plan to drop XSLT. In fact, we do have some internal improvements logged to eventually attempt to upgrade XSLT and Xalan.

    Wing's point about supporting namespaces in Velocity is definitely valid and is something we can certainly add to the XPath Tool if there is enough interest.

    Believe it or not, you can in fact use native Java within XSLT. Scope out my comment on this discussion where I provide a sample XSLT Format that does some date manipulation using Java.Calendar.

    Please let me know if you have any additional questions.

    Thanks!

  5. 5 Posted by Wing Ming Chan on 13 May, 2015 03:59 PM

    Wing Ming Chan's Avatar

    Ryan,

    I never knew that Java can be used in xslt. I will definitely look into this. By the way, the namespace declaration xmlns:java="http://xml.apache.org/xalan/java" is missing from the attached file hours.xsl.

    Wing

  6. 6 Posted by Bryce Roberts on 14 May, 2015 01:42 AM

    Bryce Roberts's Avatar

    Couple of point to add:

    1) Namespaces are fairly easy to create and register into the xpath tool:
    $_.getClass().forName('org.jdom.Namespace').getNamespace('prefixAsString', 'uriAsString')
    This can be stored in a variable and added to an xpathtool by
    $_XPathTool.addNamespace($NSVar)
    2) Full Java (through rhino/narwhal) scripting is possible in both XSLT and Velocity, with Velocity having the direct advantage of reflection to be able to control the context and values included within the evaluation
    3) With the locator tool and some dynamic evaluation, 'templating' with name and xpath matching is fully possible in Velocity, and script based extensions are also possible
    4) Template level velocity formats are possible through xslt > extension > java > velocity, but there are some performance issues

    Hope these points are helpful,
    Bryce

  7. 7 Posted by Wing Ming Chan on 14 May, 2015 11:37 AM

    Wing Ming Chan's Avatar

    Hi Bryce,

    I have been waiting for some veterans like you to join the discussions. I hope you don't mind my attempt to pick your brain.

    This can be stored in a variable and added to an xpathtool by $_XPathTool.addNamespace($NSVar)

    Can you provide an example? Let's say, I want to register a namespace for a library file with macros. What do I do in the library file, and what do I do in the script using the library?

    Wing

  8. 8 Posted by Wing Ming Chan on 14 May, 2015 12:00 PM

    Wing Ming Chan's Avatar

    Hi Ryan,

    I have been trying the java: extension in xslt. So far, I have got two named templates working:

        <xsl:template name="charAt">
            <xsl:param name="calling-object"/>
            <xsl:param name="int"/>
            <xsl:value-of select="java:charAt($calling-object,$int)"/>
        </xsl:template>
    <xsl:template name="concat"> <xsl:param name="calling-object"/> <xsl:param name="string"/> <xsl:value-of select="java:concat($calling-object,$string)"/> </xsl:template>
    But when I tried contains (which involves a boolean) and replace, they don't work:
        <xsl:template name="contains">
            <xsl:param name="calling-object"/>
            <xsl:param name="string"/>
            <xsl:value-of select="java:contains($calling-object,$string)"/>
        </xsl:template>
    <xsl:template name="replace"> <xsl:param name="calling-object"/> <xsl:param name="target"/> <xsl:param name="replacement"/>
    <xsl:value-of select="java:replace($calling-object,$target,$replacement)"/> </xsl:template>
    I must have done something wrong. But what did I do wrong?

    Wing

  9. 9 Posted by Bryce Roberts on 14 May, 2015 02:11 PM

    Bryce Roberts's Avatar

    Hello Wing,

    The namespaces I am talking about have to do with XPath traversing.

    <xml>
    <ns1:node xmlns:ns1="http://www.stoneridge.net/new-node"/>
    <ns2:node xmlns:ns2="http://www.emory.edu/new-node"/>
    </xml>
    

    Format

    <![CDATA[
    #set($ns1 = $contentRoot.getClass().forName('org.jdom.Namespace').getNamespace('ns1', 'http://www.stoneridge.net/new-node'))
    #set($ns2 = $contentRoot.getClass().forName('org.jdom.Namespace').getNamespace('ns2', 'http://www.emory.edu/new-node'))
    $contentRoot
    $contentRoot.getChild('node', $ns1)
    $contentRoot.getChild('node', $ns2)
    #set($xpath = $_XPathTool.newInstance('/xml/ns1:node | /xml/ns2:node'))
    $xpath.addNamespace($ns1)
    $xpath.addNamespace('ns2', 'http://www.emory.edu/new-node')
    $xpath.selectNodes($contentRoot)
    ]]>
    
    Expected Output;
    <![CDATA[
    [Element: <xml/>]
    [Element: <ns1:node [Namespace: http://www.stoneridge.net/new-node]/>]
    [Element: <ns2:node [Namespace: http://www.emory.edu/new-node]/>]
    [[Element: <ns1:node [Namespace: http://www.stoneridge.net/new-node]/>], [Element: <ns2:node [Namespace: http://www.emory.edu/new-node]/>]]
    ]]>
    

    If you want to create macro sets (like namespaced templates), you would need to create a some other kind of machines. Couple of ways i have done this is through a hash map (macro name and signature) call through #evaluate or building the 'template' with strings and then #evaluate.

    In the macros, you can use this for filtering the nodes sets before applying.

    For java in xslt the signature is important for mapping, which can cause failures :
    XSLT Type Java Types
    Node-Set org.w3c.dom.traversal.NodeIterator, org.w3c.dom.NodeList, org.w3c.dom.Node or its subclasses, java.lang.String, java.lang.Object, char, [double, float, long, int, short, byte,] boolean
    String java.lang.String, java.lang.Object, char, [double, float, long, int, short, byte,] boolean
    Boolean boolean, java.lang.Boolean, java.lang.Object, java.lang.String
    Number double, java.lang.Double, float, long, int, short,char, byte, boolean, java.lang.String, java.lang.Object
    Result Tree Fragment org.w3c.dom.traversal.NodeIterator, org.w3c.dom.NodeList, org.w3c.dom.Node or its subclasses, java.lang.String, java.lang.Object, char, [double, float, long, int, short, byte,] boolean
    Non-XSLT Type the native type or any of its superclasses, double, float, long, int, short, char, byte, java.lang.String

    For return:
    Java Types XSLT Type
    org.w3c.dom.traversal.NodeIterator
    org.apache.xml.dtm.DTM
    org.apache.xml.dtm.DTMAxisIterator
    org.apache.xml.dtm.DTMIterator
    org.w3c.dom.Node Node-Set
    java.lang.String String
    java.lang.Boolean Boolean
    java.lang.Number Number
    org.w3c.dom.DocumentFragment Result Tree Fragment
    org.apache.xpath.objects.XObject Specified XSLT Type
    All other classes Non-XSLT Type

    It may be easier to create a rhino script that maps functions out of the String Class you need. Plus you can be sure to do the type coercion as you expect.

    For boolean values are you trying to match? You may need to stringify the boolean and match as string.

    Sincerely,
    Bryce

  10. 10 Posted by Wing Ming Chan on 14 May, 2015 02:17 PM

    Wing Ming Chan's Avatar

    Bryce,

    Thank you very much for the info. This will take me some time to digest.

    Wing

  11. 11 Posted by Wing Ming Chan on 14 May, 2015 03:51 PM

    Wing Ming Chan's Avatar

    I could not get replace to work, maybe due to the fact the method is overloaded. But I have a working replaceAll:

        <xsl:template name="contains">
            <xsl:param name="calling-object"/>
            <xsl:param name="string"/>
            <xsl:value-of select="java:toString(java:java.lang.Boolean.new(contains($calling-object,$string)))"/>
        </xsl:template>
        <xsl:template name="replaceAll">
            <xsl:param name="calling-object"/>
            <xsl:param name="regex"/>
            <xsl:param name="replacement"/>
    <xsl:value-of select="java:replaceAll($calling-object,$regex,$replacement)"/> </xsl:template>
    Wing
  12. 12 Posted by nicban on 14 May, 2015 07:23 PM

    nicban's Avatar

    Thanks everyone. This is a lot of really good info!

  13. 13 Posted by Wing Ming Chan on 18 May, 2015 07:09 PM

    Wing Ming Chan's Avatar

    An update. This stylesheet is kind of a partial equivalence of the FieldTool of Velocity:

    <xsl:stylesheet 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
        exclude-result-prefixes="java javareflection" version="1.0" 
        xmlns:java="http://xml.apache.org/xalan/java" 
        xmlns:javareflection="http://www.upstate.edu/chanw/javareflection">
        <xsl:output indent="yes" method="html"/>
        <xsl:template name="javareflection:get-static-class-field">
            <xsl:param name="class-name"/>
            <xsl:param name="field-name"/>
            <xsl:value-of select="java:get(java:getField(java:java.lang.Class.forName($class-name), $field-name),null)"/>
        </xsl:template>
    </xsl:stylesheet>
    
    And here is a format using it:
    <xsl:stylesheet 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
        xmlns:java="http://xml.apache.org/xalan/java" 
        xmlns:javareflection="http://www.upstate.edu/chanw/javareflection">
        <xsl:include href="site://_common/formats/Upstate/library/java-reflection"/>
        <xsl:output indent="yes" method="html"/>
        <xsl:template match="/">
            <br/>
            <br/>
            <xsl:call-template name="javareflection:get-static-class-field">
                <xsl:with-param name="class-name">java.lang.Math</xsl:with-param>
                <xsl:with-param name="field-name">PI</xsl:with-param>
            </xsl:call-template>
        </xsl:template>
    </xsl:stylesheet>
    Wing
  14. 14 Posted by Wing Ming Chan on 22 May, 2015 06:20 PM

    Wing Ming Chan's Avatar

    For those who are interested in string functions, here is a format I created, using Java extension:

    <xsl:stylesheet
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="java stringmethods" version="1.0"
        xmlns:java="http://xml.apache.org/xalan/java"
        xmlns:stringmethods="http://www.upstate.edu/chanw/stringmethods">
        <xsl:output indent="yes" method="html"/>
        <xsl:template name="stringmethods:charAt">
            <xsl:param name="calling-object"/>
            <xsl:param name="index"/>
            <xsl:value-of select="java:charAt($calling-object,$index)"/>
        </xsl:template>
        <xsl:template name="stringmethods:concat">
            <xsl:param name="calling-object"/>
            <xsl:param name="str"/>
            <xsl:value-of select="java:concat($calling-object,$str)"/>
        </xsl:template>
        <xsl:template name="stringmethods:contains">
            <xsl:param name="calling-object"/>
            <xsl:param name="str"/>
            <!-- does not accept java:contains -->
            <xsl:value-of select="java:toString(java:java.lang.Boolean.new(contains($calling-object,$str)))"/>
        </xsl:template>
        <xsl:template name="stringmethods:endsWith">
            <xsl:param name="calling-object"/>
            <xsl:param name="suffix"/>
            <xsl:value-of select="java:toString(java:java.lang.Boolean.new(java:endsWith($calling-object,$suffix)))"/>
        </xsl:template>
        <xsl:template name="stringmethods:equalsIgnoreCase">
            <xsl:param name="calling-object"/>
            <xsl:param name="string"/>
            <xsl:value-of select="java:toString(java:java.lang.Boolean.new(java:equalsIgnoreCase($calling-object,$string)))"/>
        </xsl:template>
        <xsl:template name="stringmethods:indexOf">
            <xsl:param name="calling-object"/>
            <xsl:param name="charstring"/>
            <xsl:param name="from"/>
            <xsl:choose>
                <xsl:when test="$from">
                    <xsl:value-of select="java:indexOf($calling-object,$charstring,$from)"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="java:indexOf($calling-object,$charstring)"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:template>
        <xsl:template name="stringmethods:lastIndexOf">
            <xsl:param name="calling-object"/>
            <xsl:param name="charstring"/>
            <xsl:param name="from"/>
            <xsl:choose>
                <xsl:when test="$from">
                    <xsl:value-of select="java:lastIndexOf($calling-object,$charstring,$from)"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="java:lastIndexOf($calling-object,$charstring)"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:template>
        <xsl:template name="stringmethods:length">
            <xsl:param name="calling-object"/>
            <xsl:value-of select="java:length($calling-object)"/>
        </xsl:template>
        <xsl:template name="stringmethods:matches">
            <xsl:param name="calling-object"/>
            <xsl:param name="regex"/>
            <xsl:value-of select="java:toString(java:java.lang.Boolean.new(java:matches($calling-object,$regex)))"/>
        </xsl:template>
        <xsl:template name="stringmethods:replaceFirst">
            <xsl:param name="calling-object"/>
            <xsl:param name="regex"/>
            <xsl:param name="replacement"/>
            <xsl:value-of select="java:replaceFirst($calling-object,$regex,$replacement)"/>
        </xsl:template>
        <xsl:template name="stringmethods:startsWith">
            <xsl:param name="calling-object"/>
            <xsl:param name="prefix"/>
            <xsl:param name="toffset"/>
            <xsl:choose>
                <xsl:when test="$toffset">
                    <xsl:value-of select="java:toString(java:java.lang.Boolean.new(java:startsWith($calling-object,$prefix,$toffset)))"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="java:toString(java:java.lang.Boolean.new(java:startsWith($calling-object,$prefix)))"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:template>
        <xsl:template name="stringmethods:subSequence">
            <xsl:param name="calling-object"/>
            <xsl:param name="beginIndex"/>
            <xsl:param name="endIndex"/>
            <xsl:value-of select="java:subSequence($calling-object,$beginIndex,$endIndex)"/>
        </xsl:template>
        <xsl:template name="stringmethods:substring">
            <xsl:param name="calling-object"/>
            <xsl:param name="beginIndex"/>
            <xsl:param name="endIndex"/>
            <xsl:choose>
                <xsl:when test="$endIndex">
                    <xsl:value-of select="java:substring($calling-object,$beginIndex,$endIndex)"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="java:substring($calling-object,$beginIndex)"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:template>
        <xsl:template name="stringmethods:replaceAll">
            <xsl:param name="calling-object"/>
            <xsl:param name="regex"/>
            <xsl:param name="replacement"/>
            <xsl:value-of select="java:replaceAll($calling-object,$regex,$replacement)"/>
        </xsl:template>
        <xsl:template name="stringmethods:toLowerCase">
            <xsl:param name="calling-object"/>
            <xsl:value-of select="java:toLowerCase($calling-object)"/>
        </xsl:template>
        <xsl:template name="stringmethods:toUpperCase">
            <xsl:param name="calling-object"/>
            <xsl:value-of select="java:toUpperCase($calling-object)"/>
        </xsl:template>
        <xsl:template name="stringmethods:trim">
            <xsl:param name="calling-object"/>
            <xsl:value-of select="java:trim($calling-object)"/>
        </xsl:template>
    </xsl:stylesheet>
    
    And here is the test xsl:
    <xsl:stylesheet
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
        xmlns:java="http://xml.apache.org/xalan/java"
        xmlns:javareflection="http://www.upstate.edu/chanw/javareflection"
        xmlns:stringmethods="http://www.upstate.edu/chanw/stringmethods">
        <xsl:include href="site://_common/formats/Upstate/library/java-reflection"/>
        <xsl:include href="site://_common/formats/Upstate/library/java-string-methods"/>
        <xsl:output indent="yes" method="html"/>
        <xsl:template match="/">
            <br/>
            <br/>
            <strong>Testing charAt:</strong>
            <br/>
            <xsl:call-template name="stringmethods:charAt">
                <xsl:with-param name="calling-object">hello</xsl:with-param>
                <xsl:with-param name="index">2</xsl:with-param>
            </xsl:call-template>, l
    <br/> <strong>Testing concat:</strong> <br/> <xsl:call-template name="stringmethods:concat"> <xsl:with-param name="calling-object">Hello</xsl:with-param> <xsl:with-param name="str"> World</xsl:with-param> </xsl:call-template>, Hello World
    <br/> <strong>Testing contains:</strong> <br/> <xsl:call-template name="stringmethods:contains"> <xsl:with-param name="calling-object">http://www.upstate.edu/cascade-admin/intra/format</xsl:with-param> <xsl:with-param name="str">/intra/</xsl:with-param> </xsl:call-template>, true
    <br/> <xsl:call-template name="stringmethods:contains"> <xsl:with-param name="calling-object">http://www.upstate.edu/cascade-admin/intra/format</xsl:with-param> <xsl:with-param name="str">//web</xsl:with-param> </xsl:call-template>, false
    <br/> <strong>Testing endsWith:</strong> <br/> <xsl:call-template name="stringmethods:endsWith"> <xsl:with-param name="calling-object">http://www.upstate.edu/cascade-admin/intra/format</xsl:with-param> <xsl:with-param name="string">/format</xsl:with-param> </xsl:call-template>, true
    <br/> <xsl:call-template name="stringmethods:endsWith"> <xsl:with-param name="calling-object">http://www.upstate.edu/cascade-admin/intra/format</xsl:with-param> <xsl:with-param name="suffix">/formats</xsl:with-param> </xsl:call-template>, false
    <br/> <strong>Testing equalsIgnoreCase:</strong> <br/> <xsl:call-template name="stringmethods:equalsIgnoreCase"> <xsl:with-param name="calling-object">FormatS</xsl:with-param> <xsl:with-param name="string">formats</xsl:with-param> </xsl:call-template>, true
    <br/> <xsl:call-template name="stringmethods:equalsIgnoreCase"> <xsl:with-param name="calling-object">FormatS</xsl:with-param> <xsl:with-param name="string">formasS</xsl:with-param> </xsl:call-template>, false
    <br/> <xsl:call-template name="stringmethods:equalsIgnoreCase"> <xsl:with-param name="calling-object">FormatS</xsl:with-param> <xsl:with-param name="string">format</xsl:with-param> </xsl:call-template>, false
    <br/> <strong>Testing indexOf:</strong> <br/> <xsl:call-template name="stringmethods:indexOf"> <xsl:with-param name="calling-object">FormatS</xsl:with-param> <xsl:with-param name="charstring">t</xsl:with-param> </xsl:call-template>, 5
    <br/> <xsl:call-template name="stringmethods:indexOf"> <xsl:with-param name="calling-object">FormatS</xsl:with-param> <xsl:with-param name="charstring">orm</xsl:with-param> </xsl:call-template>, 1
    <br/> <xsl:call-template name="stringmethods:indexOf"> <xsl:with-param name="calling-object">FormatSFormatS</xsl:with-param> <xsl:with-param name="charstring">r</xsl:with-param> <xsl:with-param name="from">0</xsl:with-param> </xsl:call-template>, 2
    <br/> <xsl:call-template name="stringmethods:indexOf"> <xsl:with-param name="calling-object">FormatSFormatS</xsl:with-param> <xsl:with-param name="charstring">r</xsl:with-param> <xsl:with-param name="from">5</xsl:with-param> </xsl:call-template>, 9
    <br/> <xsl:call-template name="stringmethods:indexOf"> <xsl:with-param name="calling-object">FormatSFormatS</xsl:with-param> <xsl:with-param name="charstring">orm</xsl:with-param> <xsl:with-param name="from">0</xsl:with-param> </xsl:call-template>, 1
    <br/> <xsl:call-template name="stringmethods:indexOf"> <xsl:with-param name="calling-object">FormatSFormatS</xsl:with-param> <xsl:with-param name="charstring">orm</xsl:with-param> <xsl:with-param name="from">5</xsl:with-param> </xsl:call-template>, 8
    <br/> <strong>Testing lastIndexOf:</strong> <br/> <xsl:call-template name="stringmethods:lastIndexOf"> <xsl:with-param name="calling-object">FormatSFormatS</xsl:with-param> <xsl:with-param name="charstring">o</xsl:with-param> </xsl:call-template>, 8
    <br/> <xsl:call-template name="stringmethods:lastIndexOf"> <xsl:with-param name="calling-object">FormatSFormatS</xsl:with-param> <xsl:with-param name="charstring">o</xsl:with-param> <xsl:with-param name="from">5</xsl:with-param> </xsl:call-template>, 1
    <br/> <xsl:call-template name="stringmethods:lastIndexOf"> <xsl:with-param name="calling-object">FormatSFormatS</xsl:with-param> <xsl:with-param name="charstring">o</xsl:with-param> <xsl:with-param name="from">10</xsl:with-param> </xsl:call-template>, 8
    <br/> <xsl:call-template name="stringmethods:lastIndexOf"> <xsl:with-param name="calling-object">FormatSFormatS</xsl:with-param> <xsl:with-param name="charstring">or</xsl:with-param> </xsl:call-template>, 8
    <br/> <xsl:call-template name="stringmethods:lastIndexOf"> <xsl:with-param name="calling-object">FormatSFormatS</xsl:with-param> <xsl:with-param name="charstring">or</xsl:with-param> <xsl:with-param name="from">5</xsl:with-param> </xsl:call-template>, 1
    <br/> <xsl:call-template name="stringmethods:lastIndexOf"> <xsl:with-param name="calling-object">FormatSFormatS</xsl:with-param> <xsl:with-param name="charstring">or</xsl:with-param> <xsl:with-param name="from">1</xsl:with-param> </xsl:call-template>, 1
    <br/> <xsl:call-template name="stringmethods:lastIndexOf"> <xsl:with-param name="calling-object">FormatSFormatS</xsl:with-param> <xsl:with-param name="charstring">or</xsl:with-param> <xsl:with-param name="from">0</xsl:with-param> </xsl:call-template>, -1
    <br/> <strong>Testing matches:</strong> <br/> <xsl:call-template name="stringmethods:matches"> <xsl:with-param name="calling-object">FormatSFormatS</xsl:with-param> <xsl:with-param name="regex">F.*</xsl:with-param> </xsl:call-template>, true
    <br/> <xsl:call-template name="stringmethods:matches"> <xsl:with-param name="calling-object">FormatSFormatS</xsl:with-param> <xsl:with-param name="regex">\s+</xsl:with-param> </xsl:call-template>, false
    <br/> <strong>Testing replaceFirst:</strong> <br/> <xsl:call-template name="stringmethods:replaceFirst"> <xsl:with-param name="calling-object">FormatSFormatS</xsl:with-param> <xsl:with-param name="regex">or</xsl:with-param> <xsl:with-param name="replacement">ar</xsl:with-param> </xsl:call-template>, FarmatSFormatS
    <br/> <strong>Testing startsWith:</strong> <br/> <xsl:call-template name="stringmethods:startsWith"> <xsl:with-param name="calling-object">FormatSFormatS</xsl:with-param> <xsl:with-param name="prefix">For</xsl:with-param> </xsl:call-template>, true
    <br/> <xsl:call-template name="stringmethods:startsWith"> <xsl:with-param name="calling-object">FormatSFormatS</xsl:with-param> <xsl:with-param name="prefix">For</xsl:with-param> <xsl:with-param name="toffset">3</xsl:with-param> </xsl:call-template>, false
    <br/> <xsl:call-template name="stringmethods:startsWith"> <xsl:with-param name="calling-object">FormatSFormatS</xsl:with-param> <xsl:with-param name="prefix">For</xsl:with-param> <xsl:with-param name="toffset">7</xsl:with-param> </xsl:call-template>, true
    <br/> <xsl:call-template name="stringmethods:startsWith"> <xsl:with-param name="calling-object">FormatSFormatS</xsl:with-param> <xsl:with-param name="prefix">For</xsl:with-param> <xsl:with-param name="toffset">8</xsl:with-param> </xsl:call-template>, false
    <br/> <strong>Testing subSequence:</strong> <br/> <xsl:call-template name="stringmethods:subSequence"> <xsl:with-param name="calling-object">FormatSFormatS</xsl:with-param> <xsl:with-param name="beginIndex">3</xsl:with-param> <xsl:with-param name="endIndex">9</xsl:with-param> </xsl:call-template>, matSFo
    <br/> <strong>Testing substring:</strong> <br/> <xsl:call-template name="stringmethods:substring"> <xsl:with-param name="calling-object">FormatSFormatS</xsl:with-param> <xsl:with-param name="beginIndex">3</xsl:with-param> </xsl:call-template>, matSFormatS
    <br/> <xsl:call-template name="stringmethods:substring"> <xsl:with-param name="calling-object">FormatSFormatS</xsl:with-param> <xsl:with-param name="beginIndex">3</xsl:with-param> <xsl:with-param name="endIndex">10</xsl:with-param> </xsl:call-template>, matSFor
    <br/> <strong>Testing replaceAll:</strong> <br/> <xsl:call-template name="stringmethods:replaceAll"> <xsl:with-param name="calling-object">abbbaabbbbbaabba</xsl:with-param> <xsl:with-param name="regex">ab+a</xsl:with-param> <xsl:with-param name="replacement">aba</xsl:with-param> </xsl:call-template>, abaabaaba
    <br/> <strong>Testing toLowerCase:</strong> <br/> <xsl:call-template name="stringmethods:toLowerCase"> <xsl:with-param name="calling-object">HelLO</xsl:with-param> </xsl:call-template>, hello
    <br/> <strong>Testing toUpperCase:</strong> <br/> <xsl:call-template name="stringmethods:toUpperCase"> <xsl:with-param name="calling-object">HelLO</xsl:with-param> </xsl:call-template>, HELLO
    <br/> <strong>Testing trim:</strong> <br/> <xsl:call-template name="stringmethods:trim"> <xsl:with-param name="calling-object"> Hey Jude </xsl:with-param> </xsl:call-template>, Hey Jude
    <br/> </xsl:template> </xsl:stylesheet>
    Wing
  15. 15 Posted by Ryan Griffith on 27 May, 2015 12:59 PM

    Ryan Griffith's Avatar

    Thank you for providing these Formats, Wing. I can see these being a nice alternative/replace for eXSLT extensions.

    Please feel free to continue contributing these helper stylesheets and I'll talk to Charlie about adding them to our XSLT Workbook and Cascade Exchange.

    Thanks!

  16. Ryan Griffith closed this discussion on 30 Jun, 2015 06:42 PM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac