1

我一直在试图找出解决这个问题的正确方法,但还没有取得任何成功。问题是我有两个变量-一个包含服务器+站点根路径,第二个包含文件的路径,例如-

<xsl:variable name="a">/user/folder/academics/aps/includes</xsl:variable>
<xsl:variable name="b">/aps/includes/something/test.html</xsl:variable> 

我在这里尝试做的是对这两个字符串应用一个函数,以便最终结果看起来像 -

/user/folder/academics/aps/includes/something/test.html

到目前为止,我尝试的是 tokenize() 字符串,然后比较每个项目,但问题是如果让我们说文件夹名称“academics”重复两次,它会停在第一个。我确信有更好的方法来解决这个问题。任何建议都受到高度赞赏。

4

1 回答 1

4

如果您愿意假设两条路径之间最长的重叠是一个共同部分,那么这样的事情可能对您有用:

<xsl:template name="merge-paths">
    <xsl:param name="path1"/>
    <xsl:param name="path2"/>
    <xsl:variable name="root2" select="concat('/', substring-before(substring-after($path2, '/'), '/'), '/')"/>
    <xsl:choose>
        <xsl:when test="contains($path1, $root2)">
            <xsl:variable name="tail1" select="concat($root2, substring-after($path1, $root2))" />
            <xsl:choose>
                <xsl:when test="starts-with($path2, $tail1)">
                    <xsl:value-of select="$path1"/>
                    <xsl:value-of select="substring-after($path2, $tail1)"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="substring-before($path1, $root2)"/>
                    <xsl:value-of select="substring($root2, 1, string-length($root2) - 1)"/>
                    <xsl:call-template name="merge-paths">
                        <xsl:with-param name="path1" select="concat('/', substring-after($path1, $root2))"/>
                        <xsl:with-param name="path2" select="$path2"/>
                    </xsl:call-template>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="substring($path1, 1, string-length($path1) - 1)"/>
            <xsl:value-of select="$path2"/>
        </xsl:otherwise>
    </xsl:choose>   
</xsl:template>

以下是调用模板和结果输出的一些示例:

1. 无重叠:

    <xsl:call-template name="merge-paths">
        <xsl:with-param name="path1">/a/b/c/</xsl:with-param>
        <xsl:with-param name="path2">/d/e/f.html</xsl:with-param>
    </xsl:call-template>

<result>/a/b/c/d/e/f.html</result>

2.简单重叠:

    <xsl:call-template name="merge-paths">
        <xsl:with-param name="path1">/a/b/c/d/</xsl:with-param>
        <xsl:with-param name="path2">/c/d/e/f.html</xsl:with-param>
    </xsl:call-template>

<result>/a/b/c/d/e/f.html</result>

3.双重重叠:

    <xsl:call-template name="merge-paths">
        <xsl:with-param name="path1">/a/b/c/d/c/d/</xsl:with-param>
        <xsl:with-param name="path2">/c/d/e/f.html</xsl:with-param>
    </xsl:call-template>

<result>/a/b/c/d/c/d/e/f.html</result>

4. 错误重叠:

    <xsl:call-template name="merge-paths">
        <xsl:with-param name="path1">/a/b/c/d/x/</xsl:with-param>
        <xsl:with-param name="path2">/c/d/e/f.html</xsl:with-param>
    </xsl:call-template>

<result>/a/b/c/d/x/c/d/e/f.html</result>

请注意在 path1 末尾的斜杠。
这实际上是一个 XSLT 1.0 解决方案;在以后的版本中可能有更好的方法来实现这一点(正则表达式?)。

于 2014-10-02T05:04:46.773 回答