Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: XML XSLT
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:

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 17-Mar-10 2:23am

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

So say for example your XML looks like...
 
<?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 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 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>
  Permalink  

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

  Print Answers RSS
0 Sergey Alexandrovich Kryukov 175
1 Zoltán Zörgő 160
2 Peter Leow 130
3 CPallini 70
4 Ramza360 51
0 Sergey Alexandrovich Kryukov 9,568
1 OriginalGriff 6,901
2 Peter Leow 4,737
3 Zoltán Zörgő 4,404
4 CHill60 2,932


Advertise | Privacy | Mobile
Web02 | 2.8.150129.1 | Last Updated 5 May 2010
Copyright © CodeProject, 1999-2015
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100