Click here to Skip to main content
15,889,034 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
XSL:
I need to read the string from XML and split using the delimiter "|" and concatenate the text with the URL until the maximum count of the split () array. I have given my XML input format and output in XML (see below). I have tried with str: split function in XSLT but it’s not supporting in XSL.

XML input:
<tag>
text1|url1|text2|url2...


My Output Should be:
Hyperlink URL; Hyperlink2;
So when I click text1 it should navigate to url1

PLEASE HELP ME!!
Posted

1 solution

So say for example your XML looks like...

XML
<?xml version="1.0"?>
<root>
    <links>Some URL|http://www.someurl.com|Another URL|http://www.anotherurl.com</links>
</root>


If you are using XSLT 1.0 then you'll need yo use some form of recursion (be aware, if you have too many text+link pairs the transformation engine may stack overflow - in which case you'll need to look at using divide'n'conquer). But something like...
XML
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="html" indent="yes"/>

    <xsl:template match="/">
        <html>
            <body>
                <p>
                    <xsl:text>My links are:-</xsl:text>
                    <br/>
                    <!-- do the links elements -->
                    <xsl:apply-templates select="root/links"/>
                </p>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="links">
        <xsl:call-template name="SplitLinks">
            <xsl:with-param name="pLinks" select="text()"/>
        </xsl:call-template>
    </xsl:template>

    <!-- recursive template for splitting links (text|url) -->
    <xsl:template name="SplitLinks">
        <xsl:param name="pLinks"/>
        <!-- how many seperators are there in the string... -->
        <xsl:variable name="vCountSeperators" select="string-length($pLinks) - string-length(translate($pLinks,'|',''))"/>
        <xsl:choose>
            <xsl:when test="$vCountSeperators &gt;= 2">
                <!-- two seperators - text|link|...more... -->
                <a href="{substring-before(substring-after($pLinks,'|'),'|')}">
                    <xsl:value-of select="substring-before($pLinks,'|')"/>
                </a>
                <!-- delimit the links -->
                <xsl:text>&#160;|&#160;</xsl:text>
                <!-- recursive call -->
                <xsl:call-template name="SplitLinks">
                    <xsl:with-param name="pLinks" select="substring-after(substring-after($pLinks,'|'),'|')"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:when test="$vCountSeperators = 1">
                <!-- one seperator - text|link -->
                <a href="{substring-after($pLinks,'|')}">
                    <xsl:value-of select="substring-before($pLinks,'|')"/>
                </a>
            </xsl:when>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>


In XSLT 2.0/XPath 2.0 you can use the tokenize() function, something like...
XML
<?xml version="1.0"?>
<xsl:stylesheet version="2.0" exclude-result-prefixes="xs"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xsl:output method="html" indent="yes"/>

    <xsl:template match="/">
        <html>
            <body>
                <p>
                    <xsl:text>My links are:-</xsl:text>
                    <br/>
                    <!-- do the links elements -->
                    <xsl:apply-templates select="root/links"/>
                </p>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="links">
        <!-- tokenize by the seperator bar -->
        <xsl:variable name="vLinksParts" select="tokenize(text(),'\|')" as="xs:string*"/>
        <!-- iterate through the pairs -->
        <xsl:for-each select="1 to xs:integer(floor(count($vLinksParts) div 2))">
            <!-- index of the pair start -->
            <xsl:variable name="vIndex" select="(. * 2) - 1" as="xs:integer"/>
            <a href="{$vLinksParts[$vIndex + 1]}">
                <xsl:value-of select="$vLinksParts[$vIndex]"/>
            </a>
            <xsl:if test="position() != last()">
                <!-- if not the last, output a seperator -->
                <xsl:text>&#160;|&#160;</xsl:text>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900