0

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')"/>
Oleg_08
  • 447
  • 1
  • 4
  • 23
  • Which XSLT processor are you using? – potame Mar 22 '18 at 11:03
  • @potame It's Xalan 2.7.1 – Oleg_08 Mar 22 '18 at 11:35
  • 1
    `replace` is a function introduced in XSLT/XPath 2.0 introduced in 2007 and implemented in XSLT 2 processors like Saxon 9. You are using an XSLT 1 processor that does not support that function or any other XSLT/XPath 2 feature. In the Java world it is easy to install Saxon 9 and use it instead of Xalan. – Martin Honnen Mar 22 '18 at 11:43
  • @MartinHonnen But is it a way how to do it in XSLT 1? – Oleg_08 Mar 22 '18 at 12:07
  • You could use a recursive template to do it. See https://stackoverflow.com/questions/3067113/xslt-string-replace for an example – Tim C Mar 22 '18 at 13:13

1 Answers1

2

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>
FelHa
  • 1,043
  • 11
  • 24