如何在字符串变量XSLT中进行替换?

时间:2018-03-22 10:52:07

标签: xml xslt replace

我有以下XSLT脚本从XML中提取URL:

<?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>  

在提取的网址中,我想立即更改最后一个“/”后面的单词。所以它应该是附件而不是内联。

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

我要做的是将URL保存在变量$ file中,然后将'inline'替换为'attachment'。 我收到以下错误:[main] JAXPSAXProcessorInvoker - 无法找到函数: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')"/>

1 个答案:

答案 0 :(得分:2)

与评论中提出的一样,您可以使用递归模板解决此问题。在此示例中,模板replace会将输入字符串$file拆分为字符串&#39; inline&#39;之前和之后的子字符串。只要$sub_after还包含字符串&#39; inline&#39;,模板就会递归调用自身。如果$sub_after中没有这样的字符串,则会提取其字符串并完成模板。

<?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>