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')"/>
5
  • Which XSLT processor are you using? Commented Mar 22, 2018 at 11:03
  • @potame It's Xalan 2.7.1 Commented Mar 22, 2018 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. Commented Mar 22, 2018 at 11:43
  • @MartinHonnen But is it a way how to do it in XSLT 1? Commented Mar 22, 2018 at 12:07
  • You could use a recursive template to do it. See stackoverflow.com/questions/3067113/xslt-string-replace for an example Commented Mar 22, 2018 at 13:13

1 Answer 1

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>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.