Oleg_08
Oleg_08

Reputation: 487

How to make a replace in string variable XSLT?

I have the following XSLT Script that extracts an URL from my XML:

<?xml version="1.0" encoding="UTF-8"?>     
<xsl:stylesheet  version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:dcterms="http://purl.org/dc/terms/" 
 xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:ns="http://www.openarchives.org/OAI/2.0/"
xmlns:ns0="http://schema.fabrik.de/data/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
 exclude-result-prefixes="dc dcterms ">     
    <xsl:output method="xml" version="1.0"
    encoding="UTF-8" indent="yes" />        
    <xsl:template match="/">
 <xsl:if test="string(xml-fragment/ns:metadata/ns0:objects/ns0:objekttyp/ns0:datei/ns0:files/ns0:file/ns0:versions/ns0:version[@name='small']/ns0:deep_link_url)">
    <dc:identifier xsi:type="dcterms:URI"> 
     <xsl:value-of select="/xml-fragment/ns:metadata/ns0:objects/ns0:objekttyp/ns0:datei/ns0:files/ns0:file/ns0:versions/ns0:version[@name='small']/ns0:deep_link_url"/> 
      </dc:identifier>
 </xsl:template> 

</xsl:stylesheet>  

In the extracted URL I want immediately change the word after the last "/" . So it should be attachment instead inline.

NOW: https://id/1001976586/file_version/name/small/disposition/inline
Should be: https://id/1001976586/file_version/name/small/disposition/attachment

What I'm trying to do is to save the URL in the variable $file and then replace 'inline' through 'attachment'. I get the following error: [main] JAXPSAXProcessorInvoker - Function couldn't be found: replace

<xsl:variable name='file' select="/xml-fragment/ns:metadata/ns0:objects/ns0:objekttyp/ns0:datei/ns0:files/ns0:file/ns0:versions/ns0:version[@name='small']/ns0:deep_link_url"/> 
<xsl:value-of select="replace($file, 'inline', 'attachment')"/>

Upvotes: 0

Views: 1101

Answers (1)

FelHa
FelHa

Reputation: 1103

Like proposed in the comment, you could solve this with a recursive template. In this example, template replace will split your input string $file in a sub-string before and after the string 'inline'. As long as $sub_after also contains the string 'inline', the template recursively calls itself. If there is no such string in $sub_after, its string will be extracted and the template is done.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
    version="1.0">

    <xsl:template match="/">
        <xsl:call-template name="replace">
            <xsl:with-param name="file" select="'https://id/1001976586/file_version/name/small/inline/disposition/inline/test'"/>
        </xsl:call-template>
    </xsl:template>

    <xsl:template name="replace">
        <xsl:param name="file"/>
        <xsl:variable name="sub_before" select="substring-before($file, 'inline')"/>
        <xsl:variable name="sub_after" select="substring-after($file, 'inline')"/>
        <xsl:value-of select="concat($sub_before, 'attachment')"/>
        <xsl:choose>
            <xsl:when test="contains($sub_after, 'inline')">
                <xsl:call-template name="replace">
                    <xsl:with-param name="file" select="$sub_after"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$sub_after"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template> 
</xsl:stylesheet>

Upvotes: 2

Related Questions