2014-10-02 127 views
1

我一直在试图找出解决这个问题的正确方法,但还没有取得任何成功。问题是,我有两个变量 - 一个包含服务器+站点根路径和第二个包含喜欢 -合并xslt中的两个字符串

<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 

我已经试过到目前为止令牌化()的字符串,然后比较每个项目,但有一点问题,如果让我们说文件夹命名为“学者”重复两次,它停在第一个。我相信有更好的方法来解决这个问题。任何建议非常感谢。

+0

为了您的利益以及对于那些可能会帮助您使用XSLT的人员,您应该更清楚地定义预期的合并。仅仅提供一个单一案例就没有明确规定。 – kjhughes 2014-10-02 03:16:53

+0

我不认为这个问题*定义明确*。有多种可能的解决方案,无法确定哪一个是正确的。如果该文件的* real *路径是'/user/folder/academics/aps/includes/includes/something/test.html?' – 2014-10-02 03:20:43

+0

我同意,无法完成。简单的例子。部分“a”是/ foo/bar/foo/bar,部分“b”是/foo/bar/x.html。什么是正确答案?是/foo/bar/x.html还是/foo/bar/foo/bar/x.html? – 2014-10-02 03:59:14

回答

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解决方案;在更高版本中可能有更好的方法来实现它(正则表达式?)。

+1

有助于XSLT实施以及充实需求。很好的答案。+1 – kjhughes 2014-10-02 13:18:48

+1

+1,可以立即进入XSLT教科书。 – 2014-10-03 13:39:13